//Rose: a = 2nh / (n+1); b = (n-1)h / (n+1) //Fiddle with a, b, and h. //See http://mathworld.wolfram.com/Hypotrochoid.html for more info. //Made by Bogden var PETALS = 4; var width = window.innerWidth, height = window.innerHeight; var x = 100, y = 100, n = PETALS, h = Math.min(width,height)/5, b = (n-1)*h/(n+1), a = 2*n*h/(n+1); var oldX, oldY; function Layer(layerName) { this.canvas = document.getElementById(layerName); this.canvas.width = width; this.canvas.height = height; this.ctx = this.canvas.getContext('2d'); this.ctx.strokeStyle = '#fff'; this.ctx.fillStyle = 'rgba(0,0,0,0.01)'; } Layer.prototype.drawLine = function(x1, y1, x2, y2) { this.ctx.beginPath(); this.ctx.moveTo(x1,y1); this.ctx.lineTo(x2,y2); this.ctx.stroke(); } Layer.prototype.drawDot = function(x1, y1) { this.ctx.beginPath(); this.ctx.moveTo(x1, y1); this.ctx.arc(x1, y1, 5, 0, 2*Math.PI); this.ctx.fill(); } function updatePosition(t) { x = (a-b) * Math.cos(t) + h*Math.cos((a-b)/b*t) + width/2; y = (a-b) * Math.sin(t) - h*Math.sin((a-b)/b*t) + height/2; } function renderFrame(time) { oldX = x; oldY = y; updatePosition(time/(a/b * 1000) * 2 * Math.PI); layer1.drawLine(oldX, oldY, x, y); layer2.ctx.clearRect(0, 0, width, height); layer2.drawDot(x,y); layer1.ctx.fillRect(0,0,width,height); requestAnimationFrame(renderFrame); } var layer1 = new Layer('layer1'); var layer2 = new Layer('layer2'); layer2.ctx.fillStyle = '#f00'; updatePosition(0); setTimeout(renderFrame, 100);