Заодно переработанный Elastic экспрешн. Новый учитывает вообще все ключи параметра на таймлайне, корректно просчитывая колебания, но из этого же следует, что увеличивается нагрузка. Старый учитывал только два последних ключа, от чего иногда случались рывки.
amp = 0.1;
freq = 1.2;
decay = 3;
var frameOffsetDelta = thisComp.frameDuration / 10;
var calculatedPropertyValue = value;
if (numKeys > 0) {
var lastKeyframeIndex = nearestKey(time).index;
if (key(lastKeyframeIndex).time > time) {
lastKeyframeIndex--;
}
for (var keyframeIndex = 1; keyframeIndex <= lastKeyframeIndex; keyframeIndex++) {
var keyframeTime = key(keyframeIndex).time;
var timeSinceKeyframe = time - keyframeTime;
var velocityBeforeKeyframe = velocityAtTime(keyframeTime - frameOffsetDelta);
var velocityAfterKeyframe = velocityAtTime(keyframeTime + frameOffsetDelta);
var velocityMagnitude = 0;
if (typeof velocityBeforeKeyframe == "number") {
velocityMagnitude = Math.abs(velocityBeforeKeyframe);
} else {
velocityMagnitude = length(velocityBeforeKeyframe);
}
if (velocityMagnitude > 0.1) {
var velocityDifference = velocityBeforeKeyframe - velocityAfterKeyframe;
var oscillationFactor = Math.sin(freq * timeSinceKeyframe * 2 * Math.PI);
var decayFactor = Math.exp(decay * timeSinceKeyframe);
calculatedPropertyValue += (velocityDifference * amp * oscillationFactor) / decayFactor;
}
}
}
calculatedPropertyValue;
сжатый вариант (лично мне удобнее использовать)
amp = 0.1; freq = 1.2; decay = 3;
d=thisComp.frameDuration/10; res=value;
if(numKeys>0){ n=nearestKey(time).index; if(key(n).time>time) n--;
for(i=1;i<=n;i++){ kt=key(i).time; t=time-kt; vIn=velocityAtTime(kt-d); vOut=velocityAtTime(kt+d);
if(((typeof vIn=="number")?Math.abs(vIn):length(vIn))>0.1) res+=(vIn-vOut)*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);}} res;