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

标签 javascript html css animation bezier

我正在 Javascript 中尝试使用三次贝塞尔定时函数为各种元素设置动画。

(我知道这通常最好用 CSS3 或 Javascript 动画库来完成。我只是在这里使用 Javascript 来了解贝塞尔函数的工作原理,并自学它们。)

所以,我了解了基本概念,并且我正在使用 Stephen McKamey 编写的简单贝塞尔曲线库,这是 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 贝塞尔曲线函数可以写成:

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

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

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

问题是,我不确定这里的“x”值是多少。我假设在这种情况下,x 实际上是 time,而 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”是否应该是位置增量(移动距离),但这似乎是唯一有意义的应用方法。

所以,我在这里做错了吗?将三次贝塞尔函数应用于我们想要使用 Javascript 设置动画的属性的正确方法是什么?

最佳答案

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

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

According to the jQuery 1.6.2 source, the meaning of the easing function is as follows. The function is called at various points in time during the animation. At the instants it is called,

  • x and t both say what the time is now, relative to the start of the animation. x is expressed as a floating point number in the range [0,1], where 0 is the start and 1 is the end. t is expressed in milliseconds since the start of the animation.

  • d is the duration of the animation, as specified in the animate call, in milliseconds.

  • b=0 and 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');

关于javascript - 应用三次贝塞尔函数为属性更改设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30134085/

相关文章:

javascript - 使用 place_id 作为参数的谷歌地图静态 map

javascript - 移动突出显示在一页上有效,但在另一页上无效

css - 如何通过CSS改变背景图片的颜色?

html - 用于渲染 html 子集的 Django templatetag

javascript - 两个类之间的状态

javascript - 使用 jquery 将 html 对象转换为字符串失败

javascript - 我可以在打印 HTML 页面时使用 scoped CSS 吗? (使用 Laravel 和 Vue.js)

Javascript:重新分配 'this' ,还是替代方案?

javascript - iframe 和转换的不良行为

javascript - 使用javascript绘制面向对象的lineTo