キーダウンイベントに対応した、流れ星のアニメーションを適切に制御する。

HTML,JavaScript

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="UTF-8"> 5 <link rel="stylesheet" href="Moon.css"> 6 </head> 7 <body> 8 <canvas id="canvas"></canvas> 9 10 <script> 11 let canvas, ctx, w, h, moon, meteor; 12 let count = 0; 13 let stars = []; 14 let meteors = []; 15 16 function init() { 17 canvas = document.querySelector("#canvas"); 18 ctx = canvas.getContext("2d"); 19 resizeReset(); 20 moon = new Moon(); 21 for (let a = 0; a < w * h * 0.0001; a++) { 22 stars.push(new Star()); 23 } 24 // for (let b = 0; b < 7; b++) { 25 // meteors.push(new Meteor()); 26 // } 27 StarAnimationLoop(); 28 } 29 30 const countUp = () => { 31 if (count < 80) { 32 count++; 33 console.log(count); 34 drawMeteorScene(); 35 requestAnimationFrame(countUp); 36 } 37 } 38 39 function keydown() { 40 count = 0; 41 meteor = new Meteor(); 42 meteors.push(meteor); 43 countUp(); 44 // MeteorAnimationLoop(); 45 // if (meteor.y >= h + 50) { 46 // cancelAnimationFrame(MeteorAnimationLoop); 47 // } 48 } 49 50 function resizeReset() { 51 w = canvas.width = window.innerWidth; 52 h = canvas.height = window.innerHeight; 53 } 54 55 function StarAnimationLoop() { 56 ctx.clearRect(0, 0, w, h); 57 drawStarScene(); 58 requestAnimationFrame(StarAnimationLoop); 59 } 60 61 function MeteorAnimationLoop() { 62 drawMeteorScene(); 63 // requestAnimationFrame(MeteorAnimationLoop); 64 } 65 66 function drawStarScene() { 67 moon.draw(); 68 stars.map((star) => { 69 star.update(); 70 star.draw(); 71 }) 72 } 73 74 function drawMeteorScene() { 75 meteors.map((meteor) => { 76 meteor.update(); 77 meteor.draw(); 78 }) 79 } 80 81 class Moon { 82 constructor() { 83 this.x = 150; 84 this.y = 150; 85 this.size = 100; 86 } 87 draw() { 88 ctx.save(); 89 ctx.beginPath(); 90 ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); 91 ctx.shadowColor = "rgba(254, 247, 144, .5)"; 92 ctx.shadowBlur = 50; 93 ctx.fillStyle = "rgba(254,247,144, 1)"; 94 ctx.fill(); 95 ctx.closePath(); 96 ctx.restore(); 97 } 98 } 99 100 class Star { 101 constructor() { 102 this.x = Math.random() * w; 103 this.y = Math.random() * h; 104 this.size = Math.random() + 0.5; 105 this.blinkChance = 0.05; 106 this.alpha = 1; 107 this.alphaChange = 0; 108 } 109 draw() { 110 ctx.beginPath(); 111 ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); 112 ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`; 113 ctx.fill(); 114 ctx.closePath(); 115 } 116 update(){ 117 if (this.alphaChange === 0 && Math.random() < this.blinkChance) { 118 this.alphaChange = -1; 119 } else if (this.alphaChange !== 0) { 120 this.alpha += this.alphaChange * 0.5; 121 if (this.alpha <= 0) { 122 this.alphaChange = 1; 123 } else if (this.alpha >= 1) { 124 this.alphaChange = 0; 125 } 126 } 127 } 128 } 129 130 class Meteor { 131 constructor() { 132 this.reset(); 133 } 134 reset() { 135 this.x = Math.random() * w; 136 this.y = -100; 137 this.size = Math.random() * 2 + 0.5; 138 this.speed = (Math.random() + 1) * 5; 139 } 140 draw() { 141 ctx.save(); 142 ctx.strokeStyle = "rgba(255, 255, 255, .1)"; 143 ctx.lineCap = "round"; 144 ctx.shadowColor = "rgba(255, 255, 255, 1)"; 145 ctx.shadowBlur = 10; 146 for (let i = 0; i < 10; i++) { 147 ctx.beginPath(); 148 ctx.moveTo(this.x, this.y); 149 ctx.lineWidth = this.seze; 150 ctx.lineTo(this.x + 10 * (i + 1), this.y - 10 * (i + 1)); 151 ctx.stroke(); 152 ctx.closePath(); 153 } 154 ctx.restore(); 155 } 156 update() { 157 this.x -= this.speed; 158 this.y += this.speed; 159 if ( this.y >= h + 50) { 160 this.reset(); 161 } 162 } 163 } 164 165 window.addEventListener("DOMContentLoaded", init); 166 window.addEventListener("keydown", keydown); 167 window.addEventListener("resize", resizeReset); 168 </script> 169 </body> 170</html>

コメントを投稿

0 コメント