Flash基础入门之JS模拟CSS3动画-贝塞尔曲线
小标 2019-01-24 来源 : 阅读 1131 评论 0

摘要:本文主要向大家介绍了Flash基础入门之JS模拟CSS3动画-贝塞尔曲线,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。

本文主要向大家介绍了Flash基础入门之JS模拟CSS3动画-贝塞尔曲线,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。

一、什么是贝塞尔曲线

1962年,法国工程师皮埃尔·贝塞尔(Pierre  Bézier),贝塞尔曲线来为为解决汽车的主体的设计问题而发明了贝塞尔曲线。如今,贝赛尔曲线是计算机图形学中相当重要的一种曲线,它能过优雅地模拟人手绘画出的线。它通过控制曲线上的点(起始点、终止点以及多个参考点)来创造、编辑图形。其中起重要作用的是位于曲线中央的控制线。这条线是虚拟的,中间与贝塞尔曲线交叉,两端是控制端点。移动两端的端点时贝塞尔曲线改变曲线的曲率(弯曲的程度);移动中间点(也就是移动虚拟的控制线)时,贝塞尔曲线在起始点和终止点锁定的情况下做均匀移动。

二、贝塞尔曲线的应用

贝赛尔曲线广泛应用于绘图软件中,例如Adobe PhotoShop、Adobe Flash。

Android可以通过自定义的view来实现贝塞尔曲线

ios则可以使用UIBezierPath类来生成贝塞尔曲线

前端,canvas bezierCurveTo,css animation-timing-function: cubic-bezier(x,x,x,x}都有关于贝赛尔曲线的一些应用

三、贝塞尔曲线公式及其分析

一次:

二次:

三次:

n次

但是公式中只是给出了点与点之间的关系,并没有给出y与x坐标的关系,为此我们需要对其进行分解,下面以三次贝塞尔曲线为例子:

四、贝塞尔曲线在动画中的应用

如图,X轴用来表示时间,Y轴用来表示动画的完成度。所以贝塞尔曲线在动画中的应用很简单,每隔一定时间传入当前动画的执行时间占总时间的比例然后就可以得出动画在此时刻完成的程度,最后只需要设置一下此时刻动画的完成度就行了。由于它的起始坐标分别为(0,0),(1,1)。

JS代码实现

我们已经求出了三次贝塞尔曲线x,y与t的关系,那么就可以根据这个关系通过JS实现

function UnitBezier(p1x,p1y,p2x,p2y) {         this.cx = 3.0 * p1x;         this.bx = 3.0 * (p2x - p1x) - this.cx;         this.ax = 1.0 - this.cx -this.bx;             this.cy = 3.0 * p1y;         this.by = 3.0 * (p2y - p1y) - this.cy;         this.ay = 1.0 - this.cy - this.by; } UnitBezier.prototype = {     sampleCurveX : function(t) {         return ((this.ax * t + this.bx) * t + this.cx) * t;     },     sampleCurveY : function(t) {           return ((this.ay * t + this.by) * t + this.cy) * t;     } }


可能到这里感觉上,我们已经实现了贝塞尔曲线的在动画上的应用了,我们看下这个demo.

然而我们发现原始JS实现的动画效果明显不同于CSS3中的动画效果。那么该如何去模拟了?看下面的代码:

function UnitBezier(p1x,p1y,p2x,p2y) {         this.cx = 3.0 * p1x;         this.bx = 3.0 * (p2x - p1x) - this.cx;         this.ax = 1.0 - this.cx -this.bx;             this.cy = 3.0 * p1y;         this.by = 3.0 * (p2y - p1y) - this.cy;         this.ay = 1.0 - this.cy - this.by; } UnitBezier.prototype = {     sampleCurveX : function(t) { //贝赛尔曲线t时刻的坐标点的X坐标         return ((this.ax * t + this.bx) * t + this.cx) * t;     },     sampleCurveY : function(t) {  //贝赛尔曲线t时刻的坐标点的y坐标         return ((this.ay * t + this.by) * t + this.cy) * t;     },     solve:function(t){         this.sampleCurveY(this.sampleCurveX(t))      } }


我们再来测试一下看下效果

额,这下差别更大。但是仔细想想这里所有的数据基本都是浮点运算,那么产生的误差可想而知。

五、浮点型运算误差

在计算机中浮点型运算造成的误差非常普遍,不管是C、C++、java、javaScript等待语言都存在,因为都是按照IEEE 754标准来进行浮点运算。

IEEE 754

按照IEEE 754 标准,32位中有:

1位是符号位(sign)

8位是指数位(exponent)

23位是数值 (fraction)

那么计算出的结果为:

举些栗子

比如 0.1的单精度浮点数在计算机二进制数为:

0 01111011 10011001100110011001101

那么实际值为

比如 0.5的单精度浮点数在计算机二进制数为:

0 01111110 00000000000000000000000

六、怎样缩小浮点型运算产生的误差

首先我们可以来看下最简单的减少误差的方法

放大法

由于浮点型运算会产生误差,因此我们可以变相地将它放大,知道它为整数,最后返回的时候在将值还原,而这种方法是为完全将误差消除的。


Math.formatFloat = function(f, digit) {  
    var m = Math.pow(10, digit);  
    return parseInt(f*m,10) m;  
}

var numA = 0.1;  
var numB = 0.2;
alert(Math.formatFloat(numA+numB,1)===0.3);

虽然这种方法在JS中能够很好地消除误差,但是并不是所有的场景均适应。它比较时候简单的加减运算和位数较低的乘法除法运算,这是因为在JS中精确整数的范围被定义为:−9007199254740992到9007199254740992(2的53次方),也就是说最多16位。然而我们的贝塞尔曲线应用在动画的过程中肯定会产生位数超过16位的浮点数,这种方式仍然不能解决问题。

二分法

二分法是我们在高中的时候老师就已经给我们讲过,不过那个时候通常是用来判断f(x0)是正数还是负数,有时候还会给出精度要求。在这里我们同样也可以使用二分法来解决,我们只需要不断地利用二分法找出(f(x0)-x)

function division(x,t1,t2, epsilon,func) {//计算x的近似值         var t0,             t1,             t2,             x2,             i;             t2 = x;             if (t2 < t0)                  return t0;             if (t2 > t1)                 return t1;             while (t0 < t1) {                 x2 = func(t2);                 if (Math.abs(x2 - x) < epsilon)                     return t2;                 if (x > x2)                     t0 = t2;                 else t1 = t2;                     t2 = (t1 - t0) * .5 + t0;             }         return t2;     }


牛顿迭代法

牛顿迭代法也是常常在计算机中减少误差的一种常用方法,公式如下:

设r是f(x)=0的根,选取x0作为r的初始近似值,过点(x0,f(x0))做曲线  的切线L,L的方程为y=f(x0)+f’(x0)(x-x0),求出L与x轴交点的横坐标 x1=x0-f(x0)/f’(x0)  ,称x1为r的一次近似值。过点 做曲线 的切线,并求该切线与x轴交点的横坐标 ,称  为r的二次近似值。重复以上过程,得r的近似值序列,其中,xn+1=xn-f(xn)/f’(xn)称为r的n+1次近似值。

在处理贝塞尔曲线的过程中,由于我们不可能求出真正准确的值,为此我们只需要满足f(x0)-x

最终的效果

最后已经非常接近CSS3自带的贝塞尔曲线动画效果了,虽然仍有一点差别,这是因为采取的方法只能使误差只能缩小而不能被消除,而且精度越多,那么JS动画性能就越差,所以这里精度为设定为0.01.


以上就介绍了Flash的相关知识,希望对Flash有兴趣的朋友有所帮助。了解更多内容,请关注职坐标常用软件Flash频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程