重新创建CSS3过渡Cubic-Bezier曲线 [英] Recreating CSS3 transitions Cubic-Bezier curve
问题描述
在CSS3过渡中,您可以将计时函数指定为'cubic-bezier:(0.25,0.3,0.8,1.0)'
在该字符串中,您仅指定沿P1和P2点的XY曲线,因为P0和P3始终分别是(0.0,0.0)和(1.0,1.0)。
根据苹果公司的网站:
x [表示]
我的问题是,如何将其映射回javascript中的传统一维T值? ?
-
希望这对某人有帮助!
function loop(){
var t =(now-animationStartTime)/(animationDuration * 1000);
var曲线= new UnitBezier(Bx,By,Cx,Cy);
var t1 = curve.solve(t,UnitBezier.prototype.epsilon);
var s1 = 1.0-t1;
//使用求解的T
进行rp变数finalPosition.x =(startPosition.x * s1)+(endPosition.x * t1);
var finalPosition.y =(startPosition.y * s1)+(endPosition.y * t1);
}
/ **
*三次贝塞尔曲线的求解器,隐含控制点为(0,0)和(1.0,1.0)
* /
函数UnitBezier(p1x,p1y,p2x,p2y){
//预计算多项式系数
//第一个和最后一个控制点隐含为(0,0)和(1.0,1.0)
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.epsilon = 1e-6; //精度
UnitBezier.prototype.sampleCurveX = function(t){
return((this.ax * t + this.bx)* t + this.cx)* t;
}
UnitBezier.prototype.sampleCurveY =函数(t){
return((this.ay * t + this.by)* t + this.cy)* t;
}
UnitBezier.prototype.sampleCurveDerivativeX =函数(t){
return(3.0 * this.ax * t + 2.0 * this.bx)* t + this.cx;
}
UnitBezier.prototype.solveCurveX = function(x,epsilon){
var t0;
var t1;
var t2;
var x2;
var d2;
var i;
//首先尝试牛顿方法的一些迭代-通常非常快。
for(t2 = x,i = 0; i< 8; i ++){
x2 = this.sampleCurveX(t2)-x;
如果(Math.abs(x2)< epsilon)
返回t2;
d2 = this.sampleCurveDerivativeX(t2);如果(Math.abs(d2)< epsilon)中断
,则
;
t2 = t2-x2 / d2;
}
//未找到解决方案-使用二等分
t0 = 0.0;
t1 = 1.0;
t2 = x;
如果(t2 如果(t2> t1)返回t1;
而(t0 x2 = this.sampleCurveX(t2);
如果(Math.abs(x2-x)< epsilon)
返回t2;
如果(x> x2)t0 = t2;
else t1 = t2;
t2 =(t1-t0)* .5 + t0;
}
//放弃
return t2;
}
//沿着曲线X找到新的T作为Y的函数
UnitBezier.prototype.solve =函数(x,epsilon){
返回此值。 sampleCurveY(this.solveCurveX(x,epsilon));
}
In CSS3 transitions, you can specify a timing function as 'cubic-bezier:(0.25, 0.3, 0.8, 1.0)' In that string, you are only specifying the XY for points P1 and P2 along the curve, as P0 and P3 are always (0.0, 0.0), and (1.0, 1.0) respectively.
According to Apple's site: x [is] expressed as a fraction of the overall duration and y expressed as a fraction of the overall change
My question is how can this be mapped back to a traditional 1 dimensional T value in javascript?
--
From Apple docs on animating with transitions
Browsing through webkit-source a bit, the following code will give the correct T value for the implicit curve used in CSS3 transitions:
Hope this helps someone!
function loop(){
var t = (now - animationStartTime) / ( animationDuration*1000 );
var curve = new UnitBezier(Bx, By, Cx, Cy);
var t1 = curve.solve(t, UnitBezier.prototype.epsilon);
var s1 = 1.0-t1;
// Lerp using solved T
var finalPosition.x = (startPosition.x * s1) + (endPosition.x * t1);
var finalPosition.y = (startPosition.y * s1) + (endPosition.y * t1);
}
/**
* Solver for cubic bezier curve with implicit control points at (0,0) and (1.0, 1.0)
*/
function UnitBezier(p1x, p1y, p2x, p2y) {
// pre-calculate the polynomial coefficients
// First and last control points are implied to be (0,0) and (1.0, 1.0)
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.epsilon = 1e-6; // Precision
UnitBezier.prototype.sampleCurveX = function(t) {
return ((this.ax * t + this.bx) * t + this.cx) * t;
}
UnitBezier.prototype.sampleCurveY = function (t) {
return ((this.ay * t + this.by) * t + this.cy) * t;
}
UnitBezier.prototype.sampleCurveDerivativeX = function (t) {
return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;
}
UnitBezier.prototype.solveCurveX = function (x, epsilon) {
var t0;
var t1;
var t2;
var x2;
var d2;
var i;
// First try a few iterations of Newton's method -- normally very fast.
for (t2 = x, i = 0; i < 8; i++) {
x2 = this.sampleCurveX(t2) - x;
if (Math.abs (x2) < epsilon)
return t2;
d2 = this.sampleCurveDerivativeX(t2);
if (Math.abs(d2) < epsilon)
break;
t2 = t2 - x2 / d2;
}
// No solution found - use bi-section
t0 = 0.0;
t1 = 1.0;
t2 = x;
if (t2 < t0) return t0;
if (t2 > t1) return t1;
while (t0 < t1) {
x2 = this.sampleCurveX(t2);
if (Math.abs(x2 - x) < epsilon)
return t2;
if (x > x2) t0 = t2;
else t1 = t2;
t2 = (t1 - t0) * .5 + t0;
}
// Give up
return t2;
}
// Find new T as a function of Y along curve X
UnitBezier.prototype.solve = function (x, epsilon) {
return this.sampleCurveY( this.solveCurveX(x, epsilon) );
}
这篇关于重新创建CSS3过渡Cubic-Bezier曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!