Горный пейзаж со звёздным небом и метеоритами на HTML5 Canvas
1 2 3 4 5 |
#bgCanvas, #terCanvas { position: absolute; top: 0; left: 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
<canvas id="bgCanvas"></canvas> <canvas id="terCanvas"></canvas> <script> (function() { var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); }; window.requestAnimationFrame = requestAnimationFrame; })(); // Terrain stuff. var terrain = document.getElementById("terCanvas"), background = document.getElementById("bgCanvas"), terCtx = terrain.getContext("2d"), bgCtx = background.getContext("2d"), width = window.innerWidth, height = document.body.offsetHeight; (height < 400) ? height = 400: height; terrain.width = background.width = width; terrain.height = background.height = height; // Some random points var points = [], displacement = 140, power = Math.pow(2, Math.ceil(Math.log(width) / (Math.log(2)))); // set the start height and end height for the terrain points[0] = (height - (Math.random() * height / 2)) - displacement; points[power] = (height - (Math.random() * height / 2)) - displacement; // create the rest of the points for (var i = 1; i < power; i *= 2) { for (var j = (power / i) / 2; j < power; j += power / i) { points[j] = ((points[j - (power / i) / 2] + points[j + (power / i) / 2]) / 2) + Math.floor(Math.random() * -displacement + displacement); } displacement *= 0.6; } // draw the terrain terCtx.beginPath(); for (var i = 0; i <= width; i++) { if (i === 0) { terCtx.moveTo(0, points[0]); } else if (points[i] !== undefined) { terCtx.lineTo(i, points[i]); } } terCtx.lineTo(width, terrain.height); terCtx.lineTo(0, terrain.height); terCtx.lineTo(0, points[0]); terCtx.fill(); // Second canvas used for the stars bgCtx.fillStyle = '#05004c'; bgCtx.fillRect(0, 0, width, height); // stars function Star(options) { this.size = Math.random() * 2; this.speed = Math.random() * .1; this.x = options.x; this.y = options.y; } Star.prototype.reset = function() { this.size = Math.random() * 2; this.speed = Math.random() * .1; this.x = width; this.y = Math.random() * height; } Star.prototype.update = function() { this.x -= this.speed; if (this.x < 0) { this.reset(); } else { bgCtx.fillRect(this.x, this.y, this.size, this.size); } } function ShootingStar() { this.reset(); } ShootingStar.prototype.reset = function() { this.x = Math.random() * width; this.y = 0; this.len = (Math.random() * 80) + 10; this.speed = (Math.random() * 10) + 6; this.size = (Math.random() * 1) + 0.1; // this is used so the shooting stars arent constant this.waitTime = new Date().getTime() + (Math.random() * 3000) + 500; this.active = false; } ShootingStar.prototype.update = function() { if (this.active) { this.x -= this.speed; this.y += this.speed; if (this.x < 0 || this.y >= height) { this.reset(); } else { bgCtx.lineWidth = this.size; bgCtx.beginPath(); bgCtx.moveTo(this.x, this.y); bgCtx.lineTo(this.x + this.len, this.y - this.len); bgCtx.stroke(); } } else { if (this.waitTime < new Date().getTime()) { this.active = true; } } } var entities = []; // init the stars for (var i = 0; i < height; i++) { entities.push(new Star({ x: Math.random() * width, y: Math.random() * height })); } // Add 2 shooting stars that just cycle. entities.push(new ShootingStar()); entities.push(new ShootingStar()); //animate background function animate() { bgCtx.fillStyle = '#05004c'; bgCtx.fillRect(0, 0, width, height); bgCtx.fillStyle = '#ffffff'; bgCtx.strokeStyle = '#ffffff'; var entLen = entities.length; while (entLen--) { entities[entLen].update(); } requestAnimationFrame(animate); } animate(); </script></script> |