@lightningjs/renderer
Version:
Lightning 3 Renderer
137 lines • 4.52 kB
JavaScript
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2023 Comcast Cable Communications Management, LLC.
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const tfCache = {};
const cubicBezierMap = {
ease: [0.25, 0.1, 0.25, 1.0],
'ease-in': [0.42, 0, 1.0, 1.0],
'ease-out': [0, 0, 0.58, 1.0],
'ease-in-out': [0.42, 0, 0.58, 1.0],
'ease-in-sine': [0.12, 0, 0.39, 0],
'ease-out-sine': [0.12, 0, 0.39, 0],
'ease-in-out-sine': [0.37, 0, 0.63, 1],
'ease-in-cubic': [0.32, 0, 0.67, 0],
'ease-out-cubic': [0.33, 1, 0.68, 1],
'ease-in-out-cubic': [0.65, 0, 0.35, 1],
'ease-in-circ': [0.55, 0, 1, 0.45],
'ease-out-circ': [0, 0.55, 0.45, 1],
'ease-in-out-circ': [0.85, 0, 0.15, 1],
'ease-in-back': [0.36, 0, 0.66, -0.56],
'ease-out-back': [0.34, 1.56, 0.64, 1],
'ease-in-out-back': [0.68, -0.6, 0.32, 1.6],
};
const createCubicBezierFunction = (a, b, c, d) => {
const xc = 3.0 * a;
const xb = 3.0 * (c - a) - xc;
const xa = 1.0 - xc - xb;
const yc = 3.0 * b;
const yb = 3.0 * (d - b) - yc;
const ya = 1.0 - yc - yb;
return function (time) {
if (time >= 1.0) {
return 1;
}
if (time <= 0) {
return 0;
}
let t = 0.5;
let cbx;
let cbxd;
let dx;
for (let it = 0; it < 20; it++) {
cbx = t * (t * (t * xa + xb) + xc);
dx = time - cbx;
if (dx > -1e-8 && dx < 1e-8) {
return t * (t * (t * ya + yb) + yc);
}
// Cubic bezier derivative.
cbxd = t * (t * (3 * xa) + 2 * xb) + xc;
if (cbxd > 1e-10 && cbxd < 1e-10) {
// Problematic. Fall back to binary search method.
break;
}
t += dx / cbxd;
}
// Fallback: binary search method. This is more reliable when there are near-0 slopes.
let minT = 0;
let maxT = 1;
for (let it = 0; it < 20; it++) {
t = 0.5 * (minT + maxT);
cbx = t * (t * (t * xa + xb) + xc);
dx = time - cbx;
if (dx > -1e-8 && dx < 1e-8) {
// Solution found!
return t * (t * (t * ya + yb) + yc);
}
if (dx < 0) {
maxT = t;
}
else {
minT = t;
}
}
return time;
};
};
const parseCubicBezier = (str) => {
//cubic-bezier(0.84, 0.52, 0.56, 0.6)
const regex = /-?\d*\.?\d+/g;
const match = str.match(regex);
if (match) {
const [num1, num2, num3, num4] = match;
const a = parseFloat(num1 || '0.42');
const b = parseFloat(num2 || '0');
const c = parseFloat(num3 || '1');
const d = parseFloat(num4 || '1');
const timing = createCubicBezierFunction(a, b, c, d);
tfCache[str] = timing;
return timing;
}
// parse failed, return linear
console.warn('cubic-bezier invalid' + str);
return null;
};
export const normalizeTimingFunction = (something) => {
if (something === undefined ||
(typeof something !== 'string' && typeof something !== 'function')) {
return null;
}
//predefined timing functions
if (typeof something === 'function') {
return something;
}
if (tfCache[something] !== undefined) {
return tfCache[something];
}
if (cubicBezierMap[something] !== undefined) {
const [a, b, c, d] = cubicBezierMap[something];
const tf = createCubicBezierFunction(a, b, c, d);
tfCache[something] = tf;
return tf;
}
//custom cubic-bezier
if (something.startsWith('cubic-bezier')) {
const tf = parseCubicBezier(something);
if (tf !== null) {
tfCache[something] = tf;
}
return tf;
}
return null;
};
//# sourceMappingURL=utils.js.map