星空旋转特效
1 function random(min, max) { 2 if (arguments.length < 2) { 3 max = min; 4 min = 0; 5 } 6 if (min > max) { 7 const hold = max; 8 max = min; 9 min = hold; 10 } 11 return Math.floor(Math.random() * (max - min + 1)) + min; 12 } 13 14 // 星星移动范围,值越大范围越小 15 function maxOrbit(x, y) { 16 const max = Math.max(x, y); 17 const diameter = Math.round(Math.sqrt(max * max + max * max)); 18 return diameter / 2; 19 } 20 21 export default class Star { 22 constructor(ctx, canvas2, w, h, maxStars) { 23 this.ctx = ctx; 24 this.canvas2 = canvas2; 25 26 this.orbitRadius = random(maxOrbit(w, h)); 27 this.radius = random(60, this.orbitRadius) / 8; 28 // 星星大小 29 this.orbitX = w / 2; 30 this.orbitY = h / 2; 31 this.timePassed = random(0, maxStars); 32 // 转动速度 33 this.speed = random(this.orbitRadius) / 500000; 34 // 透明度-闪烁效果 35 this.alpha = random(2, 10) / 10; 36 } 37 38 draw() { 39 const x = Math.sin(this.timePassed) * this.orbitRadius + this.orbitX; 40 const y = Math.cos(this.timePassed) * this.orbitRadius + this.orbitY; 41 const twinkle = random(10); 42 43 if (twinkle === 1 && this.alpha > 0) { 44 this.alpha -= 0.05; 45 } else if (twinkle === 2 && this.alpha < 1) { 46 this.alpha += 0.05; 47 } 48 49 this.ctx.globalAlpha = this.alpha; 50 this.ctx.drawImage(this.canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius); 51 this.timePassed += this.speed; 52 } 53 }
1 import 'jquery'; 2 import Star from './star'; 3 4 const hue = 217; 5 const stars = []; 6 const maxStars = 1300; // 星星数量 7 8 export default class Stars { 9 constructor(canvas) { 10 this.ctx = canvas.getContext('2d'); 11 this.w = canvas.width = canvas.clientWidth; 12 this.h = canvas.height = canvas.clientHeight; 13 14 const canvas2 = document.createElement('canvas'); 15 const ctx2 = canvas2.getContext('2d'); 16 canvas2.width = 100; 17 canvas2.height = 100; 18 const half = canvas2.width / 2; 19 const gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half); 20 gradient2.addColorStop(0.025, '#CCC'); 21 gradient2.addColorStop(0.1, `hsl(${hue}, 61%, 33%)`); 22 gradient2.addColorStop(0.25, `hsl(${hue}, 64%, 6%)`); 23 gradient2.addColorStop(1, 'transparent'); 24 25 ctx2.fillStyle = gradient2; 26 ctx2.beginPath(); 27 ctx2.arc(half, half, half, 0, Math.PI * 2); 28 ctx2.fill(); 29 30 for (let i = 0; i < maxStars; i++) { 31 stars[i] = new Star(this.ctx, canvas2, this.w, this.h, maxStars); 32 } 33 } 34 35 animation() { 36 this.ctx.globalCompositeOperation = 'source-over'; 37 this.ctx.globalAlpha = 0.5; // 尾巴 38 this.ctx.fillStyle = `hsla(${ hue }, 64%, 6%, 2)`; 39 this.ctx.fillRect(0, 0, this.w, this.h) 40 41 this.ctx.globalCompositeOperation = 'lighter'; 42 for (let i = 1, l = stars.length; i < l; i++) { 43 stars[i].draw(); 44 }; 45 46 window.requestAnimationFrame(this.animation.bind(this)); 47 } 48 }
import Stars from 'utils/star/index.js' const canvas = document.getElementById('canvas'); const stars = new Stars(canvas); stars.animation();
1 #canvas { 2 position: absolute; 3 left: 0; 4 top: 0; 5 z-index: -1; 6 display: inline-block; 7 width: 100%; 8 height: 100%; 9 }