uniapp使用canvas实现雪花飘落动画
时间: 2023-10-22 17:09:52 浏览: 231
Canvas实现动态的雪花效果
1. 创建canvas画布
在uniapp的vue文件中,我们可以使用`<canvas>`标签来创建canvas画布。我们需要设置画布的宽高,以及给画布一个唯一的id。
```
<canvas id="snow-canvas" canvas-id="snow-canvas" :style="{width: canvasWidth + 'px', height: canvasHeight + 'px'}"></canvas>
```
在`data`中定义`canvasWidth`和`canvasHeight`,并在`mounted`生命周期函数中获取canvas的上下文。
```
data() {
return {
canvasWidth: 0,
canvasHeight: 0,
ctx: null,
snows: []
}
},
mounted() {
uni.getSystemInfo({
success: (res) => {
this.canvasWidth = res.windowWidth
this.canvasHeight = res.windowHeight
const context = uni.createCanvasContext('snow-canvas', this)
this.ctx = context
}
})
}
```
2. 定义雪花类
我们可以定义一个雪花类,包含雪花的位置、大小、速度等属性,以及雪花的绘制方法。
```
class Snow {
constructor(canvasWidth, canvasHeight) {
this.x = Math.random() * canvasWidth
this.y = Math.random() * canvasHeight
this.radius = Math.random() * 3 + 1
this.speed = Math.random() * 2 + 1
this.alpha = Math.random() * (1 - 0.5) + 0.5
}
draw(ctx) {
ctx.beginPath()
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`
ctx.fill()
}
update(canvasWidth, canvasHeight) {
this.y += this.speed
if (this.y > canvasHeight) {
this.y = 0
this.x = Math.random() * canvasWidth
}
}
}
```
3. 在canvas中绘制雪花
在`mounted`生命周期函数中,我们可以循环创建多个雪花对象,并将它们存储在`snows`数组中。
```
for (let i = 0; i < 100; i++) {
const snow = new Snow(this.canvasWidth, this.canvasHeight)
this.snows.push(snow)
}
```
在`drawSnows`方法中,我们可以循环遍历`snows`数组,对每个雪花对象进行绘制和更新。
```
drawSnows() {
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
for (let i = 0; i < this.snows.length; i++) {
const snow = this.snows[i]
snow.draw(this.ctx)
snow.update(this.canvasWidth, this.canvasHeight)
}
uni.drawCanvas({
canvasId: 'snow-canvas',
actions: this.ctx.getActions()
}, this)
}
```
4. 实现动画效果
我们可以使用`setInterval`定时器来不断调用`drawSnows`方法,实现雪花飘落的动画效果。
```
setInterval(() => {
this.drawSnows()
}, 30)
```
完整代码如下:
```
<template>
<canvas id="snow-canvas" canvas-id="snow-canvas" :style="{width: canvasWidth + 'px', height: canvasHeight + 'px'}"></canvas>
</template>
<script>
class Snow {
constructor(canvasWidth, canvasHeight) {
this.x = Math.random() * canvasWidth
this.y = Math.random() * canvasHeight
this.radius = Math.random() * 3 + 1
this.speed = Math.random() * 2 + 1
this.alpha = Math.random() * (1 - 0.5) + 0.5
}
draw(ctx) {
ctx.beginPath()
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false)
ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`
ctx.fill()
}
update(canvasWidth, canvasHeight) {
this.y += this.speed
if (this.y > canvasHeight) {
this.y = 0
this.x = Math.random() * canvasWidth
}
}
}
export default {
data() {
return {
canvasWidth: 0,
canvasHeight: 0,
ctx: null,
snows: []
}
},
mounted() {
uni.getSystemInfo({
success: (res) => {
this.canvasWidth = res.windowWidth
this.canvasHeight = res.windowHeight
const context = uni.createCanvasContext('snow-canvas', this)
this.ctx = context
}
})
for (let i = 0; i < 100; i++) {
const snow = new Snow(this.canvasWidth, this.canvasHeight)
this.snows.push(snow)
}
setInterval(() => {
this.drawSnows()
}, 30)
},
methods: {
drawSnows() {
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
for (let i = 0; i < this.snows.length; i++) {
const snow = this.snows[i]
snow.draw(this.ctx)
snow.update(this.canvasWidth, this.canvasHeight)
}
uni.drawCanvas({
canvasId: 'snow-canvas',
actions: this.ctx.getActions()
}, this)
}
}
}
```
阅读全文