Adobe After Effects (приложение для анимации / создания композиций) имеет язык сценариев (Expressions), основанный на JavaScript, и поставляется с набором специфических для After Effects функций, созданных поверх JS. Функция linear()
является одной из них. Он учитывает анимированное изменение свойства одного объекта (скажем, положение ползунка X) и связывает его с другим свойством (скажем, вращением какого-либо другого объекта в сцене), так что первое анимированное свойство контролирует / анимирует второесвойство.
Если это объяснение сбивает с толку, см. 11:33 в этом видео: https://www.youtube.com/watch?v=gK1Ejt7qND0&t=693s
Вызов функции linear()
выглядит следующим образом:
linear(ref, refStart, refEnd, outStart, outEnd);
Я не знаю, каковы фактические внутренние имена arg, но это то, что они делают:
ref
== свойство «controller» (в моем предыдущем примере, положение X объекта). Обычно анимируется, меняется со временем.
refStart
/ refEnd
== нижняя и верхняя границы свойства ref
outStart
/ outEnd
== нижняя и верхняяграницы свойства приемника (в моем предыдущем примере - вращение другого объекта)
Существует ли общий программный термин для того, что делает эта функция? Или математический термин? Насколько я могу судить, это что-то, связанное с "интерполяцией", может быть, линейной интерполяцией, но я неясен.
Существуют ли общие библиотеки по программированию / математике, которые включают эквивалент этой функции? After Effects также ослабил версии linear()
, называемые ease()
, easeIn()
и easeOut()
. Насколько я могу судить, их можно было бы назвать «функциями замедления» в программировании, но не уверен.
Бонус: я попробовал свои силы в обратном проектировании AE linear () с нуля. Довольно скромно и не выполняет никакой проверки типов или ошибок, но в других случаях, похоже, в моем тестировании в AE это работает одинаково:
function fauxLinear( ref, refStart, refEnd, outStart, outEnd ) {
// constrain refTemp to range of refStart to refEnd
let refTemp = 0;
const refMin = Math.min( refStart, refEnd );
const refMax = Math.max( refStart, refEnd );
refTemp = (ref < refMin) ? refMin :
(ref > refMax) ? refMax : ref;
// calculate input range and ref proportion
const refRange = Math.abs( refStart - refEnd ) || .001; // avoid dbz
const refRangeTarget = Math.abs( refMin - refTemp );
const refProportion = refRangeTarget / refRange;
// calculations for final output
let outRange = [], outSlope = [], finalVal = [];
const loopLen = ( Array.isArray( outStart ) ) ? outStart.length : 1;
if (loopLen == 1) { outStart = [outStart], outEnd = [outEnd]; }
for (let i = 0; i < loopLen; i++) {
outRange[i] = Math.abs( outStart[i] - outEnd[i] );
outSlope[i] = ( outStart[i] <= outEnd[i] ) ? 1 : -1;
finalVal[i] = ( outSlope[i] * (outRange[i] * refProportion) + outStart[i] );
}
return ( loopLen == 1 ) ? finalVal[0] : finalVal;
}