Skip to content

Instantly share code, notes, and snippets.

@xav76
Created October 23, 2012 18:24
Show Gist options
  • Select an option

  • Save xav76/3940541 to your computer and use it in GitHub Desktop.

Select an option

Save xav76/3940541 to your computer and use it in GitHub Desktop.
A CodePen by Neil Carpenter. RAINBOWBALLZ - First go at a canvas thing, so code is pretty badly written, gets quite sluggish towards the higher end of balls too.
<body>
<div id="controls">
<span>
<h1>RAINBOWBALLZ</h1>
<p>Drag your mouse around. Move sliders to adjust effects. Click to toggle painting mode on/off. (No sliders in Firefox, sorry!)</p>
<p>
<label>Ball count</label>
<input class="controller" name="COLS" type="range" min="5" max="70" value="50">
</p>
<p>
<label>Effect radius</label>
<input class="controller" name="MOUSE_RADIUS" type="range" min="100" max="500" value="200">
</p>
<p>
<label>Effect strength</label>
<input class="controller" name="EFFECT_STRENGTH" type="range" min="1" max="20" value="2">
</p>
<p>
<label>Min size</label>
<input class="controller" name="MIN_RADIUS" type="range" min="0" max="50" value="0.5">
</p>
<p>
<label>Line thickness</label>
<input class="controller" name="LINE_WIDTH" type="range" min="1" max="5" value="1">
</p>
</span>
<a href="#" class="toggle-controls" id="open">Open controls</a>
<a href="#" class="toggle-controls" id="close">Close controls</a>
</div>
</body>
var params, ctx, winWidth, winHeight;
var rainbowBallz = function() {
var canvas = document.createElement('canvas');
winWidth = window.innerWidth;
winHeight = window.innerHeight;
canvas.width = winWidth;
canvas.height = winHeight;
document.body.appendChild(canvas);
var c = document.getElementsByTagName('canvas')[0];
ctx = c.getContext('2d');
var CANVAS_PADDING = 20,
clearing = false,
xCounter = 0,
yCounter = 0,
itemWidth,
rows,
itemCount,
hueIncrement,
satIncrement,
rMax,
hue,
sat,
x,
y,
mouseX = null,
mouseY = null;
function refresh(params) {
var strength, dist;
itemWidth = (winWidth - (CANVAS_PADDING * 2)) / params.COLS,
rows = winHeight / itemWidth,
itemCount = params.COLS * rows,
hueIncrement = Math.floor(360 / rows),
satIncrement = Math.floor(100 / params.COLS),
rMax = ((itemWidth - 4) / 2) + params.MIN_RADIUS;
if (clearing) {
ctx.clearRect(0, 0, winWidth, winHeight);
}
for (var i = 0; i < itemCount; i++) {
if (i !== 0 && i % params.COLS === 0) {
xCounter = 0;
yCounter += 1;
}
hue = hueIncrement * yCounter;
sat = satIncrement * xCounter;
x = (CANVAS_PADDING + (xCounter * itemWidth)) + params.MIN_RADIUS + (rMax - params.MIN_RADIUS);
y = (CANVAS_PADDING + (yCounter * itemWidth)) + params.MIN_RADIUS + (rMax - params.MIN_RADIUS);
if (mouseX) {
dist = Math.sqrt( Math.pow((x-mouseX),2) + Math.pow((y-mouseY),2));
if (dist >= params.MOUSE_RADIUS) {
r = params.MIN_RADIUS;
ctx.lineWidth = params.LINE_WIDTH;
}
else {
strength = (params.MOUSE_RADIUS - dist) / params.MOUSE_RADIUS;
r = ((strength * rMax) * params.EFFECT_STRENGTH) + params.MIN_RADIUS;
ctx.lineWidth = (strength * 1) + params.LINE_WIDTH;
}
}
else {
r = params.MIN_RADIUS;
ctx.lineWidth = params.LINE_WIDTH;
}
drawThatShit(hue, sat, x, y, r);
xCounter += 1;
}
xCounter = 0;
yCounter = 0;
}
function drawThatShit (hue, sat, x, y, r) {
ctx.strokeStyle = 'hsl(' + hue + ', ' + sat + '%, 50%)';
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.stroke();
}
function mouse (e) {
mouseX = e.pageX;
mouseY = e.pageY;
}
function toggleClear () {
clearing = clearing ? false : true;
}
c.addEventListener('mousemove', mouse, false);
c.addEventListener('mouseup', toggleClear, false);
setInterval(function() {
refresh(params);
}, 1000/60);
};
function eventListenerz() {
var inputs = document.getElementsByClassName('controller');
function onChange() {
var name = this.name,
value = this.value,
max = this.getAttribute('max');
value = +value;
ctx.clearRect(0, 0, winWidth, winHeight);
if (value > max) {
value = max;
this.value = max;
}
params[name] = value;
}
for (var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('change', onChange, false);
}
var controlToggles = document.getElementsByClassName('toggle-controls'),
controls = document.getElementById('controls');
function toggleControls(e) {
e.preventDefault();
controls.className = controls.className === 'closed' ? '' : 'closed';
}
for (var j = 0; j < 2; j++) {
controlToggles[j].addEventListener('click', toggleControls, false);
}
}
window.onload = function() {
params = {
COLS : 50, // maybe 5 - 70
MOUSE_RADIUS : 200, // 100 - 1000
MIN_RADIUS : 0.5, // 0 - 100
LINE_WIDTH : 1, // 1 - 5
EFFECT_STRENGTH : 2 // 1 - 20
};
rainbowBallz();
eventListenerz();
};
@import url("http://fonts.googleapis.com/css?family=Luckiest+Guy");
@import url("http://fonts.googleapis.com/css?family=Carrois+Gothic");
html, body {
-webkit-font-smoothing: antialiased;
font: normal 12px/14px 'Carrois Gothic', sans-serif;
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
span {
display: inline-block;
color: white;
background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,0,0,1)), color-stop(6%,rgba(255,93,0,1)), color-stop(12%,rgba(255,187,0,1)), color-stop(18%,rgba(229,255,0,1)), color-stop(24%,rgba(136,255,0,1)), color-stop(30%,rgba(42,255,0,1)), color-stop(36%,rgba(0,255,51,1)), color-stop(42%,rgba(0,255,144,1)), color-stop(48%,rgba(0,255,233,1)), color-stop(54%,rgba(0,187,255,1)), color-stop(60%,rgba(0,93,255,1)), color-stop(66%,rgba(0,0,255,1)), color-stop(72%,rgba(93,0,255,1)), color-stop(78%,rgba(187,0,255,1)), color-stop(84%,rgba(255,0,229,1)), color-stop(90%,rgba(255,0,131,1)), color-stop(95%,rgba(255,0,63,1)), color-stop(100%,rgba(255,0,4,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, rgba(255,0,0,1) 0%,rgba(255,93,0,1) 6%,rgba(255,187,0,1) 12%,rgba(229,255,0,1) 18%,rgba(136,255,0,1) 24%,rgba(42,255,0,1) 30%,rgba(0,255,51,1) 36%,rgba(0,255,144,1) 42%,rgba(0,255,233,1) 48%,rgba(0,187,255,1) 54%,rgba(0,93,255,1) 60%,rgba(0,0,255,1) 66%,rgba(93,0,255,1) 72%,rgba(187,0,255,1) 78%,rgba(255,0,229,1) 84%,rgba(255,0,131,1) 90%,rgba(255,0,63,1) 95%,rgba(255,0,4,1) 100%); /* Chrome10+,Safari5.1+ */
background: linear-gradient(to right, rgba(255,0,0,1) 0%,rgba(255,93,0,1) 6%,rgba(255,187,0,1) 12%,rgba(229,255,0,1) 18%,rgba(136,255,0,1) 24%,rgba(42,255,0,1) 30%,rgba(0,255,51,1) 36%,rgba(0,255,144,1) 42%,rgba(0,255,233,1) 48%,rgba(0,187,255,1) 54%,rgba(0,93,255,1) 60%,rgba(0,0,255,1) 66%,rgba(93,0,255,1) 72%,rgba(187,0,255,1) 78%,rgba(255,0,229,1) 84%,rgba(255,0,131,1) 90%,rgba(255,0,63,1) 95%,rgba(255,0,4,1) 100%); /* W3C */
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-fill-color: transparent;
}
h1 {
font: normal 34px/28px 'Luckiest Guy', Helvetica, Arial;
margin: 10px 0;
text-align: center;
}
#controls {
background: rgba(0,0,0,0.8);
position: fixed;
top: 0;
left: 20px;
width: 250px;
padding: 20px;
-webkit-transform-origin: top center;
-moz-transform-origin: top center;
-o-transform-origin: top center;
transform-origin: top center;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
-webkit-transition: -webkit-transform .5s ease-in-out;
-moz-transition: -moz-transform .5s ease-in-out;
-o-transition: -o-transform .5s ease-in-out;
transition: transform .5s ease-in-out;
}
#controls.closed {
-webkit-transform: rotate(-180deg);
-moz-transform: rotate(-180deg);
-o-transform: rotate(-180deg);
transform: rotate(-180deg);
}
.controller {
float: right;
width: 150px;
}
.toggle-controls {
position: absolute;
display: block;
height: 10px;
background: rgba(0,0,0,0.9);
width: 290px;
left: 0;
text-align: center;
padding: 3px 0 7px;
text-decoration: none;
color: white;
}
#close {
bottom: -20px;
}
#open {
top: -20px;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment