需求
实现
- 在
src/main.js
文件中对requestAnimationFrame
做兼容处理
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame||
window.oRequestAnimationFrame ||
function (callback) {
return setTimeout(callback, Math.floor(1000 / 60))
}
)
}
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
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
}
this.ctx.drawImage(canvas, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius)
this.timePassed += this.speed
}
}
export default Star
<div>
<canvas ref="canvasStar"></canvas>
</div>
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() {
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)
}
}
}
发表评论