<!DOCTYPE html>
<html>
<title>Animation example</title>
<canvas id="trails" style="border: 1px solid;" width="400" height="600"> </canvas>
<script>
var canvas = document.getElementById("trails");
var gravel = new Image();
gravel.src = "gravel.jpg";
gravel.onload = function () {
drawTrails();
}
// create an image for our rain texture
var rain = new Image();
rain.src = "rain.png";
rain.onload = function () {
// Start off the animation with a single frame request
// once the rain is loaded
window.requestAnimFrame(loopAnimation, canvas);
}
function createCanopyPath(context) {
context.beginPath();
context.moveTo(-25, -50);
context.lineTo(-10, -80);
context.lineTo(-20, -80);
context.lineTo(-5, -110);
context.lineTo(-15, -110);
context.lineTo(0, -140);
context.lineTo(15, -110);
context.lineTo(5, -110);
context.lineTo(20, -80);
context.lineTo(10, -80);
context.lineTo(25, -50);
context.closePath();
}
function drawTree(context) {
context.save();
context.transform(1, 0,
-0.5, 1,
0, 0);
context.scale(1, 0.6);
context.fillStyle = 'rgba(0, 0, 0, 0.2)';
context.fillRect(-5, -50, 10, 50);
createCanopyPath(context);
context.fill();
context.restore();
var trunkGradient = context.createLinearGradient(-5, -50, 5, -50);
trunkGradient.addColorStop(0, '#663300');
trunkGradient.addColorStop(0.4, '#996600');
trunkGradient.addColorStop(1, '#552200');
context.fillStyle = trunkGradient;
context.fillRect(-5, -50, 10, 50);
var canopyShadow = context.createLinearGradient(0, -50, 0, 0);
canopyShadow.addColorStop(0, 'rgba(0, 0, 0, 0.5)');
canopyShadow.addColorStop(0.2, 'rgba(0, 0, 0, 0.0)');
context.fillStyle = canopyShadow;
context.fillRect(-5, -50, 10, 50);
createCanopyPath(context);
context.lineWidth = 4;
context.lineJoin = 'round';
context.strokeStyle = '#663300';
context.stroke();
context.fillStyle = '#339900';
context.fill();
}
function drawTrails() {
var context = canvas.getContext('2d');
context.save();
context.clearRect(0, 0, 400, 600);
context.translate(130, 250);
drawTree(context);
context.restore();
context.save();
context.translate(260, 500);
context.scale(2, 2);
drawTree(context);
context.restore();
context.save();
context.translate(-10, 350);
context.beginPath();
context.moveTo(0, 0);
context.quadraticCurveTo(170, -50, 260, -190);
context.quadraticCurveTo(310, -250, 410,-250);
context.strokeStyle = context.createPattern(gravel, 'repeat');
context.lineWidth = 20;
context.stroke();
context.restore();
context.save();
context.font = "60px impact";
context.textAlign = 'center';
context.fillStyle = '#996600';
context.fillText('Happy Trails!', 200, 60, 400);
context.restore();
}
// this function allows us to cover all browsers
// by aliasing the different browser-specific
// versions of the function to a single function
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
// fall back to the old setTimeout technique if nothing
// else is available
function(/* function */ callback, /* DOMElement */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
// This function is where we update the content of our canvas
function drawAFrame() {
var context = canvas.getContext('2d');
// do some drawing on the canvas, using the elapsedTime
// as a guide for changes.
context.save();
// draw the existing trails picture first
drawTrails();
// Darken the canvas for an eerie sky.
// By only darkening most of the time, we create lightning flashes
if (Math.random() > .01) {
context.globalAlpha = 0.65;
context.fillStyle = '#000000';
context.fillRect(0, 0, 400, 600);
context.globalAlpha = 1.0;
}
// Then draw a rain image, adjusted by the current time
var now = Date.now();
context.fillStyle = context.createPattern(rain, 'repeat');
// We'll draw two translated rain images at different rates to
// show thick rain and snow
// Our rectangle will be bigger than the display size, and
// repositioned based on the time
context.save();
context.translate(-256 + (0.1 * now) % 256, -256 + (0.5 * now) % 256);
context.fillRect(0, 0, 400 + 256, 600 + 256);
context.restore();
// The second rectangle translates at a different rate for
// thicker rain appearance
context.save();
context.translate(-256 + (0.08 * now) % 256, -256 + (0.2 * now) % 256);
context.fillRect(0, 0, 400 + 256, 600 + 256);
context.restore();
// draw some explanatory text
context.font = '32px san-serif';
context.textAlign = 'center';
context.fillStyle = '#990000';
context.fillText('Event canceled due to weather!', 200, 550, 400);
context.restore();
}
// This function will be called whenever the browser is ready
// for our application to render another frame.
function loopAnimation(currentTime) {
// Draw a single frame of animation on our canvas
drawAFrame();
// After this frame is drawn, let the browser schedule
// the next one
window.requestAnimFrame(loopAnimation, canvas);
}
</script>
</html>