function j(d){b.clearRect(0,0,f,f);g[0].value=d.clientX||g[0].value;g[1].value=d.clientY||g[1].value;for(a=4;a--;)h[a]=g[a].value;var e=h[0]/10;d=s-e;var m=d/e,n=0,t=h[1]/10;e=h[2]/2+e;var o=h[3]*2,k,p;for(a=o;a--;){var c=t*n,q=d*Math.sin(c)+e*Math.sin(c*m)+l;c=d*Math.cos(c)-e*Math.cos(c*m)+l;n+=Math.PI*4/o;if(k){b.strokeStyle="hsl("+(r+a%85)+", 80%, 20%)";b.beginPath();b.moveTo(k,p);b.lineTo(q,c);b.closePath();b.stroke()}k=q;p=c}}for(a=4;a--;)document.body.innerHTML+='<input type="range" value="500"" max="1000" style="display:block" onchange="j({})">';
var i=document.getElementById("c"),b=i.getContext("2d"),f=1E3,l=f/2,s=l-100,r=0,a,g=document.getElementsByTagName("input"),h=[];i.width=f;i.height=f;b.globalAlpha=0.3;i.onclick=function(){r=Math.random()*256;j({})};i.onmousemove=j;j({})
for (i = 4; i--;) {
document.body.innerHTML += '<input type="range" value="500"" max="1000" style="display:block" onchange="draw({})">'
}
var canvas = document.getElementById("c"),
ctx = canvas.getContext('2d'),
size = 1000,
halfSize = size / 2,
majorR = halfSize - 100,
hue = 0,
i,
inputs = document.getElementsByTagName('input'),
values = [];
canvas.width = size;
canvas.height = size,
ctx.globalAlpha = .3;
canvas.onclick = function() {
hue = Math.random() * 256;
draw({});
};
canvas.onmousemove = draw
draw({});
function draw(event) {
ctx.clearRect(0, 0, size, size);
inputs[0].value = event.clientX || inputs[0].value
inputs[1].value = event.clientY || inputs[1].value
for (i = 4; i--;) values[i] = inputs[i].value;
var minorR = values[0] / 10,
diff = majorR - minorR,
s = diff / minorR,
theta = 0,
angleMuliplier = values[1] / 10 ,
radiusEffect = values[2] / 2 + minorR,
steps = values[3] * 2,
oldX, oldY;
for (i = steps; i--;) {
var mult = angleMuliplier * theta,
x = diff * Math.sin(mult) + radiusEffect * Math.sin(mult * s) + halfSize,
y = diff * Math.cos(mult) - radiusEffect * Math.cos(mult * s) + halfSize;
theta += Math.PI * 4 / steps;
if (oldX) {
ctx.strokeStyle = 'hsl(' + ( hue + (i % 85)) + ', 80%, 20%)';
ctx.beginPath();
ctx.moveTo(oldX, oldY);
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
}
oldX = x;
oldY = y;
}
}