@tamagui/cubic-bezier-animator 1.88.13 → 1.89.0-1706360676826
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/cubicBezier.mjs +56 -0
- package/dist/esm/index.mjs +33 -0
- package/dist/jsx/cubicBezier.mjs +56 -0
- package/dist/jsx/index.mjs +33 -0
- package/package.json +3 -3
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const float32ArraySupported = typeof Float32Array == "function";
|
|
2
|
+
function A(aA1, aA2) {
|
|
3
|
+
return 1 - 3 * aA2 + 3 * aA1;
|
|
4
|
+
}
|
|
5
|
+
function B(aA1, aA2) {
|
|
6
|
+
return 3 * aA2 - 6 * aA1;
|
|
7
|
+
}
|
|
8
|
+
function C(aA1) {
|
|
9
|
+
return 3 * aA1;
|
|
10
|
+
}
|
|
11
|
+
function calcBezier(aT, aA1, aA2) {
|
|
12
|
+
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
|
|
13
|
+
}
|
|
14
|
+
function getSlope(aT, aA1, aA2) {
|
|
15
|
+
return 3 * A(aA1, aA2) * aT * aT + 2 * B(aA1, aA2) * aT + C(aA1);
|
|
16
|
+
}
|
|
17
|
+
function binarySubdivide(aX, aA, aB, mX1, mX2) {
|
|
18
|
+
let currentX,
|
|
19
|
+
currentT,
|
|
20
|
+
i = 0;
|
|
21
|
+
do currentT = aA + (aB - aA) / 2, currentX = calcBezier(currentT, mX1, mX2) - aX, currentX > 0 ? aB = currentT : aA = currentT; while (Math.abs(currentX) > 1e-7 && ++i < 10);
|
|
22
|
+
return currentT;
|
|
23
|
+
}
|
|
24
|
+
function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
|
|
25
|
+
for (let i = 0; i < 4; ++i) {
|
|
26
|
+
const currentSlope = getSlope(aGuessT, mX1, mX2);
|
|
27
|
+
if (currentSlope === 0) return aGuessT;
|
|
28
|
+
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
|
|
29
|
+
aGuessT -= currentX / currentSlope;
|
|
30
|
+
}
|
|
31
|
+
return aGuessT;
|
|
32
|
+
}
|
|
33
|
+
function LinearEasing(x) {
|
|
34
|
+
return x;
|
|
35
|
+
}
|
|
36
|
+
function bezier(mX1, mY1, mX2, mY2) {
|
|
37
|
+
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) throw new Error("bezier x values must be in [0, 1] range");
|
|
38
|
+
if (mX1 === mY1 && mX2 === mY2) return LinearEasing;
|
|
39
|
+
const sampleValues = float32ArraySupported ? new Float32Array(11) : new Array(11);
|
|
40
|
+
for (let i = 0; i < 11; ++i) sampleValues[i] = calcBezier(i * 0.1, mX1, mX2);
|
|
41
|
+
function getTForX(aX) {
|
|
42
|
+
let intervalStart = 0,
|
|
43
|
+
currentSample = 1;
|
|
44
|
+
const lastSample = 10;
|
|
45
|
+
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) intervalStart += 0.1;
|
|
46
|
+
--currentSample;
|
|
47
|
+
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]),
|
|
48
|
+
guessForT = intervalStart + dist * 0.1,
|
|
49
|
+
initialSlope = getSlope(guessForT, mX1, mX2);
|
|
50
|
+
return initialSlope >= 1e-3 ? newtonRaphsonIterate(aX, guessForT, mX1, mX2) : initialSlope === 0 ? guessForT : binarySubdivide(aX, intervalStart, intervalStart + 0.1, mX1, mX2);
|
|
51
|
+
}
|
|
52
|
+
return function (x) {
|
|
53
|
+
return x === 0 || x === 1 ? x : calcBezier(getTForX(x), mY1, mY2);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export { bezier };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { bezier } from "./cubicBezier.mjs";
|
|
2
|
+
function animate(param) {
|
|
3
|
+
let start = null;
|
|
4
|
+
const easing = param.cubicBezier ? bezier(...param.cubicBezier) : v => v,
|
|
5
|
+
{
|
|
6
|
+
x: fromX,
|
|
7
|
+
y: fromY,
|
|
8
|
+
scaleX: fromScaleX,
|
|
9
|
+
scaleY: fromScaleY
|
|
10
|
+
} = param.from,
|
|
11
|
+
{
|
|
12
|
+
x: toX,
|
|
13
|
+
y: toY,
|
|
14
|
+
scaleX: toScaleX,
|
|
15
|
+
scaleY: toScaleY
|
|
16
|
+
} = param.to;
|
|
17
|
+
function frame(timestamp) {
|
|
18
|
+
start || (start = timestamp);
|
|
19
|
+
const progress = timestamp - start,
|
|
20
|
+
x = toX !== void 0 ? fromX + (toX - fromX) * easing(progress / param.duration) : void 0,
|
|
21
|
+
y = toY !== void 0 ? fromY + (toY - fromY) * easing(progress / param.duration) : void 0,
|
|
22
|
+
scaleX = toScaleX !== void 0 ? fromScaleX + (toScaleX - fromScaleX) * easing(progress / param.duration) : void 0,
|
|
23
|
+
scaleY = toScaleY !== void 0 ? fromScaleY + (toScaleY - fromScaleY) * easing(progress / param.duration) : void 0;
|
|
24
|
+
param.onUpdate({
|
|
25
|
+
x,
|
|
26
|
+
y,
|
|
27
|
+
scaleX,
|
|
28
|
+
scaleY
|
|
29
|
+
}), progress < param.duration && requestAnimationFrame(frame);
|
|
30
|
+
}
|
|
31
|
+
requestAnimationFrame(frame);
|
|
32
|
+
}
|
|
33
|
+
export { animate };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const float32ArraySupported = typeof Float32Array == "function";
|
|
2
|
+
function A(aA1, aA2) {
|
|
3
|
+
return 1 - 3 * aA2 + 3 * aA1;
|
|
4
|
+
}
|
|
5
|
+
function B(aA1, aA2) {
|
|
6
|
+
return 3 * aA2 - 6 * aA1;
|
|
7
|
+
}
|
|
8
|
+
function C(aA1) {
|
|
9
|
+
return 3 * aA1;
|
|
10
|
+
}
|
|
11
|
+
function calcBezier(aT, aA1, aA2) {
|
|
12
|
+
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
|
|
13
|
+
}
|
|
14
|
+
function getSlope(aT, aA1, aA2) {
|
|
15
|
+
return 3 * A(aA1, aA2) * aT * aT + 2 * B(aA1, aA2) * aT + C(aA1);
|
|
16
|
+
}
|
|
17
|
+
function binarySubdivide(aX, aA, aB, mX1, mX2) {
|
|
18
|
+
let currentX,
|
|
19
|
+
currentT,
|
|
20
|
+
i = 0;
|
|
21
|
+
do currentT = aA + (aB - aA) / 2, currentX = calcBezier(currentT, mX1, mX2) - aX, currentX > 0 ? aB = currentT : aA = currentT; while (Math.abs(currentX) > 1e-7 && ++i < 10);
|
|
22
|
+
return currentT;
|
|
23
|
+
}
|
|
24
|
+
function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
|
|
25
|
+
for (let i = 0; i < 4; ++i) {
|
|
26
|
+
const currentSlope = getSlope(aGuessT, mX1, mX2);
|
|
27
|
+
if (currentSlope === 0) return aGuessT;
|
|
28
|
+
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
|
|
29
|
+
aGuessT -= currentX / currentSlope;
|
|
30
|
+
}
|
|
31
|
+
return aGuessT;
|
|
32
|
+
}
|
|
33
|
+
function LinearEasing(x) {
|
|
34
|
+
return x;
|
|
35
|
+
}
|
|
36
|
+
function bezier(mX1, mY1, mX2, mY2) {
|
|
37
|
+
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) throw new Error("bezier x values must be in [0, 1] range");
|
|
38
|
+
if (mX1 === mY1 && mX2 === mY2) return LinearEasing;
|
|
39
|
+
const sampleValues = float32ArraySupported ? new Float32Array(11) : new Array(11);
|
|
40
|
+
for (let i = 0; i < 11; ++i) sampleValues[i] = calcBezier(i * 0.1, mX1, mX2);
|
|
41
|
+
function getTForX(aX) {
|
|
42
|
+
let intervalStart = 0,
|
|
43
|
+
currentSample = 1;
|
|
44
|
+
const lastSample = 10;
|
|
45
|
+
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) intervalStart += 0.1;
|
|
46
|
+
--currentSample;
|
|
47
|
+
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]),
|
|
48
|
+
guessForT = intervalStart + dist * 0.1,
|
|
49
|
+
initialSlope = getSlope(guessForT, mX1, mX2);
|
|
50
|
+
return initialSlope >= 1e-3 ? newtonRaphsonIterate(aX, guessForT, mX1, mX2) : initialSlope === 0 ? guessForT : binarySubdivide(aX, intervalStart, intervalStart + 0.1, mX1, mX2);
|
|
51
|
+
}
|
|
52
|
+
return function (x) {
|
|
53
|
+
return x === 0 || x === 1 ? x : calcBezier(getTForX(x), mY1, mY2);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export { bezier };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { bezier } from "./cubicBezier.mjs";
|
|
2
|
+
function animate(param) {
|
|
3
|
+
let start = null;
|
|
4
|
+
const easing = param.cubicBezier ? bezier(...param.cubicBezier) : v => v,
|
|
5
|
+
{
|
|
6
|
+
x: fromX,
|
|
7
|
+
y: fromY,
|
|
8
|
+
scaleX: fromScaleX,
|
|
9
|
+
scaleY: fromScaleY
|
|
10
|
+
} = param.from,
|
|
11
|
+
{
|
|
12
|
+
x: toX,
|
|
13
|
+
y: toY,
|
|
14
|
+
scaleX: toScaleX,
|
|
15
|
+
scaleY: toScaleY
|
|
16
|
+
} = param.to;
|
|
17
|
+
function frame(timestamp) {
|
|
18
|
+
start || (start = timestamp);
|
|
19
|
+
const progress = timestamp - start,
|
|
20
|
+
x = toX !== void 0 ? fromX + (toX - fromX) * easing(progress / param.duration) : void 0,
|
|
21
|
+
y = toY !== void 0 ? fromY + (toY - fromY) * easing(progress / param.duration) : void 0,
|
|
22
|
+
scaleX = toScaleX !== void 0 ? fromScaleX + (toScaleX - fromScaleX) * easing(progress / param.duration) : void 0,
|
|
23
|
+
scaleY = toScaleY !== void 0 ? fromScaleY + (toScaleY - fromScaleY) * easing(progress / param.duration) : void 0;
|
|
24
|
+
param.onUpdate({
|
|
25
|
+
x,
|
|
26
|
+
y,
|
|
27
|
+
scaleX,
|
|
28
|
+
scaleY
|
|
29
|
+
}), progress < param.duration && requestAnimationFrame(frame);
|
|
30
|
+
}
|
|
31
|
+
requestAnimationFrame(frame);
|
|
32
|
+
}
|
|
33
|
+
export { animate };
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/cubic-bezier-animator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.89.0-1706360676826",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"source": "src/index.
|
|
5
|
+
"source": "src/index.tsx",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
7
7
|
"main": "dist/cjs",
|
|
8
8
|
"module": "dist/esm",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"clean:build": "tamagui-build clean:build"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@tamagui/build": "1.
|
|
24
|
+
"@tamagui/build": "1.89.0-1706360676826"
|
|
25
25
|
},
|
|
26
26
|
"exports": {
|
|
27
27
|
"./package.json": "./package.json",
|