学妹说她想看雪,我只能写下这个动画!!

简介: 大家好!我是Fly哥,最近做了很多粒子动画, 对canvas 实现粒子动画有了一点小感悟,前几天北方都下雪了, 身在魔都的我们, 一点点雪的影子都没有。而下雪动画作为粒子动画中我觉得算是比较简单的好理解, 先把这篇文章讲完,后面再去给大家讲 酷炫的 canvas 文字烟花动画。本篇文章大概阅读花费7分钟, 你可以学到如何去实现一个粒子动画,我觉得把思路学会了, 后面产品假设提出任何需求你都是可以cover 住的。废话不多说, 直接先看先看效果:图片snow看着是不是像辣么回事,哈哈哈哈, fly哥写的基础版,圣诞节快到了,你可以在我的基础上做下面👇🏻几个优化使用雪花贴图为每一

大家好!我是Fly哥,最近做了很多粒子动画, 对canvas 实现粒子动画有了一点小感悟,前几天北方都下雪了, 身在魔都的我们, 一点点雪的影子都没有。而下雪动画作为粒子动画中我觉得算是比较简单的好理解, 先把这篇文章讲完,后面再去给大家讲 酷炫的 canvas 文字烟花动画。本篇文章大概阅读花费7分钟, 你可以学到如何去实现一个粒子动画,我觉得把思路学会了, 后面产品假设提出任何需求你都是可以cover 住的。废话不多说, 直接先看先看效果:


640 (7).gif


snow


看着是不是像辣么回事,哈哈哈哈, fly哥写的基础版,圣诞节快到了,你可以在我的基础上做下面👇🏻几个优化


  1. 使用雪花贴图


  1. 为每一个粒子增加重力效果


  1. 性能优化的角度考虑下,考虑使用离屏canvas(数量比较多的情况下,可以去使用)



粒子动画



可能有的人到现在还不是很清楚啥是粒子动画:


粒子


粒子是什么?粒子是一种微小的物体,比如像我们周边环境中的雪花,火星等物体。因此在游戏中一般都用粒子特效来模拟咱们现实生活中的许多自然现象。


粒子系统


粒子系统是众多粒子的集合。一般具有具有粒子的更新,显示,销毁及其创建粒子等性质。不同的粒子系统具有不同的粒子行为,所以所具有的性质会略有区别。


综合


粒子动画其实很容易理解了,就是很多个粒子按照某个特定的运动轨迹组合起来的动画,所以做粒子类属性 会带有一些物理属性, 比如重力,风的阻力, 加速度。。。这些东西,其实主要为了更加贴近自然,更加真实。物理比较差的同学记得把物理知识补一下。


雪粒子


简单介绍上面的概念后,大家可以结合上面的动画简单分析一下,雪粒子这个类应该有哪些属性呢???


首先我的雪花粒子是用「ctx.arc」 去画的,所以呢??「肯定有 x 和 y 轴 坐标 ,还有 radius 半径」



这时候有同学开始抢答了?说fly哥,你上面提到了粒子的速度, 雪花肯定每一个下的速度不一样, 「肯定有一个 vx, vy」


哎呦不错哦, 现在已经5个属性了, 还有没有属性呢, 这时候有个细心的妹子站出来了, 我看到了透明度的变化,确实 还是妹子细心哇!!


image.gif小姐姐


大家在思考下, 还有没有什么属性呢?看着同学们鸦雀无声, 我给一个提醒, 如何保持雪一直下,难道我要不断添加粒子嘛, 有没有边界啥的??



有同学就说:不亏是fly哥,思考问题就是全面哇,哈哈哈哈其实这里涉及到 就一个属性 边界检测呗, 不过没辣么夸张, 「就是是一个最大距离 maxDistance」, 如果超过了 最大距离 我们就让它从一开始落呗, 不就实现了永动机的效果!


编码实现



理论说的都差不多了,我这里写的都是伪代码,本着 「授人以鱼不如授人以渔」 的目的, 你如果真的想学, 跟着我的思路做一篇肯定很没问题!


创建canvas


创建canvas 拿到canvas 的上下文 这个应该不用多讲了


const canvas = document.getElementById( 'canvas' );
  const ctx = canvas.getContext( '2d' );


创建snow 类


主要是每一个小的雪花粒子:


class Snow {
  dia: number
  fill: string
  vy: number
  vx: number
  z: number
  y: number
  x: number
  maxDistance: number
  width: number
  height: number
  constructor(width: number, height: number, maxDistance: number) {
    this.x = Math.random() * (width + maxDistance) - maxDistance / 2
    this.y = Math.random() * (height + maxDistance) - maxDistance / 2
    this.maxDistance = maxDistance
    this.width = width
    this.height = height
    this.z = Math.random() * 0.5 + 0.5
    this.vx = (Math.random() * 2 - 0.5) * this.z
    this.vy = (Math.random() * 1.5 + 1.5) * this.z
    this.fill = 'rgba(255,255,255,' + (0.5 * Math.random() + 0.5) + ')'
    this.dia = (Math.random() * 2.5 + 1.5) * this.z
  }
  draw(ctx: CanvasRenderingContext2D) {
    ctx.beginPath()
    ctx.strokeStyle = 'transparent'
    ctx.fillStyle = this.fill
    ctx.arc(this.x, this.y, this.dia, 0, 2 * Math.PI)
    ctx.closePath()
    ctx.stroke()
    ctx.fill()
    return this
  }
  update() {
    this.x += this.vx
    this.y += this.vy
    if (this.x > this.width + this.maxDistance / 2) {
      this.x = -(this.maxDistance / 2)
    } else if (this.x < -(this.maxDistance / 2)) {
      this.x = this.width + this.maxDistance / 2
    }
    if (this.y > this.height + this.maxDistance / 2) {
      this.y = -(this.maxDistance / 2)
    } else if (this.y < -(this.maxDistance / 2)) {
      this.y = this.height + this.maxDistance / 2
    }
  }
}


这里面 把上面的所说的属性 都讲到了, 其实无论你做任何粒子, 他都有一个创建 和 更新 ,因为你是做动画,


比如第一帧画面 是没有雪花粒子的, 所以第一帧 就是创建粒子,然后后面每一帧其实就是改变粒子的位置 就好了,不断重复这样的过程 配合 requestanimation  去实现。后面每一帧 就是更新 「update」 函数,


我这里还是解释下:粒子不断加 一个固定的速度 「vx vy」 ,然后做了边界判断 , 你可以自己去修改的。由于 有不同的粒子, 粒子的大小 透明度 、速度 都是不同的, 所以 使用了「random」


动画实现



动画实现 很简单 就两步骤


  1. 创建粒子


  1. 更新粒子


// 第一帧 创建1000 个
for (let i = 0; i < 1000; i++) {
  points.push(new Snow(100, 100, 100))
}
// 后面都是更新
 ctx.clearRect(0, 0, view.width, view.height)
 ctx.fillStyle = 'rgba(0,128,255,1)'
 ctx.fillRect(0, 0, view.width, view.height)
 // 调用每个粒子的更新 函数
 points.forEach((point) => {
    point.draw(ctx).update()
 })


相关文章
|
存储 开发工具 索引
游戏编程之十七 生成简单的动画
游戏编程之十七 生成简单的动画
71 0
|
3月前
|
JavaScript
新年倒计时动画网页特效源码
新年倒计时动画网页特效源码是一段基于JS实现的中国节日元旦2025年倒计时动画效果代码,利用此代码,可以实现任意节日的倒计时效果,欢迎对此代码感兴趣的朋友前来下载参考。
106 6
|
缓存 云计算 容器
这个夏天,追光动画在阿里云上“绘出”《长安三万里》
这个夏天,追光动画在阿里云上“绘出”《长安三万里》
625 0
|
前端开发 机器人 程序员
六一 特效~ 你也是大小孩
六一 特效~ 你也是大小孩
142 0
|
存储 程序员
七夕快到了,用SwiftUI做一个表达爱意的心形动画
传统的七夕快到了,作为一个程序猿,最浪漫的礼物当然是自己写的啦! 思来想去也不知道写什么好,在某天在某音上学习时看到点赞的动画效果还不错,那不如就做一个表达爱意的动画吧。
379 0
七夕快到了,用SwiftUI做一个表达爱意的心形动画
|
前端开发 JavaScript
#yyds干货盘点# 前端歌谣的刷题之路-第一百题-控制动画
#yyds干货盘点# 前端歌谣的刷题之路-第一百题-控制动画
108 0
#yyds干货盘点# 前端歌谣的刷题之路-第一百题-控制动画
|
JavaScript 前端开发
WebGL 手撸3d贺卡+小草飘动滤镜
前言 图片 2022-2-15 webGL初始化(常规操作) 获取 WebGLRenderingContext const gl = canvas.getContext('webgl'); 编译shader并把编译好的shader附加到创建好的program中 //顶点着色器 const vertShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertShader,vertSource);//vertSource:着色器源码 gl.compileShader(vertShader);
WebGL 手撸3d贺卡+小草飘动滤镜
逐帧动画案例(奔跑的小人)
逐帧动画案例(奔跑的小人)
265 0
逐帧动画案例(奔跑的小人)
|
算法 API
粉丝和我说想看3D圣诞动画????它来了
前言 大家好我是Fly哥,今天是圣诞节, 首先祝大家圣诞节快乐。今天分享的是从0-1实现一个3D圣诞动画图片 这篇有配套的视频链接讲解 和 源码。我会在文章末尾给出,感兴趣的同学自取哈!!!但是视频的内容过于长了,有的同学还是喜欢看文章。我就讲解下!! 正题 本篇文章大概花费你10分钟,读完本篇文章你可以学到下面几点,可以挑自己感兴趣的点进行阅读 three.js 中加载圣诞树模型 实现自定义曲线路径动画 three.js 中如何 实现粒子动画 three.js 音频导入 和📷 动画 我们先看下圣诞动画实现的效果: 图片 圣诞动画 基本场景的搭建 首先圣诞树需要一个东西去承载, 也就
粉丝和我说想看3D圣诞动画????它来了
|
数据可视化 前端开发 小程序
中秋节——我给心爱的她做了一个3d月球动画
前言 大家好,又到了周末了,又到了Fly写文章的时候了, 过几天不是中秋节了,想着之前写过一篇从0- 1 实现3D地球的,反响效果特别好, 这次趁着🎑节给大家写了一个月球绕地球的运转的动画。本篇文章还是偏入门级别,重在把简单的知识讲清楚,如果是资深three爱好者,可以直接划走了,不浪费大家时间。ok👌言归正传,读完本篇文章你可以学到什么?至于心爱的她—— 就是学习 本文阅读估计花费 5 分钟 天空盒子的制作 three.js 中的贴图 一个物体绕另一个物体旋转 初始化 这篇文章我不会在从头详细的介绍three.js 的一些要素了,如果小伙伴你不是很清楚的话,你可以直接看下我这篇文章入
中秋节——我给心爱的她做了一个3d月球动画