我正在尝试使用立方贝塞尔定时函数动画各种元素的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之间),x
是x
坐标的值,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制作动画的属性的正确方法是什么?
答案 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');