Canvas实现星空旋转动画

需求

  • 实现星空旋转动画

实现

  • src/main.js文件中对requestAnimationFrame做兼容处理
// requestAnimationFrame兼容处理 if (!window.requestAnimationFrame) { window.requestAnimationFrame = ( window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame|| window.oRequestAnimationFrame || function (callback) { return setTimeout(callback, Math.floor(1000 / 60)) } ) }
  • 新建src/utils/star.js文件
function random(min, max = 0) { if (min > max) { [min, max] = [max, min] } return Math.floor(Math.random() * (max - min + 1)) + min } function maxOrbit(x, y) { let max = Math.max(x, y) let diameter = Math.round(Math.sqrt(max * max + max * max)) // 星星移动范围,值越大范围越小 return diameter / 2 } function getCanvas() { let canvas = document.createElement('canvas') let ctx = canvas.getContext('2d') canvas.width = 50 canvas.height = 50 let half = canvas.width / 2 let gd = ctx.createRadialGradient(half, half, 0, half, half, half) gd.addColorStop(0.025, '#CCC') gd.addColorStop(0.1, 'hsl(217, 61%, 33%)') gd.addColorStop(0.25, 'hsl(217, 64%, 6%)') gd.addColorStop(1, 'transparent') ctx.fillStyle = gd ctx.beginPath() ctx.arc(half, half, half, 0, Math.PI * 2) ctx.fill() return canvas } let ww = window.innerWidth let wh = window.innerHeight let canvas = getCanvas() class Star { constructor(ctx, max) { this.ctx = ctx // 旋转星星的半径maxOrbit(w, h) random(maxOrbit(w/4, h/4)) this.orbit = { radius: random(maxOrbit(ww, wh)), x: ww / 2, y: wh / 2 } this.radius = random(60, this.orbit.radius) / 16 this.timePassed = random(0, max) this.speed = random(this.orbit.radius) / 50000 // 星星移动速度 this.alpha = random(2, 10) / 10 } draw() { let x = Math.sin(this.timePassed) * this.orbit.radius + this.orbit.x let y = Math.cos(this.timePassed) * this.orbit.radius + this.orbit.y let twinkle = random(10) if (twinkle === 1 && this.alpha > 0) { this.alpha -= 0.05 } else if (twinkle === 2 && this.alpha < 1) { this.alpha += 0.05 } // 透明闪光 // ctx.globalAlpha = this.alpha this.ctx.drawImage(canvas, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius) this.timePassed += this.speed } } export default Star
  • html代码
<div> <canvas ref="canvasStar"></canvas> </div>
  • javascript代码
import Star from 'utils/star' export default { data() { return { canvas: null, ctx: null, stars: [], numStars: 200 } }, mounted() { this.initCanvas() this.executeFrame() }, methods: { initCanvas() { this.canvas = this.$refs.canvasStar this.ctx = this.canvas.getContext('2d') this.canvas.width = window.innerWidth this.canvas.height = window.innerHeight this.initStars() }, initStars() { this.stars = [] for (let i = 0; i < this.numStars; i++) { this.stars.push(new Star(this.ctx, this.numStars)) } }, drawStars() { // Resize to the screen if (this.canvas.width !== window.innerWidth || this.canvas.width !== window.innerWidth) { this.initCanvas() } this.ctx.globalCompositeOperation = 'source-over' this.ctx.globalAlpha = 0.5 this.ctx.fillStyle = '#000000' this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height) this.ctx.globalCompositeOperation = 'lighter' // 蓝色光环星星数组 this.stars.forEach(item => { item.draw() }) }, executeFrame() { this.drawStars() window.requestAnimationFrame(this.executeFrame) } } }

创作不易,若本文对你有帮助,欢迎打赏支持作者!

 分享给好友: