|
// Drawing code goes here. // // Methods of the canvas 2d context can simply be called // without the "context." object prefix. // // Math functions can be used without the "Math." prefix. // // For CSS colors, the function rgba(r,g,b,a) is available // and better suited for use with animations. // // "anim.type(v1, v2, dt)" can be used to animate any numeric // value. 'type' can be one of 'linear'/'lin', 'sine'/'sin', // 'cos', 'loop', 'easein', 'easeout', 'easeinout'/'ease', // and 'bounce'. // // Time is explicitly available as "t". For explicit animations, // without using the "anim." functions, you need to set the // "animate" variable to "true" like this - // animate = true; canvas.width = 128; canvas.height = 128; canvas.style.backgroundColor = 'black'; var r = createRadialGradient(48, 48, 0, 64, 64, 64); r.addColorStop(0, rgba(255, 255, 255, 1.0)); r.addColorStop(0.95, rgba(0, 0, 0, 0.75)); r.addColorStop(1, rgba(0, 0, 0, 0)); fillStyle = r; fillRect(0, 0, 128, 128); var w = 256, h = 256; canvas.width = w; canvas.height = h; canvas.style.backgroundColor = 'black'; function steelBall(x, y, r) { var grad = createRadialGradient(x - r/3, y - r/3, 0, x, y, r); grad.addColorStop(0, rgba(255, 255, 255, 1.0)); grad.addColorStop(0.97, rgba(0, 0, 0, 0.65)); grad.addColorStop(1, rgba(1, 1, 1, 1)); fillStyle = grad; fillRect(x-r, y-r, 2*r, 2*r); } // Note the twin animations. The ball's motion as well as the ball's // bouncing speed are being animated. steelBall(128, anim.bounce(250-15, anim.sine(64, 200, 120), anim.sine(30, 10, 120)), 15); // Draw a "floor". strokeStyle = rgba(128, 128, 128, 1.0); lineWidth = 3; beginPath(); moveTo(0, 250); lineTo(256, 250); stroke(); var w = 256, h = 256; canvas.width = w; canvas.height = h; canvas.style.backgroundColor = 'black'; function steelBall(x, y, r) { var grad = createRadialGradient(x - r/3, y - r/3, 0, x, y, r); grad.addColorStop(0, rgba(255, 255, 255, 1.0)); grad.addColorStop(0.97, rgba(0, 0, 0, 0.65)); grad.addColorStop(1, rgba(0, 0, 0, 0)); fillStyle = grad; fillRect(x-r, y-r, 2*r, 2*r); } var i; // Make a dozen steel balls, each oscillating with a frequency // that's harmonically related to a fundamental so the balls // will all periodically align. Note that each "anim.sine" // inside the loop is an *independent* animation. for (i = 0; i < 13; ++i) { steelBall(10 + i * 20, anim.sine(50, 150, 240 / (i+1)), 10); } var w = 640, h = 480; canvas.width = w; canvas.height = h; canvas.style.backgroundColor = 'black'; if (t === 0) { var makeSteelBall = prerender(function (r) { with (this) { canvas.width = 2 * r; canvas.height = 2 * r; var grad = createRadialGradient(r - r/3, r - r/3, 0, r, r, r); grad.addColorStop(0, rgba(255, 255, 255, 1.0)); grad.addColorStop(0.97, rgba(0, 0, 0, 0.0)); grad.addColorStop(1, rgba(0, 0, 0, 0)); fillStyle = grad;//rgba(255,0,0,0.2); fillRect(0, 0, 2*r, 2*r); } }); state.steelBall = makeSteelBall(10); } // Make a lot of steel balls, each oscillating with a frequency // that's harmonically related to a fundamental so the balls // will all periodically align. Some mesmerizing visual patterns // arise. This works better in Safari than in Chrome at the moment, // on MacOSX. var x, y; for (var i = 0; i < 640; ++i) { x = i; y = anim.sine(400, 80, 1280 / (i + 1)) - 10; drawImage(steelBall, x, y); } |