365bet电子平台-【亚洲官方投注】

热门关键词: 365bet电子平台,365bet亚洲官方投注,365bet真人在线投注

打造高大上的Canvas粒子动画,动画函数的绘制及自定义动画函数

2020-01-06 09:17 来源:未知

图片 1

打造高大上的Canvas粒子动画

2016/08/22 · HTML5 · 5 评论 · Canvas

原文出处: 腾讯ISUX   

首先来看下我们准备要做的粒子动画效果是怎么样的~

是这样:

图片 2

或者是这样:

图片 3

甚至是这样:

图片 4

很酷炫!

那如何去实现类似上面的粒子动画甚至根据自己的喜好去做更多其他轨迹的动画呢~请看下面详细的讲解。

制作动画效果离不开动画运动函数,而我们用得最多的无疑就是Tween.js。根据不同的数学公式原理,Tween.js划分出了不同的动画类型,每种动画类型里面都包含以下的缓动类型:

ease in先慢后快ease out先块后慢ease in out先慢后快再慢

技术选择

因为粒子数量很多,而且涉及到图像像素处理,所以这里使用Canvas是不二选择。

 

注意,以下演示的代码只是关键代码,重点在于解决思路。

关于缓动函数,我们在css3动画里已经用得太多了,不再细讲。Tween.js源代码请看:Tween.js

一、绘制粒子轮廓图

首先要在canvas画布上绘制一个由粒子组成的轮廓图,记录下每一个粒子的坐标,这样才能有后续的动画。

绘制动画曲线

1. 创建一个<canvas>元素,并获取Canvas画布渲染上下文

图片 5

< canvas>是一个双标签元素,通过width和height的值来设置画布的大小。至于ctx(画布渲染上下文),可以理解为画布上的画笔,我们可以通过画笔在画布上随心所欲的绘制图案。如果浏览器不支持canvas会直接显示<canvas>标签中间自己设定的文字。当然<canvas>标签中间也可以是一张当不支持canvas时需要替换显示的图片。

 

2. 使用canvas的图像操作API绘制图像

绘制图像的关键API及参数说明:

图片 6

引用MDN上的一张图会比较清晰的看出每个参数的作用:

图片 7

drawImage就是把一个image对象或者canvas上(甚至是video对象上的的每一帧)指定位置和尺寸的图像绘制到当前的画布上。而在我们的需求中,是要把整个图像绘制到画布中。

图片 8

对应浏览器看到的效果:

图片 9

 

我们可以根据实际情况选择对应的动画函数,但问题是有十几个动画函数,一个个试过去也太麻烦了。有没有一种直观的方式让我们一目了然的知道每种动画的运动效果呢?当然有,那就是把动画函数绘制出来,渲染方式多种多样,csssvgcanvas,从效果和便携考虑,我选择用canvas实现。实现原理其实非常简单,基本就是调用canvas的基础api,demo的效果请看:TweenJS动画运动函数绘制

3. 获取图像的像素信息,并根据像素信息重新绘制出粒子效果轮廓图

canvas有一个叫getImageData的接口,通过该接口可以获取到画布上指定位置的全部像素的数据:

图片 10

把获取的imageData输出到控制台可以看到,imageData包含三个属性:

图片 11

其中,width、height是读取图像像素信息完整区域的宽度和高度,data是一个Uint8ClampedArray类型的一维数组,包含了整个图片区域里每个像素点的RGBA的整型数据。这里必须要理解这个数组所保存像素信息的排序规则,请看下图描述的data数组:

图片 12

每一个色值占据data数组索引的一个位置,一个像素有个4个值(R、G、B、A)占据数组的4个索引位置。根据数列规则可以知道,要获取第n个位置(n从1开始)的R、G、B像素信息就是:Rn = (n-1)*4 ,Gn = (n-1)*4+1 ,Bn = (n-1)*4+2  ,so easy~  当然,实际上图像是一个包括image.height行,image.width列像素的矩形而不是单纯的一行到结束的,这个n值在矩形中要计算下:

图片 13

由于一个像素是带有4个索引值(rgba)的,所以拿到图像中第i行第j列的R、G、B、A像素信息就是 Rij = [(j-1)*imageData.width + (i-1)]*4 ,Gij = [(j-1)*imageData.width + (i-1)]*4 + 1,Bij = [(j-1)*imageData.width + (i-1)]*4 + 2,Aij = [(j-1)*imageData.width + (i-1)]*4 + 3 。每个像素值都可以拿到了!

接下来就要把图像的粒子化轮廓图画出来了。那么,怎么做这个轮廓图呢,我们先读取每个像素的信息(用到上面的计算公式),如果这个像素的色值符合要求,就保存起来,用于绘制在画布上。另外,既然是做成粒子的效果,我们只需要把像素粒子保存一部分,展示在画布上。

具体做法是,设定每一行和每一列要显示的粒子数,分别是cols和rows,一个粒子代表一个单元格,那么每个单元格的的宽高就是imageWidth/cols和imageHeight/rows,然后循环的判断每个单元格的第一个像素是否满足像素值的条件,如果满足了,就把这个单元格的坐标保存到数组里,用作后续绘制图案用。

关键参考代码:

图片 14

用完整代码做出的demo及效果:

图片 15

至此,粒子轮廓图已经制作完成。

 

这里解释一下坐标界面,X轴是运动时间,Y轴则是运动的距离。点击tween类型和ease类型选择框,就可以看到对应运动曲线的绘制动画,以及右边小球的实际运动效果。核心代码如下:

二、制作粒子动画

制作粒子动画分两种:

一种是粒子漂浮类,这种比较简单,只需要随机的改变每个粒子的位置值,然后一直执行setInterval或者requestAnimationFrame重绘画布即可,具体的效果因人喜好而去设定,就不具体讲解了,做了个简单的粒子漂浮的例子。

另一种是粒子的轨迹动画,这个相对复杂一些。这里要介绍的是每个粒子按照指定的轨迹在指定的时间内做位移,最终汇聚成指定图案的动画效果(也就是文章一开始的动效),要做成这类动画效果需要解决两个问题:一个是动画轨迹,另外一个是每个粒子执行动画的时机。

 function orbit(){ ctx.save(); ctx.translate(10,450); ctx.strokeStyle ='hsl(30,100%,50%)'; ctx.beginPath(); ctx.clearRect(0,1,500,150); ctx.moveTo(0,0); pos.forEach(function(n,i){ ctx.lineTo(n.x,n.y); }); ctx.stroke(); ctx.restore(); } function ball(y){ ctx.save(); ctx.clearRect(520,0,90,600); ctx.translate(540,450-y); ctx.fillStyle = gradient; ctx.beginPath(); ctx.arc(0,0,15,0,Math.PI*2,false); ctx.fill(); ctx.restore(); } ~function animate(){ isRunning = true; t = new Date() - start; if(t  duration) { pos.push({x:xLen,y:-yLen}); orbit(); ball(yLen); isRunning = false; return; } y = fn(t,0,yLen,duration); pos.push({x:t*space,y:-y}) orbit(); ball(y); requestAnimationFrame(animate); }();

粒子动画轨迹

动画位移的轨迹,最常见的就是单位时间内改变固定的位移值,从而达到动画效果。但要做到炫酷的效果依赖这种单调固定的位移肯定是不行的。所以位移可以依赖缓动函数去做到单位时间内改变不一样的位移值,从而达到特别的效果。

自定义动画函数

制作缓动效果有两种方法:

一种是自己设定好控制点,然后通过贝塞尔曲线公式来计算每个单位时间的坐标值。

引用了wikipedia里面的图:

图片 16图片 17

上面两个图都是在绘制一条特定曲线,可以看出二次曲线需要一个特定控制点P1,三次曲线需要两个特定控制点P1和P2来确定一条曲线,高阶曲线甚至需要更多的控制点来确定曲线轨迹。

求曲线的公式是根据德卡斯特里奥算法计算得来的,直接上公式。

二次曲线对应的公式:

图片 18

三次曲线对应的公式:

图片 19

从公式可以看出,只要确定控制点坐标、起始坐标和终点坐标后,就可以确定了一条曲线,然后就可以根据曲线公式求出每个时刻t对应的位置值B(t)。

当然使用这种方法需要自己去制定控制点坐标,计算也比较复杂,实现起来很繁琐。没事,我们还有别的办法确定曲线。

 

另外一种方法就是使用已有的缓动函数,不需要自己制定控制点,这里推荐出名的Tween算法的缓动函数,用其中一个缓动函数来介绍下参数值,其他缓动函数所传的参数值是一样的:

图片 20

是不是觉得很熟悉?对没错,jquery用的动画扩展插件easing.js就是Tween算法的缓动函数。有了这现成的缓动函数,就可以制定粒子的起始点、终点(终点就是图案本身的坐标位置)以及动画执行持续时间来做我们要的效果。

关键参考代码:

图片 21

根据参考代码做出一个效果:

图片 22

嗯,动画效果是有了,但总感觉不太对劲。。。唔,仔细观察一下,是图案动画执行太过整体了,没有明显的颗粒动画效果,这就引出粒子动画的另一个关键点,粒子执行动画的时机。

 

TAG标签:
版权声明:本文由365bet电子平台发布于Web前端,转载请注明出处:打造高大上的Canvas粒子动画,动画函数的绘制及自定义动画函数