HTML5 canvas绘制雪花飘落动画(需求分析、知识点、程序编写分布详解)

看到网上很多展示html5雪花飞动的效果,确实非常引人入胜,我相信大家也跟我一样看着心动的同时,也很好奇,想研究下代码如何实现;虽然哦很多地方也能下载这些源码,不过也不知道别人制作此类动画时的思路及难点分析。

我这几天刚好学习了一下,也趁着此刻有时间从需求分析、知识点、程序编写一步步给大家解剖下,要是在各位关公面前耍大刀了,可别见笑哟。

最终效果图如下:

html5雪花飞动的效果

图1

一、需求分析

1、圆形雪花

本示例中雪花形状使用圆形

2、雪花数量固定

根据图1仔细观察白色雪花数量,飘落过程中,整张图的雪花数量应该是固定的,这个需求是需要通过我们观察分析所得。这与我们现实生活中看到一幅雪花满天飞的场景是一致的。

3、雪花大小不一致

每朵雪花它们大小各有不同,也就意味着雪花的半径是随机的。这与我们现实生活中看到一幅雪花满天飞的场景也是一致的。

4、雪花位置在移动

雪花飘落,自然它们的位置也在移动。


二、知识点

1、使用Html5 Canvas+JavaScript画圆——构成圆形雪花

在Html5中,需要使用Canvas同时借助JavaScript画圆,以构成圆形雪花——arc(x,y,r,start,stop);

2、随机数—产生不同半径、坐标的圆形雪花

本示例中,网页第一次加载时,需要生成一定数量的不同半径及位置的雪花,故半径、坐标为随机数;雪花在飘落过程中,其半径不变,坐标在一定幅度内变化,故此时坐标也为随机数——

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
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) } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值