需求
实现
- 在
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))
}
)
}
<div>
<canvas ref="canvasSpace"></canvas>
</div>
export default {
data() {
return {
canvas: null,
ctx: null,
stars: [],
numStars: 1000,
center: { x: 0, y: 0 },
radius: 1
}
},
mounted() {
this.initCanvas()
this.executeFrame()
},
methods: {
initCanvas() {
this.canvas = this.$refs.canvasSpace
this.ctx = this.canvas.getContext('2d')
this.canvas.width = window.innerWidth
this.canvas.height = window.innerHeight
this.center.x = this.canvas.width / 2
this.center.y = this.canvas.height / 2
this.radius = '0.' + Math.floor(Math.random() * 9) + 1
this.initStars()
},
initStars() {
this.stars = []
for (let i = 0; i < this.numStars; i++) {
this.stars.push({
x: Math.random() * this.canvas.width,
y: Math.random() * this.canvas.height,
z: Math.random() * this.canvas.width,
o: '0.' + Math.floor(Math.random() * 10) + 1
})
}
},
moveStars() {
this.stars = this.stars.map(item => {
item.z--
if (item.z < 0) {
item.z = this.canvas.width
}
return item
})
},
drawStars() {
if (this.canvas.width !== window.innerWidth || this.canvas.width !== window.innerWidth) {
this.initCanvas()
}
this.ctx.fillStyle = 'rgba(0, 10, 20, 1)'
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
this.fillStyle = `rgba(209, 255, 255, ${this.radius})`
let focalLength = this.canvas.width * 2
this.stars.forEach(item => {
let pixelX = (item.x - this.center.x) * (focalLength / item.z)
let pixelY = (item.y - this.center.y) * (focalLength / item.z)
let pixelRadius = 1
pixelX += this.center.x
pixelY += this.center.y
this.ctx.fillRect(pixelX, pixelY, pixelRadius, pixelRadius)
this.ctx.fillStyle = '#fff'
})
},
executeFrame() {
this.moveStars()
this.drawStars()
window.requestAnimationFrame(this.executeFrame)
}
}
}
发表评论