// prepare the animation canvas and the draw canvas var animcanvas = document.createElement( 'canvas' ), animctx = animcanvas.getContext( '2d' ), drawcanvas = document.createElement( 'canvas' ), drawctx = drawcanvas.getContext( '2d' ); // dimensions and container element var container = document.querySelector('section'), height = width = 300, halfwidth = width / 2, halfheight = height / 2, offset = i = x = 0, radius = height / 2 - 10; function init(){ animcanvas.width = drawcanvas.width = width; animcanvas.height = drawcanvas.height = height; container.appendChild( animcanvas ); container.appendChild( drawcanvas ); drawcanvas.style.opacity = 0.3; drawctx.save(); drawctx.translate( halfwidth, halfheight ); while( radius > 10 ) { drawctx.fillStyle = i % 2 === 0 ? '#000' : '#fff'; radius -= 6; x = Math.sin( i / 2 ) * 10; drawctx.beginPath(); drawctx.arc( x, 0, radius, 0, Math.PI * 2 ,true ); drawctx.closePath(); drawctx.fill(); i++; } drawctx.restore(); loop(); } function loop(){ animctx.clearRect( 0, 0, width, height ); animctx.save(); animctx.translate( halfwidth, halfheight ); offset += 0.06; animctx.rotate( offset ); animctx.fill(); animctx.drawImage( drawcanvas, -halfwidth, -halfheight ); animctx.restore(); requestAnimationFrame( loop, 60 ); } /** * Provides requestAnimationFrame in a cross browser way. * http://paulirish.com/2011/requestanimationframe-for-smart-animating/ */ if ( !window.requestAnimationFrame ) { window.requestAnimationFrame = ( function() { return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( callback, fps ) { window.setTimeout( callback, 1000 / fps ); }; } )(); } init();
<section></section>