应用三次贝塞尔曲线函数为属性更改设置动画

时间:2015-05-08 23:03:37

标签: javascript html css animation bezier

我正在尝试使用立方贝塞尔定时函数动画各种元素的Javascript。

(我知道通常使用CSS3或Javascript动画库可以做得更好。我只是在这里使用Javascript来理解bezier函数是如何工作的,并自学它们。)

所以,我得到了基本概念,我使用的是Stephen McKamey编写的简单bezier曲线库,它是Webkit实现的一个很棒的Javascript端口。

我无法理解如何使用这个函数来控制Javascript中的动画。所以,从一个非常简单的东西开始:一个基本的黑色方块,我可以通过增加它的style.left属性来向右移动它来制作动画:

CSS:

.parent {
    position: relative;
}   

.foo {
    border: 1px solid #000000;
    background-color: black;
    height: 200px;
    width: 200px;
    position: absolute;
}

HTML:

<div class = "parent">
    <div class = "foo" id = "target"></div>
</div>

好的,所以,给定一个三次贝塞尔函数“bezier”,定义如下:

   function bezier(p1x, p1y, p2x, p2y, x, duration) { ... }

其中p1x,p1y,p2x和p2y是曲线控制点(0到1.0之间),xx坐标的值,duration是持续时间毫秒。该函数返回相应的y坐标。我试图通过向右移动400px来简单地为这个黑盒子设置动画。

对于我的第一次尝试,我使用CSS3使用的标准“ease”bezier值,因此我们的ease bezier函数可以写成:

function ease(x, duration) {
    return function() {
        Bezier.cubicBezier(0.25, 0.1, 0.25, 1.0, x, duration);
    }
}

所以这应该给我们一个缓慢的开始,然后快速移动,然后慢慢结束。

好的,所以我假设实现它的基本方法是使用window.setInterval,然后对于每个间隔,使用x的新值调用bezier函数,然后以某种方式将结果应用于属性我们想动画。

问题是,我不确定我的“x”值是什么。我假设在这种情况下,x实际上是时间 y 是旧位置和新位置(移动距离)之间的差值,但我不是非常肯定。我可能错了。

无论如何,插入这一切,我会写一个像:

这样的函数
var startPos = 0;
var endPos = 400; // pixels
var duration = 400; // milliseconds
var millisecondsPerInterval = 10;

var target = document.getElementById("target");
var t = 0;
var pos = 0;

var bezierFunction = Bezier.cubicBezier;

var interval = window.setInterval(
    function() {
        pos = pos + bezierFunction(0.25, 0.1, 0.25, 1.0, t / 1000, duration); // "ease" values
        target.style.left = (pos * millisecondsPerInterval) + "px";
        t += millisecondsPerInterval;
        if (t === duration) { window.clearInterval(interval); }
    },
    millisecondsPerInterval
);

这似乎有用 - 盒子慢慢开始移动然后加速。但它只是突然停止,而不是放松。所以我可能没有正确应用这个功能。我甚至不确定“x”应该是我的时间值,而“y”应该是位置delta(移动距离),但这似乎是唯一的方法应用这是有道理的。

那么,我在这里做错了吗?将立方贝塞尔函数应用于我们想要使用Javascript制作动画的属性的正确方法是什么?

1 个答案:

答案 0 :(得分:-2)

如果您使用JQuery,它可能会使过程更简单。

基于对类似问题(https://stackoverflow.com/a/6824695/363099)的回答,您可以扩展jQuery缓动以添加自定义缓动函数:

  

根据jQuery 1.6.2源代码,缓动函数的含义如下。在动画期间的各个时间点调用该函数。在它被称为时刻,

     
      
  • x和t都表示现在的时间,相对于动画的开头。 x表示为该范围内的浮点数   [0,1],其中0是开始,1是结束。 t表示为   自动画开始以来的毫秒数。

  •   
  • d是动画调用中指定的动画持续时间,以毫秒为单位。

  •   
  • b = 0且c = 1。
  •   

以下是它如何适用于您的代码:

  $.extend(jQuery.easing,{bezier:   function(x,t,b,c,d) {

        return (
          x <= 0 ? 0 :
          x >= 1 ? 1 :
          bezierFunction(0.25, 0.1, 0.25, 1.0, x, d)
            );   
     } });

然后你可以使用JQuery动画功能:

$('#target').animate({right:'400px'},400,'bezier');