// an array of keys. The ? represents the applicable number value
var keys = [{
time : 0, // the state of an object at time 0
pos : {x : ? , y : ? }, // position
scale : ?,
rotation : ?,
colour : [?,?,?], // rgb colour, just for the hell of it
// and whatever else you may want to animate
},{
time : 100, // the state of the object at time 100
pos : {x : ? , y : ? },
scale : ?,
rotation : ?,
colour : [?,?,?],
// and whatever else you may want to animate
}
]
var scaleDif = keys[1].scale - keys[0].scale; // get diff in scale
var scaleChange = scaleDif * normTime; // multiply by the normalised time
var currentScale = keys[0].scale + scaleChange; // add to the starting scale
这是有点冗长,但这是为了让你进入正在发生的事情。完整的键控功能看起来像。在
function tweenKeys(time,key1,key2){
var nt = (time - key1.time) / (key2.time - key1.time); // get normalised time
// because you can not divide by zero we need a little check. Javascript return infinity if we div by zero but we want the value 0
nt = nt < Infinity ? nt : 0; // zero if there was a divide by zero
var ck = {}; // ck for current key. the key represents the state at time
ck.scale = key1.scale + (key2.scale - key1.scale) * nt;
ck.rotation = key1.rotation + (key2.rotation - key1.rotation ) * nt;
ck.pos.x = key1.pos.x + (key2.pos.x- key1.pos.x) * nt;
ck.pos.y = key1.pos.y + (key2.pos.y- key1.pos.y) * nt;
ck.colour[0] = key1.colour[0] + (key2.colour[0] - key1.colour[0]) * nt;
ck.colour[1] = key1.colour[1] + (key2.colour[1] - key1.colour[1]) * nt;
ck.colour[2] = key1.colour[2] + (key2.colour[2] - key1.colour[2]) * nt;
return ck; // return the newly create state
}
var dist = Math.sqrt( Math.pow( p2.x - p1.x, 2) + Math.pow( p2.y - p1.y, 2)); // for the twisted world of IE users and
var dist = Math.hypot(p2.x - p1.x, p2.y - p1.y); // for all good browsers
所以标准化的距离是
var normDist = Math.hypot(c.x - p1.x, c.y - p1.y) / Math.hypot(p2.x - p1.x, p2.y - p1.y);
// because you can not divide by zero we need a little check. Javascript returns infinity if we div by zero but we want the value 0
normDist = normDist < Infinity ? normDist : 0; // zero if there was a divide by zero
然后将它(normDist)应用于所有的键状态。在
var currentScale = (keys[1].scale - keys[0].scale) * normDist + keys[0].scale;
// get the unit distance on the line p1,p2 of point c representing
// the distance along the line that is closest to c
function unitDistOfPoint(p1,p2,c){
var v1 = {}; // working vectors
var v2 = {};
v1.x = p2.x - p1.x; // vector between p1,p2
v1.y = p2.y - p1.y;
v2.x = c.x - p1.x; // vector to c from p1
v2.y = c.y - p1.y;
// a little math magic. Divide the dot product of the vectors v2, v1
// by the square of line length
return (v2.x * v1.x + v2.y * v1.y) / (v1.y * v1.y + v1.x * v1.x);
}
现在我们可以做吐温,得到你的秤
// return the state for a object at point c in terms of key1, to key2
function tweenKeysViaPos(c,key1,key2){
// get the normalised distance of the point c between keys 1 and 2
var nd = unitDistOfPoint(c, key1.pos, key2.pos); // nd for normalised distance
// you may want to constrain the position to only between the points
// do that by clamping the value nd between 0 and 1 inclusive
nd = Math.max(0, Math.min(1, nd)); // clamp the normalise distance
var ck = {}; // ck for current key. the key represents the state at time
ck.scale = key1.scale + (key2.scale - key1.scale) * nt;
ck.rotation = key1.rotation + (key2.rotation - key1.rotation ) * nt;
ck.pos.x = key1.pos.x + (key2.pos.x- key1.pos.x) * nt;
ck.pos.y = key1.pos.y + (key2.pos.y- key1.pos.y) * nt;
ck.colour[0] = key1.colour[0] + (key2.colour[0] - key1.colour[0]) * nt;
ck.colour[1] = key1.colour[1] + (key2.colour[1] - key1.colour[1]) * nt;
ck.colour[2] = key1.colour[2] + (key2.colour[2] - key1.colour[2]) * nt;
return ck; // return the newly create state
}
// returns the distance point c is from the line p1,p2. If on the line
// the the return value is 0. If befor point p1 or after p2 then the distance
// is the distance to p1, or p2 respectively
function distFromLine(p1,p2,c){
var v1 = {}; // working vectors
var v2 = {};
v1.x = p2.x - p1.x; // vector between p1,p2
v1.y = p2.y - p1.y;
v2.x = c.x - p1.x; // vector to c from p1
v2.y = c.y - p1.y;
// a little math magic. Divide the dot product of the vectors v2, v1
// by the square of line length
var u = (v2.x * v1.x + v2.y * v1.y) / (v1.y * v1.y + v1.x * v1.x);
var v3 = {};
if(u < 0){ // befor the start
return Math.hypot(v2.x,v2.y); // distance to p1
}
if(u > 1){ // after end
return Math.hypot(c.x - p2.x,c.y p2.y); // distance to p2
}
// get the point on the line that is closest
v3.x = p1.x + v1.x * u;
v3.y = p1.y + v1.y * u;
// return the distance from that point to c
return Math.hypot(c.x - v3.x,c.y - v3.y); // distance from line of c
}
在位置上有点小
关键帧和关键帧
在动画中,我们将已知的位置和状态定义为关键帧,通常我们根据时间索引关键帧。在
标准化时间
为了在关键帧之间的任何时间t获得对象的状态,我们找到时间之间的标准化时间(从0到1的值),然后乘以其他状态之间的差,然后将其添加到开始状态。在
假设时间是50,首先我们得到标准化时间
^{pr2}$现在你有了标准化的时间,你可以很容易地计算出任何状态
这是有点冗长,但这是为了让你进入正在发生的事情。完整的键控功能看起来像。在
这是关键帧的基础,您可以在这个答案中找到更多关于它的内容How would I animate... ?
在空间而不是时间上
一切都好,但对你的问题这没有帮助,你没有使用时间你正在使用位置来确定对象的当前状态。不管我们用什么来找到我们的当前状态,关键帧中的任何一个值都可以用来确定其他所有的状态。我们所要做的就是找到标准化的差异,然后像我们对所有其他值进行归一化处理一样,将其应用于所有其他值。在
标准化位置
我们来看看位置
考虑两点p1和p2,定义为
代表你的A,B位置
如果我们有第三个C点
在二维平面上的某个地方。我们需要一个公式,当C在p1点时返回0,当C点在p2点时返回1。这将是我们用来获得当前状态的标准化位置。在
因为x和y都需要计算。我们得到从p1到点c的距离,然后除以p1和p2之间的距离。这会给我们想要的价值。我们用毕达格解来求距离。平方根和
所以标准化的距离是
然后将它(normDist)应用于所有的键状态。在
定位问题
好吧,你说谢谢,对不起,但这不是解决办法,如果你知道c点总是在p1,p2之间的直线上,那就不一定了,在严格的检查下,它几乎永远不会是因为计算机存储数字信息,所以在任何需要非常精细的细节的计算中都会有一点误差。同样,对于距离p1的p2的任何点,上面的方法将返回1作为标准化距离,它描述了一个围绕点p1的圆。我们需要进一步限制这个值。另外,如果c在点p1之前或者在点p2之后,就很容易知道了。因此,我们可以使用下面的方法。在
现在我们可以做吐温,得到你的秤
这就是答案。如果偏离了c键的位置,那么它也应该远离c键的位置。在
如有需要,可获取更多信息
您可能需要扩展此选项以适应许多关键帧。在比第一帧更容易找到关键帧的地方。但是如果你用这个位置来计算你在哪一个键,这就不那么简单了。一个复杂的函数可以帮助你找到更方便的解决方案
然后,您可以通过查找从它们之间的直线返回最小距离的键来找到所需的两个键。然后通过定义许多关键帧来定义一条复杂的线,并且无论你把一个对象放在哪里,你都可以计算出它应该在哪里,处于什么状态。在
希望这对你有帮助,不要太过分。如果任何人不清楚,请在评论中说出来,我会澄清的。在
对于线性缩放,如果
D[Ay]
是圆/正方形在Ay
处的直径/边D[By]
是圆/正方形在By
处的直径/边D[Cy]
是圆/正方形在Cy
处的直径/边Ay <= Cy <= By
那么
D[Cy] = D[Ay] + (Cy - Ay) * (D[By] - D[Ay]) / (By - Ay)
如果向量}之间的线可以定义为
v=(By-Ay)
,那么Ay
和{l(t)=Ay+vt
。因此,l(t)
上带有参数t
的任何点都具有s=47.5t+5
的缩放因子。例如,在t=0处,这条直线上的点Ay
具有缩放因子s=5
。如果你把t=1
放进去,你就可以通过并缩放s= 52.5
。对于你的附加问题,比例因子是相同的,但你不能简单地乘以比例因子中的正方形坐标。您需要使用l(t)
将正方形平移到原点,并缩放坐标并将其转换回l(t)
。在相关问题 更多 >
编程相关推荐