feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,141 @@
'use strict';
/**
* https://github.com/gre/bezier-easing
* BezierEasing - use bezier curve for transition easing function
* by Gaëtan Renaudeau 2014 - 2015 MIT License
*/
// These values are established by empiricism with tests (tradeoff: performance VS precision)
const NEWTON_ITERATIONS = 4;
const NEWTON_MIN_SLOPE = 0.001;
const SUBDIVISION_PRECISION = 0.0000001;
const SUBDIVISION_MAX_ITERATIONS = 10;
const kSplineTableSize = 11;
const kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
function A(aA1, aA2) {
'worklet';
return 1.0 - 3.0 * aA2 + 3.0 * aA1;
}
function B(aA1, aA2) {
'worklet';
return 3.0 * aA2 - 6.0 * aA1;
}
function C(aA1) {
'worklet';
return 3.0 * aA1;
}
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
function calcBezier(aT, aA1, aA2) {
'worklet';
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
}
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
function getSlope(aT, aA1, aA2) {
'worklet';
return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
}
function binarySubdivide(aX, aA, aB, mX1, mX2) {
'worklet';
let currentX;
let currentT;
let i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
} else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
'worklet';
for (let i = 0; i < NEWTON_ITERATIONS; ++i) {
const currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) {
return aGuessT;
}
const currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
export function Bezier(mX1, mY1, mX2, mY2) {
'worklet';
function LinearEasing(x) {
'worklet';
return x;
}
if (!(mX1 >= 0 && mX1 <= 1 && mX2 >= 0 && mX2 <= 1)) {
throw new Error('[Reanimated] Bezier x values must be in [0, 1] range.');
}
if (mX1 === mY1 && mX2 === mY2) {
return LinearEasing;
}
// FIXME: Float32Array is not available in Hermes right now
//
// var float32ArraySupported = typeof Float32Array === 'function';
// const sampleValues = float32ArraySupported
// ? new Float32Array(kSplineTableSize)
// : new Array(kSplineTableSize);
// Precompute samples table
const sampleValues = new Array(kSplineTableSize);
for (let i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
function getTForX(aX) {
'worklet';
let intervalStart = 0.0;
let currentSample = 1;
const lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
// Interpolate to provide an initial guess for t
const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
const guessForT = intervalStart + dist * kSampleStepSize;
const initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return function BezierEasing(x) {
'worklet';
if (mX1 === mY1 && mX2 === mY2) {
return x; // linear
}
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
if (x === 0) {
return 0;
}
if (x === 1) {
return 1;
}
return calcBezier(getTForX(x), mY1, mY2);
};
}
//# sourceMappingURL=Bezier.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,568 @@
'use strict';
/**
* Copied from:
* react-native/Libraries/StyleSheet/normalizeColor.js
* react-native/Libraries/StyleSheet/processColor.js
* https://github.com/wcandillon/react-native-redash/blob/master/src/Colors.ts
*/
/* eslint no-bitwise: 0 */
import { makeShareable } from './core';
import { isAndroid, isWeb } from './PlatformChecker';
// var INTEGER = '[-+]?\\d+';
const NUMBER = '[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)';
const PERCENTAGE = NUMBER + '%';
function call(...args) {
'worklet';
return '\\(\\s*(' + args.join(')\\s*,\\s*(') + ')\\s*\\)';
}
const MATCHERS = {
rgb: new RegExp('rgb' + call(NUMBER, NUMBER, NUMBER)),
rgba: new RegExp('rgba' + call(NUMBER, NUMBER, NUMBER, NUMBER)),
hsl: new RegExp('hsl' + call(NUMBER, PERCENTAGE, PERCENTAGE)),
hsla: new RegExp('hsla' + call(NUMBER, PERCENTAGE, PERCENTAGE, NUMBER)),
hex3: /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
hex4: /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
hex6: /^#([0-9a-fA-F]{6})$/,
hex8: /^#([0-9a-fA-F]{8})$/
};
function hue2rgb(p, q, t) {
'worklet';
if (t < 0) {
t += 1;
}
if (t > 1) {
t -= 1;
}
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
}
function hslToRgb(h, s, l) {
'worklet';
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
const r = hue2rgb(p, q, h + 1 / 3);
const g = hue2rgb(p, q, h);
const b = hue2rgb(p, q, h - 1 / 3);
return Math.round(r * 255) << 24 | Math.round(g * 255) << 16 | Math.round(b * 255) << 8;
}
function parse255(str) {
'worklet';
const int = Number.parseInt(str, 10);
if (int < 0) {
return 0;
}
if (int > 255) {
return 255;
}
return int;
}
function parse360(str) {
'worklet';
const int = Number.parseFloat(str);
return (int % 360 + 360) % 360 / 360;
}
function parse1(str) {
'worklet';
const num = Number.parseFloat(str);
if (num < 0) {
return 0;
}
if (num > 1) {
return 255;
}
return Math.round(num * 255);
}
function parsePercentage(str) {
'worklet';
// parseFloat conveniently ignores the final %
const int = Number.parseFloat(str);
if (int < 0) {
return 0;
}
if (int > 100) {
return 1;
}
return int / 100;
}
const names = makeShareable({
transparent: 0x00000000,
// http://www.w3.org/TR/css3-color/#svg-color
aliceblue: 0xf0f8ffff,
antiquewhite: 0xfaebd7ff,
aqua: 0x00ffffff,
aquamarine: 0x7fffd4ff,
azure: 0xf0ffffff,
beige: 0xf5f5dcff,
bisque: 0xffe4c4ff,
black: 0x000000ff,
blanchedalmond: 0xffebcdff,
blue: 0x0000ffff,
blueviolet: 0x8a2be2ff,
brown: 0xa52a2aff,
burlywood: 0xdeb887ff,
burntsienna: 0xea7e5dff,
cadetblue: 0x5f9ea0ff,
chartreuse: 0x7fff00ff,
chocolate: 0xd2691eff,
coral: 0xff7f50ff,
cornflowerblue: 0x6495edff,
cornsilk: 0xfff8dcff,
crimson: 0xdc143cff,
cyan: 0x00ffffff,
darkblue: 0x00008bff,
darkcyan: 0x008b8bff,
darkgoldenrod: 0xb8860bff,
darkgray: 0xa9a9a9ff,
darkgreen: 0x006400ff,
darkgrey: 0xa9a9a9ff,
darkkhaki: 0xbdb76bff,
darkmagenta: 0x8b008bff,
darkolivegreen: 0x556b2fff,
darkorange: 0xff8c00ff,
darkorchid: 0x9932ccff,
darkred: 0x8b0000ff,
darksalmon: 0xe9967aff,
darkseagreen: 0x8fbc8fff,
darkslateblue: 0x483d8bff,
darkslategray: 0x2f4f4fff,
darkslategrey: 0x2f4f4fff,
darkturquoise: 0x00ced1ff,
darkviolet: 0x9400d3ff,
deeppink: 0xff1493ff,
deepskyblue: 0x00bfffff,
dimgray: 0x696969ff,
dimgrey: 0x696969ff,
dodgerblue: 0x1e90ffff,
firebrick: 0xb22222ff,
floralwhite: 0xfffaf0ff,
forestgreen: 0x228b22ff,
fuchsia: 0xff00ffff,
gainsboro: 0xdcdcdcff,
ghostwhite: 0xf8f8ffff,
gold: 0xffd700ff,
goldenrod: 0xdaa520ff,
gray: 0x808080ff,
green: 0x008000ff,
greenyellow: 0xadff2fff,
grey: 0x808080ff,
honeydew: 0xf0fff0ff,
hotpink: 0xff69b4ff,
indianred: 0xcd5c5cff,
indigo: 0x4b0082ff,
ivory: 0xfffff0ff,
khaki: 0xf0e68cff,
lavender: 0xe6e6faff,
lavenderblush: 0xfff0f5ff,
lawngreen: 0x7cfc00ff,
lemonchiffon: 0xfffacdff,
lightblue: 0xadd8e6ff,
lightcoral: 0xf08080ff,
lightcyan: 0xe0ffffff,
lightgoldenrodyellow: 0xfafad2ff,
lightgray: 0xd3d3d3ff,
lightgreen: 0x90ee90ff,
lightgrey: 0xd3d3d3ff,
lightpink: 0xffb6c1ff,
lightsalmon: 0xffa07aff,
lightseagreen: 0x20b2aaff,
lightskyblue: 0x87cefaff,
lightslategray: 0x778899ff,
lightslategrey: 0x778899ff,
lightsteelblue: 0xb0c4deff,
lightyellow: 0xffffe0ff,
lime: 0x00ff00ff,
limegreen: 0x32cd32ff,
linen: 0xfaf0e6ff,
magenta: 0xff00ffff,
maroon: 0x800000ff,
mediumaquamarine: 0x66cdaaff,
mediumblue: 0x0000cdff,
mediumorchid: 0xba55d3ff,
mediumpurple: 0x9370dbff,
mediumseagreen: 0x3cb371ff,
mediumslateblue: 0x7b68eeff,
mediumspringgreen: 0x00fa9aff,
mediumturquoise: 0x48d1ccff,
mediumvioletred: 0xc71585ff,
midnightblue: 0x191970ff,
mintcream: 0xf5fffaff,
mistyrose: 0xffe4e1ff,
moccasin: 0xffe4b5ff,
navajowhite: 0xffdeadff,
navy: 0x000080ff,
oldlace: 0xfdf5e6ff,
olive: 0x808000ff,
olivedrab: 0x6b8e23ff,
orange: 0xffa500ff,
orangered: 0xff4500ff,
orchid: 0xda70d6ff,
palegoldenrod: 0xeee8aaff,
palegreen: 0x98fb98ff,
paleturquoise: 0xafeeeeff,
palevioletred: 0xdb7093ff,
papayawhip: 0xffefd5ff,
peachpuff: 0xffdab9ff,
peru: 0xcd853fff,
pink: 0xffc0cbff,
plum: 0xdda0ddff,
powderblue: 0xb0e0e6ff,
purple: 0x800080ff,
rebeccapurple: 0x663399ff,
red: 0xff0000ff,
rosybrown: 0xbc8f8fff,
royalblue: 0x4169e1ff,
saddlebrown: 0x8b4513ff,
salmon: 0xfa8072ff,
sandybrown: 0xf4a460ff,
seagreen: 0x2e8b57ff,
seashell: 0xfff5eeff,
sienna: 0xa0522dff,
silver: 0xc0c0c0ff,
skyblue: 0x87ceebff,
slateblue: 0x6a5acdff,
slategray: 0x708090ff,
slategrey: 0x708090ff,
snow: 0xfffafaff,
springgreen: 0x00ff7fff,
steelblue: 0x4682b4ff,
tan: 0xd2b48cff,
teal: 0x008080ff,
thistle: 0xd8bfd8ff,
tomato: 0xff6347ff,
turquoise: 0x40e0d0ff,
violet: 0xee82eeff,
wheat: 0xf5deb3ff,
white: 0xffffffff,
whitesmoke: 0xf5f5f5ff,
yellow: 0xffff00ff,
yellowgreen: 0x9acd32ff
});
// copied from react-native/Libraries/Components/View/ReactNativeStyleAttributes
export const ColorProperties = makeShareable(['backgroundColor', 'borderBottomColor', 'borderColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'borderStartColor', 'borderEndColor', 'borderBlockColor', 'borderBlockEndColor', 'borderBlockStartColor', 'color', 'shadowColor', 'textDecorationColor', 'tintColor', 'textShadowColor', 'overlayColor']);
function normalizeColor(color) {
'worklet';
if (typeof color === 'number') {
if (color >>> 0 === color && color >= 0 && color <= 0xffffffff) {
return color;
}
return null;
}
if (typeof color !== 'string') {
return null;
}
let match;
// Ordered based on occurrences on Facebook codebase
if (match = MATCHERS.hex6.exec(color)) {
return Number.parseInt(match[1] + 'ff', 16) >>> 0;
}
if (names[color] !== undefined) {
return names[color];
}
if (match = MATCHERS.rgb.exec(color)) {
return (
// b
(parse255(match[1]) << 24 |
// r
parse255(match[2]) << 16 |
// g
parse255(match[3]) << 8 | 0x000000ff) >>>
// a
0
);
}
if (match = MATCHERS.rgba.exec(color)) {
return (
// b
(parse255(match[1]) << 24 |
// r
parse255(match[2]) << 16 |
// g
parse255(match[3]) << 8 | parse1(match[4])) >>>
// a
0
);
}
if (match = MATCHERS.hex3.exec(color)) {
return Number.parseInt(match[1] + match[1] +
// r
match[2] + match[2] +
// g
match[3] + match[3] +
// b
'ff',
// a
16) >>> 0;
}
// https://drafts.csswg.org/css-color-4/#hex-notation
if (match = MATCHERS.hex8.exec(color)) {
return Number.parseInt(match[1], 16) >>> 0;
}
if (match = MATCHERS.hex4.exec(color)) {
return Number.parseInt(match[1] + match[1] +
// r
match[2] + match[2] +
// g
match[3] + match[3] +
// b
match[4] + match[4],
// a
16) >>> 0;
}
if (match = MATCHERS.hsl.exec(color)) {
return (hslToRgb(parse360(match[1]),
// h
parsePercentage(match[2]),
// s
parsePercentage(match[3]) // l
) | 0x000000ff) >>>
// a
0;
}
if (match = MATCHERS.hsla.exec(color)) {
return (hslToRgb(parse360(match[1]),
// h
parsePercentage(match[2]),
// s
parsePercentage(match[3]) // l
) | parse1(match[4])) >>>
// a
0;
}
return null;
}
export const opacity = c => {
'worklet';
return (c >> 24 & 255) / 255;
};
export const red = c => {
'worklet';
return c >> 16 & 255;
};
export const green = c => {
'worklet';
return c >> 8 & 255;
};
export const blue = c => {
'worklet';
return c & 255;
};
const IS_WEB = isWeb();
const IS_ANDROID = isAndroid();
export const rgbaColor = (r, g, b, alpha = 1) => {
'worklet';
if (IS_WEB || !_WORKLET) {
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
const c = Math.round(alpha * 255) * (1 << 24) + Math.round(r) * (1 << 16) + Math.round(g) * (1 << 8) + Math.round(b);
if (IS_ANDROID) {
// on Android color is represented as signed 32 bit int
return c < 1 << 31 >>> 0 ? c : c - 4294967296; // 4294967296 == Math.pow(2, 32);
}
return c;
};
/**
*
* @param r - red value (0-255)
* @param g - green value (0-255)
* @param b - blue value (0-255)
* @returns \{h: hue (0-1), s: saturation (0-1), v: value (0-1)\}
*/
export function RGBtoHSV(r, g, b) {
'worklet';
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const d = max - min;
const s = max === 0 ? 0 : d / max;
const v = max / 255;
let h = 0;
switch (max) {
case min:
break;
case r:
h = g - b + d * (g < b ? 6 : 0);
h /= 6 * d;
break;
case g:
h = b - r + d * 2;
h /= 6 * d;
break;
case b:
h = r - g + d * 4;
h /= 6 * d;
break;
}
return {
h,
s,
v
};
}
/**
*
* @param h - hue (0-1)
* @param s - saturation (0-1)
* @param v - value (0-1)
* @returns \{r: red (0-255), g: green (0-255), b: blue (0-255)\}
*/
function HSVtoRGB(h, s, v) {
'worklet';
let r, g, b;
const i = Math.floor(h * 6);
const f = h * 6 - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0:
[r, g, b] = [v, t, p];
break;
case 1:
[r, g, b] = [q, v, p];
break;
case 2:
[r, g, b] = [p, v, t];
break;
case 3:
[r, g, b] = [p, q, v];
break;
case 4:
[r, g, b] = [t, p, v];
break;
case 5:
[r, g, b] = [v, p, q];
break;
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}
export const hsvToColor = (h, s, v, a) => {
'worklet';
const {
r,
g,
b
} = HSVtoRGB(h, s, v);
return rgbaColor(r, g, b, a);
};
function processColorInitially(color) {
'worklet';
if (color === null || color === undefined || typeof color === 'number') {
return color;
}
let normalizedColor = normalizeColor(color);
if (normalizedColor === null || normalizedColor === undefined) {
return undefined;
}
if (typeof normalizedColor !== 'number') {
return null;
}
normalizedColor = (normalizedColor << 24 | normalizedColor >>> 8) >>> 0; // argb
return normalizedColor;
}
export function isColor(value) {
'worklet';
if (typeof value !== 'string') {
return false;
}
return processColorInitially(value) != null;
}
export function processColor(color) {
'worklet';
let normalizedColor = processColorInitially(color);
if (normalizedColor === null || normalizedColor === undefined) {
return undefined;
}
if (typeof normalizedColor !== 'number') {
return null;
}
if (IS_ANDROID) {
// Android use 32 bit *signed* integer to represent the color
// We utilize the fact that bitwise operations in JS also operates on
// signed 32 bit integers, so that we can use those to convert from
// *unsigned* to *signed* 32bit int that way.
normalizedColor = normalizedColor | 0x0;
}
return normalizedColor;
}
export function processColorsInProps(props) {
'worklet';
for (const key in props) {
if (ColorProperties.includes(key)) {
props[key] = processColor(props[key]);
}
}
}
export function convertToRGBA(color) {
'worklet';
const processedColor = processColorInitially(color); // argb;
const a = (processedColor >>> 24) / 255;
const r = (processedColor << 8 >>> 24) / 255;
const g = (processedColor << 16 >>> 24) / 255;
const b = (processedColor << 24 >>> 24) / 255;
return [r, g, b, a];
}
export function rgbaArrayToRGBAColor(RGBA) {
'worklet';
return `rgba(${Math.round(RGBA[0] * 255)}, ${Math.round(RGBA[1] * 255)}, ${Math.round(RGBA[2] * 255)}, ${RGBA[3]})`;
}
export function toLinearSpace(RGBA, gamma = 2.2) {
'worklet';
const res = [];
for (let i = 0; i < 3; ++i) {
res.push(Math.pow(RGBA[i], gamma));
}
res.push(RGBA[3]);
return res;
}
export function toGammaSpace(RGBA, gamma = 2.2) {
'worklet';
const res = [];
for (let i = 0; i < 3; ++i) {
res.push(Math.pow(RGBA[i], 1 / gamma));
}
res.push(RGBA[3]);
return res;
}
//# sourceMappingURL=Colors.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,321 @@
'use strict';
import { Bezier } from './Bezier';
/**
* The `Easing` module implements common easing functions. This module is used
* by [Animate.timing()](docs/animate.html#timing) to convey physically
* believable motion in animations.
*
* You can find a visualization of some common easing functions at
* http://easings.net/
*
* ### Predefined animations
*
* The `Easing` module provides several predefined animations through the
* following methods:
*
* - [`back`](docs/easing.html#back) provides a simple animation where the
* object goes slightly back before moving forward
* - [`bounce`](docs/easing.html#bounce) provides a bouncing animation
* - [`ease`](docs/easing.html#ease) provides a simple inertial animation
* - [`elastic`](docs/easing.html#elastic) provides a simple spring interaction
*
* ### Standard functions
*
* Three standard easing functions are provided:
*
* - [`linear`](docs/easing.html#linear)
* - [`quad`](docs/easing.html#quad)
* - [`cubic`](docs/easing.html#cubic)
*
* The [`poly`](docs/easing.html#poly) function can be used to implement
* quartic, quintic, and other higher power functions.
*
* ### Additional functions
*
* Additional mathematical functions are provided by the following methods:
*
* - [`bezier`](docs/easing.html#bezier) provides a cubic bezier curve
* - [`circle`](docs/easing.html#circle) provides a circular function
* - [`sin`](docs/easing.html#sin) provides a sinusoidal function
* - [`exp`](docs/easing.html#exp) provides an exponential function
*
* The following helpers are used to modify other easing functions.
*
* - [`in`](docs/easing.html#in) runs an easing function forwards
* - [`inOut`](docs/easing.html#inout) makes any easing function symmetrical
* - [`out`](docs/easing.html#out) runs an easing function backwards
*/
/**
* @deprecated Please use {@link EasingFunction} type instead.
*/
/**
* @deprecated Please use {@link EasingFunctionFactory} type instead.
*/
/**
* A linear function, `f(t) = t`. Position correlates to elapsed time one to
* one.
*
* http://cubic-bezier.com/#0,0,1,1
*/
function linear(t) {
'worklet';
return t;
}
/**
* A simple inertial interaction, similar to an object slowly accelerating to
* speed.
*
* http://cubic-bezier.com/#.42,0,1,1
*/
function ease(t) {
'worklet';
return Bezier(0.42, 0, 1, 1)(t);
}
/**
* A quadratic function, `f(t) = t * t`. Position equals the square of elapsed
* time.
*
* http://easings.net/#easeInQuad
*/
function quad(t) {
'worklet';
return t * t;
}
/**
* A cubic function, `f(t) = t * t * t`. Position equals the cube of elapsed
* time.
*
* http://easings.net/#easeInCubic
*/
function cubic(t) {
'worklet';
return t * t * t;
}
/**
* A power function. Position is equal to the Nth power of elapsed time.
*
* n = 4: http://easings.net/#easeInQuart
* n = 5: http://easings.net/#easeInQuint
*/
function poly(n) {
'worklet';
return t => {
'worklet';
return Math.pow(t, n);
};
}
/**
* A sinusoidal function.
*
* http://easings.net/#easeInSine
*/
function sin(t) {
'worklet';
return 1 - Math.cos(t * Math.PI / 2);
}
/**
* A circular function.
*
* http://easings.net/#easeInCirc
*/
function circle(t) {
'worklet';
return 1 - Math.sqrt(1 - t * t);
}
/**
* An exponential function.
*
* http://easings.net/#easeInExpo
*/
function exp(t) {
'worklet';
return Math.pow(2, 10 * (t - 1));
}
/**
* A simple elastic interaction, similar to a spring oscillating back and
* forth.
*
* Default bounciness is 1, which overshoots a little bit once. 0 bounciness
* doesn't overshoot at all, and bounciness of N \> 1 will overshoot about N
* times.
*
* http://easings.net/#easeInElastic
*/
function elastic(bounciness = 1) {
'worklet';
const p = bounciness * Math.PI;
return t => {
'worklet';
return 1 - Math.pow(Math.cos(t * Math.PI / 2), 3) * Math.cos(t * p);
};
}
/**
* Use with `Animated.parallel()` to create a simple effect where the object
* animates back slightly as the animation starts.
*
* Wolfram Plot:
*
* - http://tiny.cc/back_default (s = 1.70158, default)
*/
function back(s = 1.70158) {
'worklet';
return t => {
'worklet';
return t * t * ((s + 1) * t - s);
};
}
/**
* Provides a simple bouncing effect.
*
* http://easings.net/#easeInBounce
*/
function bounce(t) {
'worklet';
if (t < 1 / 2.75) {
return 7.5625 * t * t;
}
if (t < 2 / 2.75) {
const t2 = t - 1.5 / 2.75;
return 7.5625 * t2 * t2 + 0.75;
}
if (t < 2.5 / 2.75) {
const t2 = t - 2.25 / 2.75;
return 7.5625 * t2 * t2 + 0.9375;
}
const t2 = t - 2.625 / 2.75;
return 7.5625 * t2 * t2 + 0.984375;
}
/**
* Provides a cubic bezier curve, equivalent to CSS Transitions'
* `transition-timing-function`.
*
* A useful tool to visualize cubic bezier curves can be found at
* http://cubic-bezier.com/
*/
function bezier(x1, y1, x2, y2) {
'worklet';
return {
factory: () => {
'worklet';
return Bezier(x1, y1, x2, y2);
}
};
}
function bezierFn(x1, y1, x2, y2) {
'worklet';
return Bezier(x1, y1, x2, y2);
}
/**
* Runs an easing function forwards.
*/
function in_(easing) {
'worklet';
return easing;
}
/**
* Runs an easing function backwards.
*/
function out(easing) {
'worklet';
return t => {
'worklet';
return 1 - easing(1 - t);
};
}
/**
* Makes any easing function symmetrical. The easing function will run
* forwards for half of the duration, then backwards for the rest of the
* duration.
*/
function inOut(easing) {
'worklet';
return t => {
'worklet';
if (t < 0.5) {
return easing(t * 2) / 2;
}
return 1 - easing((1 - t) * 2) / 2;
};
}
/**
* The `steps` easing function jumps between discrete values at regular intervals,
* creating a stepped animation effect. The `n` parameter determines the number of
* steps in the animation, and the `roundToNextStep` parameter determines whether the animation
* should start at the beginning or end of each step.
*/
function steps(n = 10, roundToNextStep = true) {
'worklet';
return t => {
'worklet';
const value = Math.min(Math.max(t, 0), 1) * n;
if (roundToNextStep) {
return Math.ceil(value) / n;
}
return Math.floor(value) / n;
};
}
const EasingObject = {
linear,
ease,
quad,
cubic,
poly,
sin,
circle,
exp,
elastic,
back,
bounce,
bezier,
bezierFn,
steps,
in: in_,
out,
inOut
};
export const Easing = EasingObject;
//# sourceMappingURL=Easing.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,98 @@
'use strict';
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { checkCppVersion } from '../platform-specific/checkCppVersion';
import { jsVersion } from '../platform-specific/jsVersion';
import { getValueUnpackerCode } from '../valueUnpacker';
import { isFabric } from '../PlatformChecker';
import { getShadowNodeWrapperFromRef } from '../fabricUtils';
import ReanimatedModule from '../../specs/NativeReanimatedModule';
// this is the type of `__reanimatedModuleProxy` which is injected using JSI
function assertSingleReanimatedInstance() {
if (global._REANIMATED_VERSION_JS !== undefined && global._REANIMATED_VERSION_JS !== jsVersion) {
throw new Error(`[Reanimated] Another instance of Reanimated was detected.
See \`https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#another-instance-of-reanimated-was-detected\` for more details. Previous: ${global._REANIMATED_VERSION_JS}, current: ${jsVersion}.`);
}
}
export class NativeReanimated {
constructor() {
_defineProperty(this, "InnerNativeModule", void 0);
// These checks have to split since version checking depend on the execution order
if (__DEV__) {
assertSingleReanimatedInstance();
}
global._REANIMATED_VERSION_JS = jsVersion;
if (global.__reanimatedModuleProxy === undefined) {
const valueUnpackerCode = getValueUnpackerCode();
ReanimatedModule === null || ReanimatedModule === void 0 || ReanimatedModule.installTurboModule(valueUnpackerCode);
}
if (global.__reanimatedModuleProxy === undefined) {
throw new Error(`[Reanimated] Native part of Reanimated doesn't seem to be initialized.
See https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#native-part-of-reanimated-doesnt-seem-to-be-initialized for more details.`);
}
if (__DEV__) {
checkCppVersion();
}
this.InnerNativeModule = global.__reanimatedModuleProxy;
}
makeShareableClone(value, shouldPersistRemote, nativeStateSource) {
return this.InnerNativeModule.makeShareableClone(value, shouldPersistRemote, nativeStateSource);
}
scheduleOnUI(shareable) {
return this.InnerNativeModule.scheduleOnUI(shareable);
}
executeOnUIRuntimeSync(shareable) {
return this.InnerNativeModule.executeOnUIRuntimeSync(shareable);
}
createWorkletRuntime(name, initializer) {
return this.InnerNativeModule.createWorkletRuntime(name, initializer);
}
scheduleOnRuntime(workletRuntime, shareableWorklet) {
return this.InnerNativeModule.scheduleOnRuntime(workletRuntime, shareableWorklet);
}
registerSensor(sensorType, interval, iosReferenceFrame, handler) {
return this.InnerNativeModule.registerSensor(sensorType, interval, iosReferenceFrame, handler);
}
unregisterSensor(sensorId) {
return this.InnerNativeModule.unregisterSensor(sensorId);
}
registerEventHandler(eventHandler, eventName, emitterReactTag) {
return this.InnerNativeModule.registerEventHandler(eventHandler, eventName, emitterReactTag);
}
unregisterEventHandler(id) {
return this.InnerNativeModule.unregisterEventHandler(id);
}
getViewProp(viewTag, propName, component,
// required on Fabric
callback) {
let shadowNodeWrapper;
if (isFabric()) {
shadowNodeWrapper = getShadowNodeWrapperFromRef(component);
return this.InnerNativeModule.getViewProp(shadowNodeWrapper, propName, callback);
}
return this.InnerNativeModule.getViewProp(viewTag, propName, callback);
}
configureLayoutAnimationBatch(layoutAnimationsBatch) {
this.InnerNativeModule.configureLayoutAnimationBatch(layoutAnimationsBatch);
}
setShouldAnimateExitingForTag(viewTag, shouldAnimate) {
this.InnerNativeModule.setShouldAnimateExitingForTag(viewTag, shouldAnimate);
}
enableLayoutAnimations(flag) {
this.InnerNativeModule.enableLayoutAnimations(flag);
}
configureProps(uiProps, nativeProps) {
this.InnerNativeModule.configureProps(uiProps, nativeProps);
}
subscribeForKeyboardEvents(handler, isStatusBarTranslucent) {
return this.InnerNativeModule.subscribeForKeyboardEvents(handler, isStatusBarTranslucent);
}
unsubscribeFromKeyboardEvents(listenerId) {
this.InnerNativeModule.unsubscribeFromKeyboardEvents(listenerId);
}
}
//# sourceMappingURL=NativeReanimated.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
'use strict';
import reanimatedJS from '../js-reanimated';
import { shouldBeUseWeb } from '../PlatformChecker';
import { NativeReanimated } from './NativeReanimated';
export default shouldBeUseWeb() ? reanimatedJS : new NativeReanimated();
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["reanimatedJS","shouldBeUseWeb","NativeReanimated"],"sources":["index.ts"],"sourcesContent":["'use strict';\nimport reanimatedJS from '../js-reanimated';\nimport { shouldBeUseWeb } from '../PlatformChecker';\nimport { NativeReanimated } from './NativeReanimated';\n\nexport default shouldBeUseWeb() ? reanimatedJS : new NativeReanimated();\n"],"mappings":"AAAA,YAAY;;AACZ,OAAOA,YAAY,MAAM,kBAAkB;AAC3C,SAASC,cAAc,QAAQ,oBAAoB;AACnD,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,eAAeD,cAAc,CAAC,CAAC,GAAGD,YAAY,GAAG,IAAIE,gBAAgB,CAAC,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,5 @@
'use strict';
// this file was created to prevent NativeReanimated from being included in the web bundle
export { default } from '../js-reanimated';
//# sourceMappingURL=index.web.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["default"],"sources":["index.web.ts"],"sourcesContent":["'use strict';\n// this file was created to prevent NativeReanimated from being included in the web bundle\nexport { default } from '../js-reanimated';\n"],"mappings":"AAAA,YAAY;;AACZ;AACA,SAASA,OAAO,QAAQ,kBAAkB","ignoreList":[]}

View File

@@ -0,0 +1,43 @@
'use strict';
import { Platform } from 'react-native';
// This type is necessary since some libraries tend to do a lib check
// and this file causes type errors on `global` access.
export function isJest() {
return !!process.env.JEST_WORKER_ID;
}
// `isChromeDebugger` also returns true in Jest environment, so `isJest()` check should always be performed first
export function isChromeDebugger() {
return (!global.nativeCallSyncHook || !!global.__REMOTEDEV__) && !global.RN$Bridgeless;
}
export function isWeb() {
return Platform.OS === 'web';
}
export function isAndroid() {
return Platform.OS === 'android';
}
function isWindows() {
return Platform.OS === 'windows';
}
export function shouldBeUseWeb() {
return isJest() || isChromeDebugger() || isWeb() || isWindows();
}
export function isFabric() {
return !!global._IS_FABRIC;
}
export function isWindowAvailable() {
// the window object is unavailable when building the server portion of a site that uses SSG
// this function shouldn't be used to conditionally render components
// https://www.joshwcomeau.com/react/the-perils-of-rehydration/
// @ts-ignore Fallback if `window` is undefined.
return typeof window !== 'undefined';
}
export function isReducedMotion() {
return isWeb() ? isWindowAvailable() ?
// @ts-ignore Fallback if `window` is undefined.
!window.matchMedia('(prefers-reduced-motion: no-preference)').matches : false : !!global._REANIMATED_IS_REDUCED_MOTION;
}
//# sourceMappingURL=PlatformChecker.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Platform","isJest","process","env","JEST_WORKER_ID","isChromeDebugger","global","nativeCallSyncHook","__REMOTEDEV__","RN$Bridgeless","isWeb","OS","isAndroid","isWindows","shouldBeUseWeb","isFabric","_IS_FABRIC","isWindowAvailable","window","isReducedMotion","matchMedia","matches","_REANIMATED_IS_REDUCED_MOTION"],"sources":["PlatformChecker.ts"],"sourcesContent":["'use strict';\nimport { Platform } from 'react-native';\n\n// This type is necessary since some libraries tend to do a lib check\n// and this file causes type errors on `global` access.\ntype localGlobal = typeof global & Record<string, unknown>;\n\nexport function isJest(): boolean {\n return !!process.env.JEST_WORKER_ID;\n}\n\n// `isChromeDebugger` also returns true in Jest environment, so `isJest()` check should always be performed first\nexport function isChromeDebugger(): boolean {\n return (\n (!(global as localGlobal).nativeCallSyncHook ||\n !!(global as localGlobal).__REMOTEDEV__) &&\n !(global as localGlobal).RN$Bridgeless\n );\n}\n\nexport function isWeb(): boolean {\n return Platform.OS === 'web';\n}\n\nexport function isAndroid(): boolean {\n return Platform.OS === 'android';\n}\n\nfunction isWindows(): boolean {\n return Platform.OS === 'windows';\n}\n\nexport function shouldBeUseWeb() {\n return isJest() || isChromeDebugger() || isWeb() || isWindows();\n}\n\nexport function isFabric() {\n return !!(global as localGlobal)._IS_FABRIC;\n}\n\nexport function isWindowAvailable() {\n // the window object is unavailable when building the server portion of a site that uses SSG\n // this function shouldn't be used to conditionally render components\n // https://www.joshwcomeau.com/react/the-perils-of-rehydration/\n // @ts-ignore Fallback if `window` is undefined.\n return typeof window !== 'undefined';\n}\n\nexport function isReducedMotion() {\n return isWeb()\n ? isWindowAvailable()\n ? // @ts-ignore Fallback if `window` is undefined.\n !window.matchMedia('(prefers-reduced-motion: no-preference)').matches\n : false\n : !!(global as localGlobal)._REANIMATED_IS_REDUCED_MOTION;\n}\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,QAAQ,QAAQ,cAAc;;AAEvC;AACA;;AAGA,OAAO,SAASC,MAAMA,CAAA,EAAY;EAChC,OAAO,CAAC,CAACC,OAAO,CAACC,GAAG,CAACC,cAAc;AACrC;;AAEA;AACA,OAAO,SAASC,gBAAgBA,CAAA,EAAY;EAC1C,OACE,CAAC,CAAEC,MAAM,CAAiBC,kBAAkB,IAC1C,CAAC,CAAED,MAAM,CAAiBE,aAAa,KACzC,CAAEF,MAAM,CAAiBG,aAAa;AAE1C;AAEA,OAAO,SAASC,KAAKA,CAAA,EAAY;EAC/B,OAAOV,QAAQ,CAACW,EAAE,KAAK,KAAK;AAC9B;AAEA,OAAO,SAASC,SAASA,CAAA,EAAY;EACnC,OAAOZ,QAAQ,CAACW,EAAE,KAAK,SAAS;AAClC;AAEA,SAASE,SAASA,CAAA,EAAY;EAC5B,OAAOb,QAAQ,CAACW,EAAE,KAAK,SAAS;AAClC;AAEA,OAAO,SAASG,cAAcA,CAAA,EAAG;EAC/B,OAAOb,MAAM,CAAC,CAAC,IAAII,gBAAgB,CAAC,CAAC,IAAIK,KAAK,CAAC,CAAC,IAAIG,SAAS,CAAC,CAAC;AACjE;AAEA,OAAO,SAASE,QAAQA,CAAA,EAAG;EACzB,OAAO,CAAC,CAAET,MAAM,CAAiBU,UAAU;AAC7C;AAEA,OAAO,SAASC,iBAAiBA,CAAA,EAAG;EAClC;EACA;EACA;EACA;EACA,OAAO,OAAOC,MAAM,KAAK,WAAW;AACtC;AAEA,OAAO,SAASC,eAAeA,CAAA,EAAG;EAChC,OAAOT,KAAK,CAAC,CAAC,GACVO,iBAAiB,CAAC,CAAC;EACjB;EACA,CAACC,MAAM,CAACE,UAAU,CAAC,yCAAyC,CAAC,CAACC,OAAO,GACrE,KAAK,GACP,CAAC,CAAEf,MAAM,CAAiBgB,6BAA6B;AAC7D","ignoreList":[]}

View File

@@ -0,0 +1,15 @@
'use strict';
import { addWhitelistedNativeProps } from '../ConfigHelper';
// @ts-expect-error This overload is required by our API.
export function createAnimatedPropAdapter(adapter, nativeProps) {
const nativePropsToAdd = {};
nativeProps === null || nativeProps === void 0 || nativeProps.forEach(prop => {
nativePropsToAdd[prop] = true;
});
addWhitelistedNativeProps(nativePropsToAdd);
return adapter;
}
//# sourceMappingURL=PropAdapters.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["addWhitelistedNativeProps","createAnimatedPropAdapter","adapter","nativeProps","nativePropsToAdd","forEach","prop"],"sources":["PropAdapters.ts"],"sourcesContent":["'use strict';\nimport { addWhitelistedNativeProps } from '../ConfigHelper';\nimport type {\n AnimatedPropsAdapterFunction,\n AnimatedPropsAdapterWorklet,\n} from './commonTypes';\n\n// @ts-expect-error This overload is required by our API.\nexport function createAnimatedPropAdapter(\n adapter: AnimatedPropsAdapterFunction,\n nativeProps?: string[]\n): AnimatedPropsAdapterFunction;\n\nexport function createAnimatedPropAdapter(\n adapter: AnimatedPropsAdapterWorklet,\n nativeProps?: string[]\n): AnimatedPropsAdapterWorklet {\n const nativePropsToAdd: { [key: string]: boolean } = {};\n nativeProps?.forEach((prop) => {\n nativePropsToAdd[prop] = true;\n });\n addWhitelistedNativeProps(nativePropsToAdd);\n return adapter;\n}\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,yBAAyB,QAAQ,iBAAiB;;AAM3D;;AAMA,OAAO,SAASC,yBAAyBA,CACvCC,OAAoC,EACpCC,WAAsB,EACO;EAC7B,MAAMC,gBAA4C,GAAG,CAAC,CAAC;EACvDD,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAEE,OAAO,CAAEC,IAAI,IAAK;IAC7BF,gBAAgB,CAACE,IAAI,CAAC,GAAG,IAAI;EAC/B,CAAC,CAAC;EACFN,yBAAyB,CAACI,gBAAgB,CAAC;EAC3C,OAAOF,OAAO;AAChB","ignoreList":[]}

View File

@@ -0,0 +1,24 @@
'use strict';
import { isFabric } from './PlatformChecker';
import { runOnUI } from './threads';
let VIEW_TAGS = [];
export function removeFromPropsRegistry(viewTag) {
VIEW_TAGS.push(viewTag);
if (VIEW_TAGS.length === 1) {
queueMicrotask(flush);
}
}
function flush() {
if (__DEV__ && !isFabric()) {
throw new Error('[Reanimated] PropsRegistry is only available on Fabric.');
}
runOnUI(removeFromPropsRegistryOnUI)(VIEW_TAGS);
VIEW_TAGS = [];
}
function removeFromPropsRegistryOnUI(viewTags) {
'worklet';
global._removeFromPropsRegistry(viewTags);
}
//# sourceMappingURL=PropsRegistry.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["isFabric","runOnUI","VIEW_TAGS","removeFromPropsRegistry","viewTag","push","length","queueMicrotask","flush","__DEV__","Error","removeFromPropsRegistryOnUI","viewTags","global","_removeFromPropsRegistry"],"sources":["PropsRegistry.ts"],"sourcesContent":["'use strict';\nimport { isFabric } from './PlatformChecker';\nimport { runOnUI } from './threads';\n\nlet VIEW_TAGS: number[] = [];\n\nexport function removeFromPropsRegistry(viewTag: number) {\n VIEW_TAGS.push(viewTag);\n if (VIEW_TAGS.length === 1) {\n queueMicrotask(flush);\n }\n}\n\nfunction flush() {\n if (__DEV__ && !isFabric()) {\n throw new Error('[Reanimated] PropsRegistry is only available on Fabric.');\n }\n runOnUI(removeFromPropsRegistryOnUI)(VIEW_TAGS);\n VIEW_TAGS = [];\n}\n\nfunction removeFromPropsRegistryOnUI(viewTags: number[]) {\n 'worklet';\n global._removeFromPropsRegistry(viewTags);\n}\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,QAAQ,QAAQ,mBAAmB;AAC5C,SAASC,OAAO,QAAQ,WAAW;AAEnC,IAAIC,SAAmB,GAAG,EAAE;AAE5B,OAAO,SAASC,uBAAuBA,CAACC,OAAe,EAAE;EACvDF,SAAS,CAACG,IAAI,CAACD,OAAO,CAAC;EACvB,IAAIF,SAAS,CAACI,MAAM,KAAK,CAAC,EAAE;IAC1BC,cAAc,CAACC,KAAK,CAAC;EACvB;AACF;AAEA,SAASA,KAAKA,CAAA,EAAG;EACf,IAAIC,OAAO,IAAI,CAACT,QAAQ,CAAC,CAAC,EAAE;IAC1B,MAAM,IAAIU,KAAK,CAAC,yDAAyD,CAAC;EAC5E;EACAT,OAAO,CAACU,2BAA2B,CAAC,CAACT,SAAS,CAAC;EAC/CA,SAAS,GAAG,EAAE;AAChB;AAEA,SAASS,2BAA2BA,CAACC,QAAkB,EAAE;EACvD,SAAS;;EACTC,MAAM,CAACC,wBAAwB,CAACF,QAAQ,CAAC;AAC3C","ignoreList":[]}

View File

@@ -0,0 +1,63 @@
'use strict';
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import NativeReanimatedModule from './NativeReanimated';
import { SensorType } from './commonTypes';
import { makeMutable } from './mutables';
function initSensorData(sensorType) {
if (sensorType === SensorType.ROTATION) {
return makeMutable({
qw: 0,
qx: 0,
qy: 0,
qz: 0,
yaw: 0,
pitch: 0,
roll: 0,
interfaceOrientation: 0
});
} else {
return makeMutable({
x: 0,
y: 0,
z: 0,
interfaceOrientation: 0
});
}
}
export default class Sensor {
constructor(sensorType, config) {
_defineProperty(this, "listenersNumber", 0);
_defineProperty(this, "sensorId", null);
_defineProperty(this, "sensorType", void 0);
_defineProperty(this, "data", void 0);
_defineProperty(this, "config", void 0);
this.sensorType = sensorType;
this.config = config;
this.data = initSensorData(sensorType);
}
register(eventHandler) {
const config = this.config;
const sensorType = this.sensorType;
this.sensorId = NativeReanimatedModule.registerSensor(sensorType, config.interval === 'auto' ? -1 : config.interval, config.iosReferenceFrame, eventHandler);
return this.sensorId !== -1;
}
isRunning() {
return this.sensorId !== -1 && this.sensorId !== null;
}
isAvailable() {
return this.sensorId !== -1;
}
getSharedValue() {
return this.data;
}
unregister() {
if (this.sensorId !== null && this.sensorId !== -1) {
NativeReanimatedModule.unregisterSensor(this.sensorId);
}
this.sensorId = null;
}
}
//# sourceMappingURL=Sensor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_defineProperty","obj","key","value","_toPropertyKey","Object","defineProperty","enumerable","configurable","writable","t","i","_toPrimitive","r","e","Symbol","toPrimitive","call","TypeError","String","Number","NativeReanimatedModule","SensorType","makeMutable","initSensorData","sensorType","ROTATION","qw","qx","qy","qz","yaw","pitch","roll","interfaceOrientation","x","y","z","Sensor","constructor","config","data","register","eventHandler","sensorId","registerSensor","interval","iosReferenceFrame","isRunning","isAvailable","getSharedValue","unregister","unregisterSensor"],"sources":["Sensor.ts"],"sourcesContent":["'use strict';\nimport NativeReanimatedModule from './NativeReanimated';\nimport type {\n SensorConfig,\n SharedValue,\n Value3D,\n ValueRotation,\n ShareableRef,\n} from './commonTypes';\nimport { SensorType } from './commonTypes';\nimport { makeMutable } from './mutables';\n\nfunction initSensorData(\n sensorType: SensorType\n): SharedValue<Value3D | ValueRotation> {\n if (sensorType === SensorType.ROTATION) {\n return makeMutable<Value3D | ValueRotation>({\n qw: 0,\n qx: 0,\n qy: 0,\n qz: 0,\n yaw: 0,\n pitch: 0,\n roll: 0,\n interfaceOrientation: 0,\n });\n } else {\n return makeMutable<Value3D | ValueRotation>({\n x: 0,\n y: 0,\n z: 0,\n interfaceOrientation: 0,\n });\n }\n}\n\nexport default class Sensor {\n public listenersNumber = 0;\n private sensorId: number | null = null;\n private sensorType: SensorType;\n private data: SharedValue<Value3D | ValueRotation>;\n private config: SensorConfig;\n\n constructor(sensorType: SensorType, config: SensorConfig) {\n this.sensorType = sensorType;\n this.config = config;\n this.data = initSensorData(sensorType);\n }\n\n register(\n eventHandler: ShareableRef<(data: Value3D | ValueRotation) => void>\n ) {\n const config = this.config;\n const sensorType = this.sensorType;\n this.sensorId = NativeReanimatedModule.registerSensor(\n sensorType,\n config.interval === 'auto' ? -1 : config.interval,\n config.iosReferenceFrame,\n eventHandler\n );\n return this.sensorId !== -1;\n }\n\n isRunning() {\n return this.sensorId !== -1 && this.sensorId !== null;\n }\n\n isAvailable() {\n return this.sensorId !== -1;\n }\n\n getSharedValue() {\n return this.data;\n }\n\n unregister() {\n if (this.sensorId !== null && this.sensorId !== -1) {\n NativeReanimatedModule.unregisterSensor(this.sensorId);\n }\n this.sensorId = null;\n }\n}\n"],"mappings":"AAAA,YAAY;;AAAC,SAAAA,gBAAAC,GAAA,EAAAC,GAAA,EAAAC,KAAA,IAAAD,GAAA,GAAAE,cAAA,CAAAF,GAAA,OAAAA,GAAA,IAAAD,GAAA,IAAAI,MAAA,CAAAC,cAAA,CAAAL,GAAA,EAAAC,GAAA,IAAAC,KAAA,EAAAA,KAAA,EAAAI,UAAA,QAAAC,YAAA,QAAAC,QAAA,oBAAAR,GAAA,CAAAC,GAAA,IAAAC,KAAA,WAAAF,GAAA;AAAA,SAAAG,eAAAM,CAAA,QAAAC,CAAA,GAAAC,YAAA,CAAAF,CAAA,uCAAAC,CAAA,GAAAA,CAAA,GAAAA,CAAA;AAAA,SAAAC,aAAAF,CAAA,EAAAG,CAAA,2BAAAH,CAAA,KAAAA,CAAA,SAAAA,CAAA,MAAAI,CAAA,GAAAJ,CAAA,CAAAK,MAAA,CAAAC,WAAA,kBAAAF,CAAA,QAAAH,CAAA,GAAAG,CAAA,CAAAG,IAAA,CAAAP,CAAA,EAAAG,CAAA,uCAAAF,CAAA,SAAAA,CAAA,YAAAO,SAAA,yEAAAL,CAAA,GAAAM,MAAA,GAAAC,MAAA,EAAAV,CAAA;AACb,OAAOW,sBAAsB,MAAM,oBAAoB;AAQvD,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,WAAW,QAAQ,YAAY;AAExC,SAASC,cAAcA,CACrBC,UAAsB,EACgB;EACtC,IAAIA,UAAU,KAAKH,UAAU,CAACI,QAAQ,EAAE;IACtC,OAAOH,WAAW,CAA0B;MAC1CI,EAAE,EAAE,CAAC;MACLC,EAAE,EAAE,CAAC;MACLC,EAAE,EAAE,CAAC;MACLC,EAAE,EAAE,CAAC;MACLC,GAAG,EAAE,CAAC;MACNC,KAAK,EAAE,CAAC;MACRC,IAAI,EAAE,CAAC;MACPC,oBAAoB,EAAE;IACxB,CAAC,CAAC;EACJ,CAAC,MAAM;IACL,OAAOX,WAAW,CAA0B;MAC1CY,CAAC,EAAE,CAAC;MACJC,CAAC,EAAE,CAAC;MACJC,CAAC,EAAE,CAAC;MACJH,oBAAoB,EAAE;IACxB,CAAC,CAAC;EACJ;AACF;AAEA,eAAe,MAAMI,MAAM,CAAC;EAO1BC,WAAWA,CAACd,UAAsB,EAAEe,MAAoB,EAAE;IAAAxC,eAAA,0BANjC,CAAC;IAAAA,eAAA,mBACQ,IAAI;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAMpC,IAAI,CAACyB,UAAU,GAAGA,UAAU;IAC5B,IAAI,CAACe,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACC,IAAI,GAAGjB,cAAc,CAACC,UAAU,CAAC;EACxC;EAEAiB,QAAQA,CACNC,YAAmE,EACnE;IACA,MAAMH,MAAM,GAAG,IAAI,CAACA,MAAM;IAC1B,MAAMf,UAAU,GAAG,IAAI,CAACA,UAAU;IAClC,IAAI,CAACmB,QAAQ,GAAGvB,sBAAsB,CAACwB,cAAc,CACnDpB,UAAU,EACVe,MAAM,CAACM,QAAQ,KAAK,MAAM,GAAG,CAAC,CAAC,GAAGN,MAAM,CAACM,QAAQ,EACjDN,MAAM,CAACO,iBAAiB,EACxBJ,YACF,CAAC;IACD,OAAO,IAAI,CAACC,QAAQ,KAAK,CAAC,CAAC;EAC7B;EAEAI,SAASA,CAAA,EAAG;IACV,OAAO,IAAI,CAACJ,QAAQ,KAAK,CAAC,CAAC,IAAI,IAAI,CAACA,QAAQ,KAAK,IAAI;EACvD;EAEAK,WAAWA,CAAA,EAAG;IACZ,OAAO,IAAI,CAACL,QAAQ,KAAK,CAAC,CAAC;EAC7B;EAEAM,cAAcA,CAAA,EAAG;IACf,OAAO,IAAI,CAACT,IAAI;EAClB;EAEAU,UAAUA,CAAA,EAAG;IACX,IAAI,IAAI,CAACP,QAAQ,KAAK,IAAI,IAAI,IAAI,CAACA,QAAQ,KAAK,CAAC,CAAC,EAAE;MAClDvB,sBAAsB,CAAC+B,gBAAgB,CAAC,IAAI,CAACR,QAAQ,CAAC;IACxD;IACA,IAAI,CAACA,QAAQ,GAAG,IAAI;EACtB;AACF","ignoreList":[]}

View File

@@ -0,0 +1,47 @@
'use strict';
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import Sensor from './Sensor';
export class SensorContainer {
constructor() {
_defineProperty(this, "nativeSensors", new Map());
}
getSensorId(sensorType, config) {
return sensorType * 100 + config.iosReferenceFrame * 10 + Number(config.adjustToInterfaceOrientation);
}
initializeSensor(sensorType, config) {
const sensorId = this.getSensorId(sensorType, config);
if (!this.nativeSensors.has(sensorId)) {
const newSensor = new Sensor(sensorType, config);
this.nativeSensors.set(sensorId, newSensor);
}
const sensor = this.nativeSensors.get(sensorId);
return sensor.getSharedValue();
}
registerSensor(sensorType, config, handler) {
const sensorId = this.getSensorId(sensorType, config);
if (!this.nativeSensors.has(sensorId)) {
return -1;
}
const sensor = this.nativeSensors.get(sensorId);
if (sensor && sensor.isAvailable() && (sensor.isRunning() || sensor.register(handler))) {
sensor.listenersNumber++;
return sensorId;
}
return -1;
}
unregisterSensor(sensorId) {
if (this.nativeSensors.has(sensorId)) {
const sensor = this.nativeSensors.get(sensorId);
if (sensor && sensor.isRunning()) {
sensor.listenersNumber--;
if (sensor.listenersNumber === 0) {
sensor.unregister();
}
}
}
}
}
//# sourceMappingURL=SensorContainer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_defineProperty","obj","key","value","_toPropertyKey","Object","defineProperty","enumerable","configurable","writable","t","i","_toPrimitive","r","e","Symbol","toPrimitive","call","TypeError","String","Number","Sensor","SensorContainer","constructor","Map","getSensorId","sensorType","config","iosReferenceFrame","adjustToInterfaceOrientation","initializeSensor","sensorId","nativeSensors","has","newSensor","set","sensor","get","getSharedValue","registerSensor","handler","isAvailable","isRunning","register","listenersNumber","unregisterSensor","unregister"],"sources":["SensorContainer.ts"],"sourcesContent":["'use strict';\nimport type {\n SensorType,\n SensorConfig,\n Value3D,\n ValueRotation,\n ShareableRef,\n SharedValue,\n} from './commonTypes';\nimport Sensor from './Sensor';\n\nexport class SensorContainer {\n private nativeSensors: Map<number, Sensor> = new Map();\n\n getSensorId(sensorType: SensorType, config: SensorConfig) {\n return (\n sensorType * 100 +\n config.iosReferenceFrame * 10 +\n Number(config.adjustToInterfaceOrientation)\n );\n }\n\n initializeSensor(\n sensorType: SensorType,\n config: SensorConfig\n ): SharedValue<Value3D | ValueRotation> {\n const sensorId = this.getSensorId(sensorType, config);\n\n if (!this.nativeSensors.has(sensorId)) {\n const newSensor = new Sensor(sensorType, config);\n this.nativeSensors.set(sensorId, newSensor);\n }\n\n const sensor = this.nativeSensors.get(sensorId);\n return sensor!.getSharedValue();\n }\n\n registerSensor(\n sensorType: SensorType,\n config: SensorConfig,\n handler: ShareableRef<(data: Value3D | ValueRotation) => void>\n ): number {\n const sensorId = this.getSensorId(sensorType, config);\n\n if (!this.nativeSensors.has(sensorId)) {\n return -1;\n }\n\n const sensor = this.nativeSensors.get(sensorId);\n if (\n sensor &&\n sensor.isAvailable() &&\n (sensor.isRunning() || sensor.register(handler))\n ) {\n sensor.listenersNumber++;\n return sensorId;\n }\n return -1;\n }\n\n unregisterSensor(sensorId: number) {\n if (this.nativeSensors.has(sensorId)) {\n const sensor = this.nativeSensors.get(sensorId);\n if (sensor && sensor.isRunning()) {\n sensor.listenersNumber--;\n if (sensor.listenersNumber === 0) {\n sensor.unregister();\n }\n }\n }\n }\n}\n"],"mappings":"AAAA,YAAY;;AAAC,SAAAA,gBAAAC,GAAA,EAAAC,GAAA,EAAAC,KAAA,IAAAD,GAAA,GAAAE,cAAA,CAAAF,GAAA,OAAAA,GAAA,IAAAD,GAAA,IAAAI,MAAA,CAAAC,cAAA,CAAAL,GAAA,EAAAC,GAAA,IAAAC,KAAA,EAAAA,KAAA,EAAAI,UAAA,QAAAC,YAAA,QAAAC,QAAA,oBAAAR,GAAA,CAAAC,GAAA,IAAAC,KAAA,WAAAF,GAAA;AAAA,SAAAG,eAAAM,CAAA,QAAAC,CAAA,GAAAC,YAAA,CAAAF,CAAA,uCAAAC,CAAA,GAAAA,CAAA,GAAAA,CAAA;AAAA,SAAAC,aAAAF,CAAA,EAAAG,CAAA,2BAAAH,CAAA,KAAAA,CAAA,SAAAA,CAAA,MAAAI,CAAA,GAAAJ,CAAA,CAAAK,MAAA,CAAAC,WAAA,kBAAAF,CAAA,QAAAH,CAAA,GAAAG,CAAA,CAAAG,IAAA,CAAAP,CAAA,EAAAG,CAAA,uCAAAF,CAAA,SAAAA,CAAA,YAAAO,SAAA,yEAAAL,CAAA,GAAAM,MAAA,GAAAC,MAAA,EAAAV,CAAA;AASb,OAAOW,MAAM,MAAM,UAAU;AAE7B,OAAO,MAAMC,eAAe,CAAC;EAAAC,YAAA;IAAAvB,eAAA,wBACkB,IAAIwB,GAAG,CAAC,CAAC;EAAA;EAEtDC,WAAWA,CAACC,UAAsB,EAAEC,MAAoB,EAAE;IACxD,OACED,UAAU,GAAG,GAAG,GAChBC,MAAM,CAACC,iBAAiB,GAAG,EAAE,GAC7BR,MAAM,CAACO,MAAM,CAACE,4BAA4B,CAAC;EAE/C;EAEAC,gBAAgBA,CACdJ,UAAsB,EACtBC,MAAoB,EACkB;IACtC,MAAMI,QAAQ,GAAG,IAAI,CAACN,WAAW,CAACC,UAAU,EAAEC,MAAM,CAAC;IAErD,IAAI,CAAC,IAAI,CAACK,aAAa,CAACC,GAAG,CAACF,QAAQ,CAAC,EAAE;MACrC,MAAMG,SAAS,GAAG,IAAIb,MAAM,CAACK,UAAU,EAAEC,MAAM,CAAC;MAChD,IAAI,CAACK,aAAa,CAACG,GAAG,CAACJ,QAAQ,EAAEG,SAAS,CAAC;IAC7C;IAEA,MAAME,MAAM,GAAG,IAAI,CAACJ,aAAa,CAACK,GAAG,CAACN,QAAQ,CAAC;IAC/C,OAAOK,MAAM,CAAEE,cAAc,CAAC,CAAC;EACjC;EAEAC,cAAcA,CACZb,UAAsB,EACtBC,MAAoB,EACpBa,OAA8D,EACtD;IACR,MAAMT,QAAQ,GAAG,IAAI,CAACN,WAAW,CAACC,UAAU,EAAEC,MAAM,CAAC;IAErD,IAAI,CAAC,IAAI,CAACK,aAAa,CAACC,GAAG,CAACF,QAAQ,CAAC,EAAE;MACrC,OAAO,CAAC,CAAC;IACX;IAEA,MAAMK,MAAM,GAAG,IAAI,CAACJ,aAAa,CAACK,GAAG,CAACN,QAAQ,CAAC;IAC/C,IACEK,MAAM,IACNA,MAAM,CAACK,WAAW,CAAC,CAAC,KACnBL,MAAM,CAACM,SAAS,CAAC,CAAC,IAAIN,MAAM,CAACO,QAAQ,CAACH,OAAO,CAAC,CAAC,EAChD;MACAJ,MAAM,CAACQ,eAAe,EAAE;MACxB,OAAOb,QAAQ;IACjB;IACA,OAAO,CAAC,CAAC;EACX;EAEAc,gBAAgBA,CAACd,QAAgB,EAAE;IACjC,IAAI,IAAI,CAACC,aAAa,CAACC,GAAG,CAACF,QAAQ,CAAC,EAAE;MACpC,MAAMK,MAAM,GAAG,IAAI,CAACJ,aAAa,CAACK,GAAG,CAACN,QAAQ,CAAC;MAC/C,IAAIK,MAAM,IAAIA,MAAM,CAACM,SAAS,CAAC,CAAC,EAAE;QAChCN,MAAM,CAACQ,eAAe,EAAE;QACxB,IAAIR,MAAM,CAACQ,eAAe,KAAK,CAAC,EAAE;UAChCR,MAAM,CAACU,UAAU,CAAC,CAAC;QACrB;MACF;IACF;EACF;AACF","ignoreList":[]}

View File

@@ -0,0 +1,54 @@
'use strict';
import { shouldBeUseWeb } from './PlatformChecker';
import { configureLayoutAnimationBatch, makeShareableCloneRecursive } from './core';
function createUpdateManager() {
const animations = [];
// When a stack is rerendered we reconfigure all the shared elements.
// To do that we want them to appear in our batch in the correct order,
// so we defer some of the updates to appear at the end of the batch.
const deferredAnimations = [];
return {
update(batchItem, isUnmounting) {
if (isUnmounting) {
deferredAnimations.push(batchItem);
} else {
animations.push(batchItem);
}
if (animations.length + deferredAnimations.length === 1) {
setImmediate(this.flush);
}
},
flush() {
configureLayoutAnimationBatch(animations.concat(deferredAnimations));
animations.length = 0;
deferredAnimations.length = 0;
}
};
}
/**
* Lets you update the current configuration of the layout animation or shared element transition for a given component.
* Configurations are batched and applied at the end of the current execution block, right before sending the response back to native.
*
* @param viewTag - The tag of the component you'd like to configure.
* @param type - The type of the animation you'd like to configure - {@link LayoutAnimationType}.
* @param config - The animation configuration - {@link LayoutAnimationFunction}, {@link SharedTransitionAnimationsFunction}, {@link ProgressAnimationCallback} or {@link Keyframe}. Passing `undefined` will remove the animation.
* @param sharedTransitionTag - The tag of the shared element transition you'd like to configure. Passing `undefined` will remove the transition.
* @param isUnmounting - Determines whether the configuration should be included at the end of the batch, after all the non-deferred configurations (even those that were updated later). This is used to retain the correct ordering of shared elements. Defaults to `false`.
*/
export let updateLayoutAnimations;
if (shouldBeUseWeb()) {
updateLayoutAnimations = () => {
// no-op
};
} else {
const updateLayoutAnimationsManager = createUpdateManager();
updateLayoutAnimations = (viewTag, type, config, sharedTransitionTag, isUnmounting) => updateLayoutAnimationsManager.update({
viewTag,
type,
config: config ? makeShareableCloneRecursive(config) : undefined,
sharedTransitionTag
}, isUnmounting);
}
//# sourceMappingURL=UpdateLayoutAnimations.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["shouldBeUseWeb","configureLayoutAnimationBatch","makeShareableCloneRecursive","createUpdateManager","animations","deferredAnimations","update","batchItem","isUnmounting","push","length","setImmediate","flush","concat","updateLayoutAnimations","updateLayoutAnimationsManager","viewTag","type","config","sharedTransitionTag","undefined"],"sources":["UpdateLayoutAnimations.ts"],"sourcesContent":["'use strict';\nimport { shouldBeUseWeb } from './PlatformChecker';\nimport {\n configureLayoutAnimationBatch,\n makeShareableCloneRecursive,\n} from './core';\nimport type {\n LayoutAnimationFunction,\n LayoutAnimationType,\n} from './layoutReanimation';\nimport type {\n LayoutAnimationBatchItem,\n ProgressAnimationCallback,\n SharedTransitionAnimationsFunction,\n} from './layoutReanimation/animationBuilder/commonTypes';\n\nfunction createUpdateManager() {\n const animations: LayoutAnimationBatchItem[] = [];\n // When a stack is rerendered we reconfigure all the shared elements.\n // To do that we want them to appear in our batch in the correct order,\n // so we defer some of the updates to appear at the end of the batch.\n const deferredAnimations: LayoutAnimationBatchItem[] = [];\n\n return {\n update(batchItem: LayoutAnimationBatchItem, isUnmounting?: boolean) {\n if (isUnmounting) {\n deferredAnimations.push(batchItem);\n } else {\n animations.push(batchItem);\n }\n if (animations.length + deferredAnimations.length === 1) {\n setImmediate(this.flush);\n }\n },\n flush(this: void) {\n configureLayoutAnimationBatch(animations.concat(deferredAnimations));\n animations.length = 0;\n deferredAnimations.length = 0;\n },\n };\n}\n\n/**\n * Lets you update the current configuration of the layout animation or shared element transition for a given component.\n * Configurations are batched and applied at the end of the current execution block, right before sending the response back to native.\n *\n * @param viewTag - The tag of the component you'd like to configure.\n * @param type - The type of the animation you'd like to configure - {@link LayoutAnimationType}.\n * @param config - The animation configuration - {@link LayoutAnimationFunction}, {@link SharedTransitionAnimationsFunction}, {@link ProgressAnimationCallback} or {@link Keyframe}. Passing `undefined` will remove the animation.\n * @param sharedTransitionTag - The tag of the shared element transition you'd like to configure. Passing `undefined` will remove the transition.\n * @param isUnmounting - Determines whether the configuration should be included at the end of the batch, after all the non-deferred configurations (even those that were updated later). This is used to retain the correct ordering of shared elements. Defaults to `false`.\n */\nexport let updateLayoutAnimations: (\n viewTag: number,\n type: LayoutAnimationType,\n config?:\n | Keyframe\n | LayoutAnimationFunction\n | SharedTransitionAnimationsFunction\n | ProgressAnimationCallback,\n sharedTransitionTag?: string,\n isUnmounting?: boolean\n) => void;\n\nif (shouldBeUseWeb()) {\n updateLayoutAnimations = () => {\n // no-op\n };\n} else {\n const updateLayoutAnimationsManager = createUpdateManager();\n updateLayoutAnimations = (\n viewTag,\n type,\n config,\n sharedTransitionTag,\n isUnmounting\n ) =>\n updateLayoutAnimationsManager.update(\n {\n viewTag,\n type,\n config: config ? makeShareableCloneRecursive(config) : undefined,\n sharedTransitionTag,\n },\n isUnmounting\n );\n}\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,cAAc,QAAQ,mBAAmB;AAClD,SACEC,6BAA6B,EAC7BC,2BAA2B,QACtB,QAAQ;AAWf,SAASC,mBAAmBA,CAAA,EAAG;EAC7B,MAAMC,UAAsC,GAAG,EAAE;EACjD;EACA;EACA;EACA,MAAMC,kBAA8C,GAAG,EAAE;EAEzD,OAAO;IACLC,MAAMA,CAACC,SAAmC,EAAEC,YAAsB,EAAE;MAClE,IAAIA,YAAY,EAAE;QAChBH,kBAAkB,CAACI,IAAI,CAACF,SAAS,CAAC;MACpC,CAAC,MAAM;QACLH,UAAU,CAACK,IAAI,CAACF,SAAS,CAAC;MAC5B;MACA,IAAIH,UAAU,CAACM,MAAM,GAAGL,kBAAkB,CAACK,MAAM,KAAK,CAAC,EAAE;QACvDC,YAAY,CAAC,IAAI,CAACC,KAAK,CAAC;MAC1B;IACF,CAAC;IACDA,KAAKA,CAAA,EAAa;MAChBX,6BAA6B,CAACG,UAAU,CAACS,MAAM,CAACR,kBAAkB,CAAC,CAAC;MACpED,UAAU,CAACM,MAAM,GAAG,CAAC;MACrBL,kBAAkB,CAACK,MAAM,GAAG,CAAC;IAC/B;EACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,IAAII,sBAUF;AAET,IAAId,cAAc,CAAC,CAAC,EAAE;EACpBc,sBAAsB,GAAGA,CAAA,KAAM;IAC7B;EAAA,CACD;AACH,CAAC,MAAM;EACL,MAAMC,6BAA6B,GAAGZ,mBAAmB,CAAC,CAAC;EAC3DW,sBAAsB,GAAGA,CACvBE,OAAO,EACPC,IAAI,EACJC,MAAM,EACNC,mBAAmB,EACnBX,YAAY,KAEZO,6BAA6B,CAACT,MAAM,CAClC;IACEU,OAAO;IACPC,IAAI;IACJC,MAAM,EAAEA,MAAM,GAAGhB,2BAA2B,CAACgB,MAAM,CAAC,GAAGE,SAAS;IAChED;EACF,CAAC,EACDX,YACF,CAAC;AACL","ignoreList":[]}

View File

@@ -0,0 +1,106 @@
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */
'use strict';
import { processColorsInProps } from './Colors';
import { _updatePropsJS } from './js-reanimated';
import { isFabric, isJest, shouldBeUseWeb } from './PlatformChecker';
import { runOnUIImmediately } from './threads';
let updateProps;
if (shouldBeUseWeb()) {
updateProps = (_, updates, maybeViewRef, isAnimatedProps) => {
'worklet';
if (maybeViewRef) {
maybeViewRef.items.forEach((item, _index) => {
_updatePropsJS(updates, item, isAnimatedProps);
});
}
};
} else {
updateProps = (viewDescriptors, updates) => {
'worklet';
processColorsInProps(updates);
global.UpdatePropsManager.update(viewDescriptors, updates);
};
}
export const updatePropsJestWrapper = (viewDescriptors, updates, maybeViewRef, animatedStyle, adapters) => {
adapters.forEach(adapter => {
adapter(updates);
});
animatedStyle.current.value = {
...animatedStyle.current.value,
...updates
};
updateProps(viewDescriptors, updates, maybeViewRef);
};
export default updateProps;
const createUpdatePropsManager = isFabric() ? () => {
'worklet';
// Fabric
const operations = [];
return {
update(viewDescriptors, updates) {
viewDescriptors.value.forEach(viewDescriptor => {
operations.push({
shadowNodeWrapper: viewDescriptor.shadowNodeWrapper,
updates
});
if (operations.length === 1) {
queueMicrotask(this.flush);
}
});
},
flush() {
global._updatePropsFabric(operations);
operations.length = 0;
}
};
} : () => {
'worklet';
// Paper
const operations = [];
return {
update(viewDescriptors, updates) {
viewDescriptors.value.forEach(viewDescriptor => {
operations.push({
tag: viewDescriptor.tag,
name: viewDescriptor.name || 'RCTView',
updates
});
if (operations.length === 1) {
queueMicrotask(this.flush);
}
});
},
flush() {
global._updatePropsPaper(operations);
operations.length = 0;
}
};
};
if (shouldBeUseWeb()) {
const maybeThrowError = () => {
// Jest attempts to access a property of this object to check if it is a Jest mock
// so we can't throw an error in the getter.
if (!isJest()) {
throw new Error('[Reanimated] `UpdatePropsManager` is not available on non-native platform.');
}
};
global.UpdatePropsManager = new Proxy({}, {
get: maybeThrowError,
set: () => {
maybeThrowError();
return false;
}
});
} else {
runOnUIImmediately(() => {
'worklet';
global.UpdatePropsManager = createUpdatePropsManager();
})();
}
//# sourceMappingURL=UpdateProps.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,60 @@
'use strict';
import { useRef } from 'react';
import { makeMutable } from './core';
import { shouldBeUseWeb } from './PlatformChecker';
export function makeViewDescriptorsSet() {
const shareableViewDescriptors = makeMutable([]);
const data = {
shareableViewDescriptors,
add: item => {
shareableViewDescriptors.modify(descriptors => {
'worklet';
const index = descriptors.findIndex(descriptor => descriptor.tag === item.tag);
if (index !== -1) {
descriptors[index] = item;
} else {
descriptors.push(item);
}
return descriptors;
}, false);
},
remove: viewTag => {
shareableViewDescriptors.modify(descriptors => {
'worklet';
const index = descriptors.findIndex(descriptor => descriptor.tag === viewTag);
if (index !== -1) {
descriptors.splice(index, 1);
}
return descriptors;
}, false);
}
};
return data;
}
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
export const useViewRefSet = SHOULD_BE_USE_WEB ? useViewRefSetJS : useViewRefSetNative;
function useViewRefSetNative() {
// Stub native implementation.
return undefined;
}
function useViewRefSetJS() {
const ref = useRef(null);
if (ref.current === null) {
const data = {
items: new Set(),
add: item => {
if (data.items.has(item)) return;
data.items.add(item);
},
remove: item => {
data.items.delete(item);
}
};
ref.current = data;
}
return ref.current;
}
//# sourceMappingURL=ViewDescriptorsSet.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["useRef","makeMutable","shouldBeUseWeb","makeViewDescriptorsSet","shareableViewDescriptors","data","add","item","modify","descriptors","index","findIndex","descriptor","tag","push","remove","viewTag","splice","SHOULD_BE_USE_WEB","useViewRefSet","useViewRefSetJS","useViewRefSetNative","undefined","ref","current","items","Set","has","delete"],"sources":["ViewDescriptorsSet.ts"],"sourcesContent":["'use strict';\nimport { useRef } from 'react';\nimport { makeMutable } from './core';\nimport type { SharedValue } from './commonTypes';\nimport type { Descriptor } from './hook/commonTypes';\nimport { shouldBeUseWeb } from './PlatformChecker';\n\nexport interface ViewRefSet<T> {\n items: Set<T>;\n add: (item: T) => void;\n remove: (item: T) => void;\n}\n\nexport interface ViewDescriptorsSet {\n shareableViewDescriptors: SharedValue<Descriptor[]>;\n add: (item: Descriptor) => void;\n remove: (viewTag: number) => void;\n}\n\nexport function makeViewDescriptorsSet(): ViewDescriptorsSet {\n const shareableViewDescriptors = makeMutable<Descriptor[]>([]);\n const data: ViewDescriptorsSet = {\n shareableViewDescriptors,\n add: (item: Descriptor) => {\n shareableViewDescriptors.modify((descriptors) => {\n 'worklet';\n const index = descriptors.findIndex(\n (descriptor) => descriptor.tag === item.tag\n );\n if (index !== -1) {\n descriptors[index] = item;\n } else {\n descriptors.push(item);\n }\n return descriptors;\n }, false);\n },\n\n remove: (viewTag: number) => {\n shareableViewDescriptors.modify((descriptors) => {\n 'worklet';\n const index = descriptors.findIndex(\n (descriptor) => descriptor.tag === viewTag\n );\n if (index !== -1) {\n descriptors.splice(index, 1);\n }\n return descriptors;\n }, false);\n },\n };\n return data;\n}\n\nconst SHOULD_BE_USE_WEB = shouldBeUseWeb();\n\nexport const useViewRefSet = SHOULD_BE_USE_WEB\n ? useViewRefSetJS\n : useViewRefSetNative;\n\nfunction useViewRefSetNative() {\n // Stub native implementation.\n return undefined;\n}\n\nfunction useViewRefSetJS<T>(): ViewRefSet<T> {\n const ref = useRef<ViewRefSet<T> | null>(null);\n if (ref.current === null) {\n const data: ViewRefSet<T> = {\n items: new Set(),\n\n add: (item: T) => {\n if (data.items.has(item)) return;\n data.items.add(item);\n },\n\n remove: (item: T) => {\n data.items.delete(item);\n },\n };\n ref.current = data;\n }\n\n return ref.current;\n}\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,MAAM,QAAQ,OAAO;AAC9B,SAASC,WAAW,QAAQ,QAAQ;AAGpC,SAASC,cAAc,QAAQ,mBAAmB;AAclD,OAAO,SAASC,sBAAsBA,CAAA,EAAuB;EAC3D,MAAMC,wBAAwB,GAAGH,WAAW,CAAe,EAAE,CAAC;EAC9D,MAAMI,IAAwB,GAAG;IAC/BD,wBAAwB;IACxBE,GAAG,EAAGC,IAAgB,IAAK;MACzBH,wBAAwB,CAACI,MAAM,CAAEC,WAAW,IAAK;QAC/C,SAAS;;QACT,MAAMC,KAAK,GAAGD,WAAW,CAACE,SAAS,CAChCC,UAAU,IAAKA,UAAU,CAACC,GAAG,KAAKN,IAAI,CAACM,GAC1C,CAAC;QACD,IAAIH,KAAK,KAAK,CAAC,CAAC,EAAE;UAChBD,WAAW,CAACC,KAAK,CAAC,GAAGH,IAAI;QAC3B,CAAC,MAAM;UACLE,WAAW,CAACK,IAAI,CAACP,IAAI,CAAC;QACxB;QACA,OAAOE,WAAW;MACpB,CAAC,EAAE,KAAK,CAAC;IACX,CAAC;IAEDM,MAAM,EAAGC,OAAe,IAAK;MAC3BZ,wBAAwB,CAACI,MAAM,CAAEC,WAAW,IAAK;QAC/C,SAAS;;QACT,MAAMC,KAAK,GAAGD,WAAW,CAACE,SAAS,CAChCC,UAAU,IAAKA,UAAU,CAACC,GAAG,KAAKG,OACrC,CAAC;QACD,IAAIN,KAAK,KAAK,CAAC,CAAC,EAAE;UAChBD,WAAW,CAACQ,MAAM,CAACP,KAAK,EAAE,CAAC,CAAC;QAC9B;QACA,OAAOD,WAAW;MACpB,CAAC,EAAE,KAAK,CAAC;IACX;EACF,CAAC;EACD,OAAOJ,IAAI;AACb;AAEA,MAAMa,iBAAiB,GAAGhB,cAAc,CAAC,CAAC;AAE1C,OAAO,MAAMiB,aAAa,GAAGD,iBAAiB,GAC1CE,eAAe,GACfC,mBAAmB;AAEvB,SAASA,mBAAmBA,CAAA,EAAG;EAC7B;EACA,OAAOC,SAAS;AAClB;AAEA,SAASF,eAAeA,CAAA,EAAqB;EAC3C,MAAMG,GAAG,GAAGvB,MAAM,CAAuB,IAAI,CAAC;EAC9C,IAAIuB,GAAG,CAACC,OAAO,KAAK,IAAI,EAAE;IACxB,MAAMnB,IAAmB,GAAG;MAC1BoB,KAAK,EAAE,IAAIC,GAAG,CAAC,CAAC;MAEhBpB,GAAG,EAAGC,IAAO,IAAK;QAChB,IAAIF,IAAI,CAACoB,KAAK,CAACE,GAAG,CAACpB,IAAI,CAAC,EAAE;QAC1BF,IAAI,CAACoB,KAAK,CAACnB,GAAG,CAACC,IAAI,CAAC;MACtB,CAAC;MAEDQ,MAAM,EAAGR,IAAO,IAAK;QACnBF,IAAI,CAACoB,KAAK,CAACG,MAAM,CAACrB,IAAI,CAAC;MACzB;IACF,CAAC;IACDgB,GAAG,CAACC,OAAO,GAAGnB,IAAI;EACpB;EAEA,OAAOkB,GAAG,CAACC,OAAO;AACpB","ignoreList":[]}

View File

@@ -0,0 +1,104 @@
'use strict';
function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
import { registerEventHandler, unregisterEventHandler } from './core';
import { shouldBeUseWeb } from './PlatformChecker';
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
// In JS implementation (e.g. for web) we don't use Reanimated's
// event emitter, therefore we have to handle here
// the event that came from React Native and convert it.
function jsListener(eventName, handler) {
return evt => {
handler({
...evt.nativeEvent,
eventName
});
};
}
var _viewTags = /*#__PURE__*/new WeakMap();
var _registrations = /*#__PURE__*/new WeakMap();
class WorkletEventHandlerNative {
// keys are viewTags, values are arrays of registration ID's for each viewTag
constructor(worklet, eventNames) {
_defineProperty(this, "eventNames", void 0);
_defineProperty(this, "worklet", void 0);
_classPrivateFieldInitSpec(this, _viewTags, void 0);
_classPrivateFieldInitSpec(this, _registrations, void 0);
this.worklet = worklet;
this.eventNames = eventNames;
_classPrivateFieldSet(_viewTags, this, new Set());
_classPrivateFieldSet(_registrations, this, new Map());
}
updateEventHandler(newWorklet, newEvents) {
// Update worklet and event names
this.worklet = newWorklet;
this.eventNames = newEvents;
// Detach all events
_classPrivateFieldGet(_registrations, this).forEach(registrationIDs => {
registrationIDs.forEach(id => unregisterEventHandler(id));
// No need to remove registrationIDs from map, since it gets overwritten when attaching
});
// Attach new events with new worklet
Array.from(_classPrivateFieldGet(_viewTags, this)).forEach(tag => {
const newRegistrations = this.eventNames.map(eventName => registerEventHandler(this.worklet, eventName, tag));
_classPrivateFieldGet(_registrations, this).set(tag, newRegistrations);
});
}
registerForEvents(viewTag, fallbackEventName) {
_classPrivateFieldGet(_viewTags, this).add(viewTag);
const newRegistrations = this.eventNames.map(eventName => registerEventHandler(this.worklet, eventName, viewTag));
_classPrivateFieldGet(_registrations, this).set(viewTag, newRegistrations);
if (this.eventNames.length === 0 && fallbackEventName) {
const newRegistration = registerEventHandler(this.worklet, fallbackEventName, viewTag);
_classPrivateFieldGet(_registrations, this).set(viewTag, [newRegistration]);
}
}
unregisterFromEvents(viewTag) {
var _classPrivateFieldGet2;
_classPrivateFieldGet(_viewTags, this).delete(viewTag);
(_classPrivateFieldGet2 = _classPrivateFieldGet(_registrations, this).get(viewTag)) === null || _classPrivateFieldGet2 === void 0 || _classPrivateFieldGet2.forEach(id => {
unregisterEventHandler(id);
});
_classPrivateFieldGet(_registrations, this).delete(viewTag);
}
}
class WorkletEventHandlerWeb {
constructor(worklet, eventNames = []) {
_defineProperty(this, "eventNames", void 0);
_defineProperty(this, "listeners", void 0);
_defineProperty(this, "worklet", void 0);
this.worklet = worklet;
this.eventNames = eventNames;
this.listeners = {};
this.setupWebListeners();
}
setupWebListeners() {
this.listeners = {};
this.eventNames.forEach(eventName => {
this.listeners[eventName] = jsListener(eventName, this.worklet);
});
}
updateEventHandler(newWorklet, newEvents) {
// Update worklet and event names
this.worklet = newWorklet;
this.eventNames = newEvents;
this.setupWebListeners();
}
registerForEvents(_viewTag, _fallbackEventName) {
// noop
}
unregisterFromEvents(_viewTag) {
// noop
}
}
export const WorkletEventHandler = SHOULD_BE_USE_WEB ? WorkletEventHandlerWeb : WorkletEventHandlerNative;
//# sourceMappingURL=WorkletEventHandler.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,65 @@
'use strict';
import { defineAnimation, getReduceMotionForAnimation, recognizePrefixSuffix } from './util';
export const withClamp = function (config, _animationToClamp) {
'worklet';
return defineAnimation(_animationToClamp, () => {
'worklet';
const animationToClamp = typeof _animationToClamp === 'function' ? _animationToClamp() : _animationToClamp;
const strippedMin = config.min === undefined ? undefined : recognizePrefixSuffix(config.min).strippedValue;
const strippedMax = config.max === undefined ? undefined : recognizePrefixSuffix(config.max).strippedValue;
function clampOnFrame(animation, now) {
const finished = animationToClamp.onFrame(animationToClamp, now);
if (animationToClamp.current === undefined) {
console.warn("[Reanimated] Error inside 'withClamp' animation, the inner animation has invalid current value");
return true;
} else {
const {
prefix,
strippedValue,
suffix
} = recognizePrefixSuffix(animationToClamp.current);
let newValue;
if (strippedMax !== undefined && strippedMax < strippedValue) {
newValue = strippedMax;
} else if (strippedMin !== undefined && strippedMin > strippedValue) {
newValue = strippedMin;
} else {
newValue = strippedValue;
}
animation.current = typeof animationToClamp.current === 'number' ? newValue : `${prefix === undefined ? '' : prefix}${newValue}${suffix === undefined ? '' : suffix}`;
}
return finished;
}
function onStart(animation, value, now, previousAnimation) {
animation.current = value;
animation.previousAnimation = animationToClamp;
const animationBeforeClamped = previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.previousAnimation;
if (config.max !== undefined && config.min !== undefined && config.max < config.min) {
console.warn('[Reanimated] Wrong config was provided to withClamp. Min value is bigger than max');
}
animationToClamp.onStart(animationToClamp,
/** provide the current value of the previous animation of the clamped animation
so we can animate from the original "un-truncated" value
*/
(animationBeforeClamped === null || animationBeforeClamped === void 0 ? void 0 : animationBeforeClamped.current) || value, now, animationBeforeClamped);
}
const callback = finished => {
if (animationToClamp.callback) {
animationToClamp.callback(finished);
}
};
return {
isHigherOrder: true,
onFrame: clampOnFrame,
onStart,
current: animationToClamp.current,
callback,
previousAnimation: null,
reduceMotion: getReduceMotionForAnimation(config.reduceMotion)
};
});
};
//# sourceMappingURL=clamp.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
'use strict';
export {};
//# sourceMappingURL=commonTypes.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["commonTypes.ts"],"sourcesContent":["'use strict';\nimport type {\n StyleProps,\n AnimatableValue,\n AnimationObject,\n Animation,\n Timestamp,\n AnimationCallback,\n} from '../commonTypes';\nimport type { AnimatedStyle } from '../helperTypes';\n\nexport interface HigherOrderAnimation {\n isHigherOrder?: boolean;\n}\n\nexport type NextAnimation<T extends AnimationObject> = T | (() => T);\n\nexport interface ClampAnimation\n extends Animation<ClampAnimation>,\n HigherOrderAnimation {\n current: AnimatableValue;\n}\n\nexport interface DelayAnimation\n extends Animation<DelayAnimation>,\n HigherOrderAnimation {\n startTime: Timestamp;\n started: boolean;\n previousAnimation: DelayAnimation | null;\n current: AnimatableValue;\n}\n\nexport interface RepeatAnimation\n extends Animation<RepeatAnimation>,\n HigherOrderAnimation {\n reps: number;\n startValue: AnimatableValue;\n toValue?: AnimatableValue;\n previousAnimation?: RepeatAnimation;\n}\n\nexport interface SequenceAnimation\n extends Animation<SequenceAnimation>,\n HigherOrderAnimation {\n animationIndex: number;\n}\n\nexport interface StyleLayoutAnimation extends HigherOrderAnimation {\n current: StyleProps;\n styleAnimations: AnimatedStyle<any>;\n onFrame: (animation: StyleLayoutAnimation, timestamp: Timestamp) => boolean;\n onStart: (\n nextAnimation: StyleLayoutAnimation,\n current: AnimatedStyle<any>,\n timestamp: Timestamp,\n previousAnimation: StyleLayoutAnimation\n ) => void;\n callback?: AnimationCallback;\n}\n"],"mappings":"AAAA,YAAY;;AAAC","ignoreList":[]}

View File

@@ -0,0 +1,80 @@
'use strict';
import { defineAnimation, getReduceMotionForAnimation } from '../util';
import { rubberBandDecay } from './rubberBandDecay';
import { isValidRubberBandConfig } from './utils';
import { rigidDecay } from './rigidDecay';
// TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file.
function validateConfig(config) {
'worklet';
if (config.clamp) {
if (!Array.isArray(config.clamp)) {
throw new Error(`[Reanimated] \`config.clamp\` must be an array but is ${typeof config.clamp}.`);
}
if (config.clamp.length !== 2) {
throw new Error(`[Reanimated] \`clamp array\` must contain 2 items but is given ${config.clamp.length}.`);
}
}
if (config.velocityFactor <= 0) {
throw new Error(`[Reanimated] \`config.velocityFactor\` must be greather then 0 but is ${config.velocityFactor}.`);
}
if (config.rubberBandEffect && !config.clamp) {
throw new Error('[Reanimated] You need to set `clamp` property when using `rubberBandEffect`.');
}
}
/**
* Lets you create animations that mimic objects in motion with friction.
*
* @param config - The decay animation configuration - {@link DecayConfig}.
* @param callback - A function called upon animation completion - {@link AnimationCallback}.
* @returns An [animation object](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animation-object) which holds the current state of the animation.
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withDecay
*/
export const withDecay = function (userConfig, callback) {
'worklet';
return defineAnimation(0, () => {
'worklet';
const config = {
deceleration: 0.998,
velocityFactor: 1,
velocity: 0,
rubberBandFactor: 0.6
};
if (userConfig) {
Object.keys(userConfig).forEach(key => config[key] = userConfig[key]);
}
const decay = isValidRubberBandConfig(config) ? (animation, now) => rubberBandDecay(animation, now, config) : (animation, now) => rigidDecay(animation, now, config);
function onStart(animation, value, now) {
animation.current = value;
animation.lastTimestamp = now;
animation.startTimestamp = now;
animation.initialVelocity = config.velocity;
validateConfig(config);
if (animation.reduceMotion && config.clamp) {
if (value < config.clamp[0]) {
animation.current = config.clamp[0];
} else if (value > config.clamp[1]) {
animation.current = config.clamp[1];
}
}
}
return {
onFrame: decay,
onStart,
callback,
velocity: config.velocity ?? 0,
initialVelocity: 0,
current: 0,
lastTimestamp: 0,
startTimestamp: 0,
reduceMotion: getReduceMotionForAnimation(config.reduceMotion)
};
});
};
//# sourceMappingURL=decay.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
'use strict';
export { withDecay } from './decay';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["withDecay"],"sources":["index.ts"],"sourcesContent":["'use strict';\nexport type { WithDecayConfig } from './decay';\nexport { withDecay } from './decay';\nexport type { DecayAnimation } from './utils';\n"],"mappings":"AAAA,YAAY;;AAEZ,SAASA,SAAS,QAAQ,SAAS","ignoreList":[]}

View File

@@ -0,0 +1,30 @@
'use strict';
import { SLOPE_FACTOR, VELOCITY_EPS } from './utils';
export function rigidDecay(animation, now, config) {
'worklet';
const {
lastTimestamp,
startTimestamp,
initialVelocity,
current,
velocity
} = animation;
const deltaTime = Math.min(now - lastTimestamp, 64);
const v = velocity * Math.exp(-(1 - config.deceleration) * (now - startTimestamp) * SLOPE_FACTOR);
animation.current = current + v * config.velocityFactor * deltaTime / 1000;
animation.velocity = v;
animation.lastTimestamp = now;
if (config.clamp) {
if (initialVelocity < 0 && animation.current <= config.clamp[0]) {
animation.current = config.clamp[0];
return true;
} else if (initialVelocity > 0 && animation.current >= config.clamp[1]) {
animation.current = config.clamp[1];
return true;
}
}
return Math.abs(v) < VELOCITY_EPS;
}
//# sourceMappingURL=rigidDecay.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["SLOPE_FACTOR","VELOCITY_EPS","rigidDecay","animation","now","config","lastTimestamp","startTimestamp","initialVelocity","current","velocity","deltaTime","Math","min","v","exp","deceleration","velocityFactor","clamp","abs"],"sources":["rigidDecay.ts"],"sourcesContent":["'use strict';\nimport { SLOPE_FACTOR, VELOCITY_EPS } from './utils';\nimport type { DefaultDecayConfig, InnerDecayAnimation } from './utils';\n\nexport function rigidDecay(\n animation: InnerDecayAnimation,\n now: number,\n config: DefaultDecayConfig\n): boolean {\n 'worklet';\n const { lastTimestamp, startTimestamp, initialVelocity, current, velocity } =\n animation;\n\n const deltaTime = Math.min(now - lastTimestamp, 64);\n const v =\n velocity *\n Math.exp(\n -(1 - config.deceleration) * (now - startTimestamp) * SLOPE_FACTOR\n );\n animation.current = current + (v * config.velocityFactor * deltaTime) / 1000;\n animation.velocity = v;\n animation.lastTimestamp = now;\n\n if (config.clamp) {\n if (initialVelocity < 0 && animation.current <= config.clamp[0]) {\n animation.current = config.clamp[0];\n return true;\n } else if (initialVelocity > 0 && animation.current >= config.clamp[1]) {\n animation.current = config.clamp[1];\n return true;\n }\n }\n return Math.abs(v) < VELOCITY_EPS;\n}\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,YAAY,EAAEC,YAAY,QAAQ,SAAS;AAGpD,OAAO,SAASC,UAAUA,CACxBC,SAA8B,EAC9BC,GAAW,EACXC,MAA0B,EACjB;EACT,SAAS;;EACT,MAAM;IAAEC,aAAa;IAAEC,cAAc;IAAEC,eAAe;IAAEC,OAAO;IAAEC;EAAS,CAAC,GACzEP,SAAS;EAEX,MAAMQ,SAAS,GAAGC,IAAI,CAACC,GAAG,CAACT,GAAG,GAAGE,aAAa,EAAE,EAAE,CAAC;EACnD,MAAMQ,CAAC,GACLJ,QAAQ,GACRE,IAAI,CAACG,GAAG,CACN,EAAE,CAAC,GAAGV,MAAM,CAACW,YAAY,CAAC,IAAIZ,GAAG,GAAGG,cAAc,CAAC,GAAGP,YACxD,CAAC;EACHG,SAAS,CAACM,OAAO,GAAGA,OAAO,GAAIK,CAAC,GAAGT,MAAM,CAACY,cAAc,GAAGN,SAAS,GAAI,IAAI;EAC5ER,SAAS,CAACO,QAAQ,GAAGI,CAAC;EACtBX,SAAS,CAACG,aAAa,GAAGF,GAAG;EAE7B,IAAIC,MAAM,CAACa,KAAK,EAAE;IAChB,IAAIV,eAAe,GAAG,CAAC,IAAIL,SAAS,CAACM,OAAO,IAAIJ,MAAM,CAACa,KAAK,CAAC,CAAC,CAAC,EAAE;MAC/Df,SAAS,CAACM,OAAO,GAAGJ,MAAM,CAACa,KAAK,CAAC,CAAC,CAAC;MACnC,OAAO,IAAI;IACb,CAAC,MAAM,IAAIV,eAAe,GAAG,CAAC,IAAIL,SAAS,CAACM,OAAO,IAAIJ,MAAM,CAACa,KAAK,CAAC,CAAC,CAAC,EAAE;MACtEf,SAAS,CAACM,OAAO,GAAGJ,MAAM,CAACa,KAAK,CAAC,CAAC,CAAC;MACnC,OAAO,IAAI;IACb;EACF;EACA,OAAON,IAAI,CAACO,GAAG,CAACL,CAAC,CAAC,GAAGb,YAAY;AACnC","ignoreList":[]}

View File

@@ -0,0 +1,34 @@
'use strict';
import { SLOPE_FACTOR, VELOCITY_EPS } from './utils';
const DERIVATIVE_EPS = 0.1;
export function rubberBandDecay(animation, now, config) {
'worklet';
const {
lastTimestamp,
startTimestamp,
current,
velocity
} = animation;
const deltaTime = Math.min(now - lastTimestamp, 64);
const clampIndex = Math.abs(current - config.clamp[0]) < Math.abs(current - config.clamp[1]) ? 0 : 1;
let derivative = 0;
if (current < config.clamp[0] || current > config.clamp[1]) {
derivative = current - config.clamp[clampIndex];
}
const v = velocity * Math.exp(-(1 - config.deceleration) * (now - startTimestamp) * SLOPE_FACTOR) - derivative * config.rubberBandFactor;
if (Math.abs(derivative) > DERIVATIVE_EPS) {
animation.springActive = true;
} else if (animation.springActive) {
animation.current = config.clamp[clampIndex];
return true;
} else if (Math.abs(v) < VELOCITY_EPS) {
return true;
}
animation.current = current + v * config.velocityFactor * deltaTime / 1000;
animation.velocity = v;
animation.lastTimestamp = now;
return false;
}
//# sourceMappingURL=rubberBandDecay.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["SLOPE_FACTOR","VELOCITY_EPS","DERIVATIVE_EPS","rubberBandDecay","animation","now","config","lastTimestamp","startTimestamp","current","velocity","deltaTime","Math","min","clampIndex","abs","clamp","derivative","v","exp","deceleration","rubberBandFactor","springActive","velocityFactor"],"sources":["rubberBandDecay.ts"],"sourcesContent":["'use strict';\nimport type { RubberBandDecayConfig, InnerDecayAnimation } from './utils';\nimport { SLOPE_FACTOR, VELOCITY_EPS } from './utils';\n\nconst DERIVATIVE_EPS = 0.1;\n\nexport function rubberBandDecay(\n animation: InnerDecayAnimation,\n now: number,\n config: RubberBandDecayConfig\n): boolean {\n 'worklet';\n const { lastTimestamp, startTimestamp, current, velocity } = animation;\n\n const deltaTime = Math.min(now - lastTimestamp, 64);\n const clampIndex =\n Math.abs(current - config.clamp[0]) < Math.abs(current - config.clamp[1])\n ? 0\n : 1;\n\n let derivative = 0;\n if (current < config.clamp[0] || current > config.clamp[1]) {\n derivative = current - config.clamp[clampIndex];\n }\n\n const v =\n velocity *\n Math.exp(\n -(1 - config.deceleration) * (now - startTimestamp) * SLOPE_FACTOR\n ) -\n derivative * config.rubberBandFactor;\n\n if (Math.abs(derivative) > DERIVATIVE_EPS) {\n animation.springActive = true;\n } else if (animation.springActive) {\n animation.current = config.clamp[clampIndex];\n return true;\n } else if (Math.abs(v) < VELOCITY_EPS) {\n return true;\n }\n\n animation.current = current + (v * config.velocityFactor * deltaTime) / 1000;\n animation.velocity = v;\n animation.lastTimestamp = now;\n return false;\n}\n"],"mappings":"AAAA,YAAY;;AAEZ,SAASA,YAAY,EAAEC,YAAY,QAAQ,SAAS;AAEpD,MAAMC,cAAc,GAAG,GAAG;AAE1B,OAAO,SAASC,eAAeA,CAC7BC,SAA8B,EAC9BC,GAAW,EACXC,MAA6B,EACpB;EACT,SAAS;;EACT,MAAM;IAAEC,aAAa;IAAEC,cAAc;IAAEC,OAAO;IAAEC;EAAS,CAAC,GAAGN,SAAS;EAEtE,MAAMO,SAAS,GAAGC,IAAI,CAACC,GAAG,CAACR,GAAG,GAAGE,aAAa,EAAE,EAAE,CAAC;EACnD,MAAMO,UAAU,GACdF,IAAI,CAACG,GAAG,CAACN,OAAO,GAAGH,MAAM,CAACU,KAAK,CAAC,CAAC,CAAC,CAAC,GAAGJ,IAAI,CAACG,GAAG,CAACN,OAAO,GAAGH,MAAM,CAACU,KAAK,CAAC,CAAC,CAAC,CAAC,GACrE,CAAC,GACD,CAAC;EAEP,IAAIC,UAAU,GAAG,CAAC;EAClB,IAAIR,OAAO,GAAGH,MAAM,CAACU,KAAK,CAAC,CAAC,CAAC,IAAIP,OAAO,GAAGH,MAAM,CAACU,KAAK,CAAC,CAAC,CAAC,EAAE;IAC1DC,UAAU,GAAGR,OAAO,GAAGH,MAAM,CAACU,KAAK,CAACF,UAAU,CAAC;EACjD;EAEA,MAAMI,CAAC,GACLR,QAAQ,GACNE,IAAI,CAACO,GAAG,CACN,EAAE,CAAC,GAAGb,MAAM,CAACc,YAAY,CAAC,IAAIf,GAAG,GAAGG,cAAc,CAAC,GAAGR,YACxD,CAAC,GACHiB,UAAU,GAAGX,MAAM,CAACe,gBAAgB;EAEtC,IAAIT,IAAI,CAACG,GAAG,CAACE,UAAU,CAAC,GAAGf,cAAc,EAAE;IACzCE,SAAS,CAACkB,YAAY,GAAG,IAAI;EAC/B,CAAC,MAAM,IAAIlB,SAAS,CAACkB,YAAY,EAAE;IACjClB,SAAS,CAACK,OAAO,GAAGH,MAAM,CAACU,KAAK,CAACF,UAAU,CAAC;IAC5C,OAAO,IAAI;EACb,CAAC,MAAM,IAAIF,IAAI,CAACG,GAAG,CAACG,CAAC,CAAC,GAAGjB,YAAY,EAAE;IACrC,OAAO,IAAI;EACb;EAEAG,SAAS,CAACK,OAAO,GAAGA,OAAO,GAAIS,CAAC,GAAGZ,MAAM,CAACiB,cAAc,GAAGZ,SAAS,GAAI,IAAI;EAC5EP,SAAS,CAACM,QAAQ,GAAGQ,CAAC;EACtBd,SAAS,CAACG,aAAa,GAAGF,GAAG;EAC7B,OAAO,KAAK;AACd","ignoreList":[]}

View File

@@ -0,0 +1,28 @@
'use strict';
import { isWeb } from '../../PlatformChecker';
const IS_WEB = isWeb();
export const VELOCITY_EPS = IS_WEB ? 1 / 20 : 1;
export const SLOPE_FACTOR = 0.1;
/**
* The decay animation configuration.
*
* @param velocity - Initial velocity of the animation. Defaults to 0.
* @param deceleration - The rate at which the velocity decreases over time. Defaults to 0.998.
* @param clamp - Array of two numbers which restricts animation's range. Defaults to [].
* @param velocityFactor - Velocity multiplier. Defaults to 1.
* @param rubberBandEffect - Makes the animation bounce over the limit specified in `clamp`. Defaults to `false`.
* @param rubberBandFactor - Strength of the rubber band effect. Defaults to 0.6.
* @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withDecay#config
*/
// If user wants to use rubber band decay animation we have to make sure he has provided clamp
export function isValidRubberBandConfig(config) {
'worklet';
return !!config.rubberBandEffect && Array.isArray(config.clamp) && config.clamp.length === 2;
}
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["isWeb","IS_WEB","VELOCITY_EPS","SLOPE_FACTOR","isValidRubberBandConfig","config","rubberBandEffect","Array","isArray","clamp","length"],"sources":["utils.ts"],"sourcesContent":["'use strict';\nimport type {\n AnimatableValue,\n AnimationObject,\n Animation,\n ReduceMotion,\n Timestamp,\n RequiredKeys,\n} from '../../../reanimated2/commonTypes';\nimport { isWeb } from '../../PlatformChecker';\n\nconst IS_WEB = isWeb();\nexport const VELOCITY_EPS = IS_WEB ? 1 / 20 : 1;\nexport const SLOPE_FACTOR = 0.1;\n\nexport interface DecayAnimation extends Animation<DecayAnimation> {\n lastTimestamp: Timestamp;\n startTimestamp: Timestamp;\n initialVelocity: number;\n velocity: number;\n current: AnimatableValue;\n}\n\nexport interface InnerDecayAnimation\n extends Omit<DecayAnimation, 'current'>,\n AnimationObject {\n current: number;\n springActive?: boolean;\n}\n\n/**\n * The decay animation configuration.\n *\n * @param velocity - Initial velocity of the animation. Defaults to 0.\n * @param deceleration - The rate at which the velocity decreases over time. Defaults to 0.998.\n * @param clamp - Array of two numbers which restricts animation's range. Defaults to [].\n * @param velocityFactor - Velocity multiplier. Defaults to 1.\n * @param rubberBandEffect - Makes the animation bounce over the limit specified in `clamp`. Defaults to `false`.\n * @param rubberBandFactor - Strength of the rubber band effect. Defaults to 0.6.\n * @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.\n * @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withDecay#config\n */\nexport type DecayConfig = {\n deceleration?: number;\n velocityFactor?: number;\n velocity?: number;\n reduceMotion?: ReduceMotion;\n} & (\n | {\n rubberBandEffect?: false;\n clamp?: [min: number, max: number];\n }\n | {\n rubberBandEffect: true;\n clamp: [min: number, max: number];\n rubberBandFactor?: number;\n }\n);\n\nexport type DefaultDecayConfig = RequiredKeys<\n DecayConfig,\n 'deceleration' | 'velocityFactor' | 'velocity'\n> & { rubberBandFactor: number };\n\n// If user wants to use rubber band decay animation we have to make sure he has provided clamp\nexport type RubberBandDecayConfig = RequiredKeys<\n DefaultDecayConfig,\n 'clamp'\n> & { rubberBandEffect: true };\n\nexport function isValidRubberBandConfig(\n config: DefaultDecayConfig\n): config is RubberBandDecayConfig {\n 'worklet';\n return (\n !!config.rubberBandEffect &&\n Array.isArray(config.clamp) &&\n config.clamp.length === 2\n );\n}\n"],"mappings":"AAAA,YAAY;;AASZ,SAASA,KAAK,QAAQ,uBAAuB;AAE7C,MAAMC,MAAM,GAAGD,KAAK,CAAC,CAAC;AACtB,OAAO,MAAME,YAAY,GAAGD,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC;AAC/C,OAAO,MAAME,YAAY,GAAG,GAAG;;AAiB/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAuBA;;AAMA,OAAO,SAASC,uBAAuBA,CACrCC,MAA0B,EACO;EACjC,SAAS;;EACT,OACE,CAAC,CAACA,MAAM,CAACC,gBAAgB,IACzBC,KAAK,CAACC,OAAO,CAACH,MAAM,CAACI,KAAK,CAAC,IAC3BJ,MAAM,CAACI,KAAK,CAACC,MAAM,KAAK,CAAC;AAE7B","ignoreList":[]}

View File

@@ -0,0 +1,82 @@
'use strict';
import { defineAnimation, getReduceMotionForAnimation } from './util';
// TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file.
/**
* An animation modifier that lets you start an animation with a delay.
*
* @param delayMs - Duration (in milliseconds) before the animation starts.
* @param nextAnimation - The animation to delay.
* @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.
* @returns An [animation object](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animation-object) which holds the current state of the animation.
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withDelay
*/
export const withDelay = function (delayMs, _nextAnimation, reduceMotion) {
'worklet';
return defineAnimation(_nextAnimation, () => {
'worklet';
const nextAnimation = typeof _nextAnimation === 'function' ? _nextAnimation() : _nextAnimation;
function delay(animation, now) {
const {
startTime,
started,
previousAnimation
} = animation;
const current = animation.current;
if (now - startTime > delayMs || animation.reduceMotion) {
if (!started) {
nextAnimation.onStart(nextAnimation, current, now, previousAnimation);
animation.previousAnimation = null;
animation.started = true;
}
const finished = nextAnimation.onFrame(nextAnimation, now);
animation.current = nextAnimation.current;
return finished;
} else if (previousAnimation) {
const finished = previousAnimation.finished || previousAnimation.onFrame(previousAnimation, now);
animation.current = previousAnimation.current;
if (finished) {
animation.previousAnimation = null;
}
}
return false;
}
function onStart(animation, value, now, previousAnimation) {
animation.startTime = now;
animation.started = false;
animation.current = value;
if (previousAnimation === animation) {
animation.previousAnimation = previousAnimation.previousAnimation;
} else {
animation.previousAnimation = previousAnimation;
}
// child animations inherit the setting, unless they already have it defined
// they will have it defined only if the user used the `reduceMotion` prop
if (nextAnimation.reduceMotion === undefined) {
nextAnimation.reduceMotion = animation.reduceMotion;
}
}
const callback = finished => {
if (nextAnimation.callback) {
nextAnimation.callback(finished);
}
};
return {
isHigherOrder: true,
onFrame: delay,
onStart,
current: nextAnimation.current,
callback,
previousAnimation: null,
startTime: 0,
started: false,
reduceMotion: getReduceMotionForAnimation(reduceMotion)
};
});
};
//# sourceMappingURL=delay.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
'use strict';
export { cancelAnimation, defineAnimation, initialUpdaterRun } from './util';
export { withTiming } from './timing';
export { withSpring } from './spring';
export { withDecay } from './decay';
export { withClamp } from './clamp';
export { withDelay } from './delay';
export { withRepeat } from './repeat';
export { withSequence } from './sequence';
export { withStyleAnimation } from './styleAnimation';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["cancelAnimation","defineAnimation","initialUpdaterRun","withTiming","withSpring","withDecay","withClamp","withDelay","withRepeat","withSequence","withStyleAnimation"],"sources":["index.ts"],"sourcesContent":["'use strict';\nexport type {\n HigherOrderAnimation,\n NextAnimation,\n DelayAnimation,\n RepeatAnimation,\n SequenceAnimation,\n StyleLayoutAnimation,\n} from './commonTypes';\nexport { cancelAnimation, defineAnimation, initialUpdaterRun } from './util';\nexport { withTiming } from './timing';\nexport type { TimingAnimation, WithTimingConfig } from './timing';\nexport { withSpring } from './spring';\nexport type { SpringAnimation, WithSpringConfig } from './springUtils';\nexport { withDecay } from './decay';\nexport type { DecayAnimation, WithDecayConfig } from './decay';\nexport { withClamp } from './clamp';\nexport { withDelay } from './delay';\nexport { withRepeat } from './repeat';\nexport { withSequence } from './sequence';\nexport { withStyleAnimation } from './styleAnimation';\n"],"mappings":"AAAA,YAAY;;AASZ,SAASA,eAAe,EAAEC,eAAe,EAAEC,iBAAiB,QAAQ,QAAQ;AAC5E,SAASC,UAAU,QAAQ,UAAU;AAErC,SAASC,UAAU,QAAQ,UAAU;AAErC,SAASC,SAAS,QAAQ,SAAS;AAEnC,SAASC,SAAS,QAAQ,SAAS;AACnC,SAASC,SAAS,QAAQ,SAAS;AACnC,SAASC,UAAU,QAAQ,UAAU;AACrC,SAASC,YAAY,QAAQ,YAAY;AACzC,SAASC,kBAAkB,QAAQ,kBAAkB","ignoreList":[]}

View File

@@ -0,0 +1,88 @@
'use strict';
import { defineAnimation, getReduceMotionForAnimation } from './util';
// TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file.
/**
* Lets you repeat an animation given number of times or run it indefinitely.
*
* @param animation - An animation object you want to repeat.
* @param numberOfReps - The number of times the animation is going to be repeated. Defaults to 2.
* @param reverse - Whether the animation should run in reverse every other repetition. Defaults to false.
* @param callback - A function called on animation complete.
* @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.
* @returns An [animation object](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animation-object) which holds the current state of the animation.
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withRepeat
*/
export const withRepeat = function (_nextAnimation, numberOfReps = 2, reverse = false, callback, reduceMotion) {
'worklet';
return defineAnimation(_nextAnimation, () => {
'worklet';
const nextAnimation = typeof _nextAnimation === 'function' ? _nextAnimation() : _nextAnimation;
function repeat(animation, now) {
const finished = nextAnimation.onFrame(nextAnimation, now);
animation.current = nextAnimation.current;
if (finished) {
animation.reps += 1;
// call inner animation's callback on every repetition
// as the second argument the animation's current value is passed
if (nextAnimation.callback) {
nextAnimation.callback(true /* finished */, animation.current);
}
if (animation.reduceMotion || numberOfReps > 0 && animation.reps >= numberOfReps) {
return true;
}
const startValue = reverse ? nextAnimation.current : animation.startValue;
if (reverse) {
nextAnimation.toValue = animation.startValue;
animation.startValue = startValue;
}
nextAnimation.onStart(nextAnimation, startValue, now, nextAnimation.previousAnimation);
return false;
}
return false;
}
const repCallback = finished => {
if (callback) {
callback(finished);
}
// when cancelled call inner animation's callback
if (!finished && nextAnimation.callback) {
nextAnimation.callback(false /* finished */);
}
};
function onStart(animation, value, now, previousAnimation) {
animation.startValue = value;
animation.reps = 0;
// child animations inherit the setting, unless they already have it defined
// they will have it defined only if the user used the `reduceMotion` prop
if (nextAnimation.reduceMotion === undefined) {
nextAnimation.reduceMotion = animation.reduceMotion;
}
// don't start the animation if reduced motion is enabled and
// the animation would end at its starting point
if (animation.reduceMotion && reverse && (numberOfReps <= 0 || numberOfReps % 2 === 0)) {
animation.current = animation.startValue;
animation.onFrame = () => true;
} else {
nextAnimation.onStart(nextAnimation, value, now, previousAnimation);
}
}
return {
isHigherOrder: true,
onFrame: repeat,
onStart,
reps: 0,
current: nextAnimation.current,
callback: repCallback,
startValue: 0,
reduceMotion: getReduceMotionForAnimation(reduceMotion)
};
});
};
//# sourceMappingURL=repeat.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,117 @@
'use strict';
import { defineAnimation, getReduceMotionForAnimation } from './util';
/**
* Lets you run animations in a sequence.
*
* @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.
* @param animations - Any number of animation objects to be run in a sequence.
* @returns An [animation object](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animation-object) which holds the current state of the animation/
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withSequence
*/
export function withSequence(_reduceMotionOrFirstAnimation, ..._animations) {
'worklet';
let reduceMotion;
// the first argument is either a config or an animation
// this is done to allow the reduce motion config prop to be optional
if (_reduceMotionOrFirstAnimation) {
if (typeof _reduceMotionOrFirstAnimation === 'string') {
reduceMotion = _reduceMotionOrFirstAnimation;
} else {
_animations.unshift(_reduceMotionOrFirstAnimation);
}
}
if (_animations.length === 0) {
console.warn('[Reanimated] No animation was provided for the sequence');
return defineAnimation(0, () => {
'worklet';
return {
onStart: (animation, value) => animation.current = value,
onFrame: () => true,
current: 0,
animationIndex: 0,
reduceMotion: getReduceMotionForAnimation(reduceMotion)
};
});
}
return defineAnimation(_animations[0], () => {
'worklet';
const animations = _animations.map(a => {
const result = typeof a === 'function' ? a() : a;
result.finished = false;
return result;
});
function findNextNonReducedMotionAnimationIndex(index) {
// the last animation is returned even if reduced motion is enabled,
// because we want the sequence to finish at the right spot
while (index < animations.length - 1 && animations[index].reduceMotion) {
index++;
}
return index;
}
const callback = finished => {
if (finished) {
// we want to call the callback after every single animation
// not after all of them
return;
}
// this is going to be called only if sequence has been cancelled
animations.forEach(animation => {
if (typeof animation.callback === 'function' && !animation.finished) {
animation.callback(finished);
}
});
};
function sequence(animation, now) {
const currentAnim = animations[animation.animationIndex];
const finished = currentAnim.onFrame(currentAnim, now);
animation.current = currentAnim.current;
if (finished) {
// we want to call the callback after every single animation
if (currentAnim.callback) {
currentAnim.callback(true /* finished */);
}
currentAnim.finished = true;
animation.animationIndex = findNextNonReducedMotionAnimationIndex(animation.animationIndex + 1);
if (animation.animationIndex < animations.length) {
const nextAnim = animations[animation.animationIndex];
nextAnim.onStart(nextAnim, currentAnim.current, now, currentAnim);
return false;
}
return true;
}
return false;
}
function onStart(animation, value, now, previousAnimation) {
// child animations inherit the setting, unless they already have it defined
// they will have it defined only if the user used the `reduceMotion` prop
animations.forEach(anim => {
if (anim.reduceMotion === undefined) {
anim.reduceMotion = animation.reduceMotion;
}
});
animation.animationIndex = findNextNonReducedMotionAnimationIndex(0);
if (previousAnimation === undefined) {
previousAnimation = animations[animations.length - 1];
}
const currentAnimation = animations[animation.animationIndex];
currentAnimation.onStart(currentAnimation, value, now, previousAnimation);
}
return {
isHigherOrder: true,
onFrame: sequence,
onStart,
animationIndex: 0,
current: animations[0].current,
callback,
reduceMotion: getReduceMotionForAnimation(reduceMotion)
};
});
}
//# sourceMappingURL=sequence.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,174 @@
'use strict';
import { defineAnimation, getReduceMotionForAnimation } from './util';
import { initialCalculations, calculateNewMassToMatchDuration, underDampedSpringCalculations, criticallyDampedSpringCalculations, isAnimationTerminatingCalculation, scaleZetaToMatchClamps, checkIfConfigIsValid } from './springUtils';
// TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file.
/**
* Lets you create spring-based animations.
*
* @param toValue - the value at which the animation will come to rest - {@link AnimatableValue}
* @param config - the spring animation configuration - {@link SpringConfig}
* @param callback - a function called on animation complete - {@link AnimationCallback}
* @returns an [animation object](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animation-object) which holds the current state of the animation
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withSpring
*/
export const withSpring = (toValue, userConfig, callback) => {
'worklet';
return defineAnimation(toValue, () => {
'worklet';
const defaultConfig = {
damping: 10,
mass: 1,
stiffness: 100,
overshootClamping: false,
restDisplacementThreshold: 0.01,
restSpeedThreshold: 2,
velocity: 0,
duration: 2000,
dampingRatio: 0.5,
reduceMotion: undefined,
clamp: undefined
};
const config = {
...defaultConfig,
...userConfig,
useDuration: !!(userConfig !== null && userConfig !== void 0 && userConfig.duration || userConfig !== null && userConfig !== void 0 && userConfig.dampingRatio),
skipAnimation: false
};
config.skipAnimation = !checkIfConfigIsValid(config);
if (config.duration === 0) {
config.skipAnimation = true;
}
function springOnFrame(animation, now) {
// eslint-disable-next-line @typescript-eslint/no-shadow
const {
toValue,
startTimestamp,
current
} = animation;
const timeFromStart = now - startTimestamp;
if (config.useDuration && timeFromStart >= config.duration) {
animation.current = toValue;
// clear lastTimestamp to avoid using stale value by the next spring animation that starts after this one
animation.lastTimestamp = 0;
return true;
}
if (config.skipAnimation) {
animation.current = toValue;
animation.lastTimestamp = 0;
return true;
}
const {
lastTimestamp,
velocity
} = animation;
const deltaTime = Math.min(now - lastTimestamp, 64);
animation.lastTimestamp = now;
const t = deltaTime / 1000;
const v0 = -velocity;
const x0 = toValue - current;
const {
zeta,
omega0,
omega1
} = animation;
const {
position: newPosition,
velocity: newVelocity
} = zeta < 1 ? underDampedSpringCalculations(animation, {
zeta,
v0,
x0,
omega0,
omega1,
t
}) : criticallyDampedSpringCalculations(animation, {
v0,
x0,
omega0,
t
});
animation.current = newPosition;
animation.velocity = newVelocity;
const {
isOvershooting,
isVelocity,
isDisplacement
} = isAnimationTerminatingCalculation(animation, config);
const springIsNotInMove = isOvershooting || isVelocity && isDisplacement;
if (!config.useDuration && springIsNotInMove) {
animation.velocity = 0;
animation.current = toValue;
// clear lastTimestamp to avoid using stale value by the next spring animation that starts after this one
animation.lastTimestamp = 0;
return true;
}
return false;
}
function isTriggeredTwice(previousAnimation, animation) {
return (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.lastTimestamp) && (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.startTimestamp) && (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.toValue) === animation.toValue && (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.duration) === animation.duration && (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.dampingRatio) === animation.dampingRatio;
}
function onStart(animation, value, now, previousAnimation) {
animation.current = value;
animation.startValue = value;
let mass = config.mass;
const triggeredTwice = isTriggeredTwice(previousAnimation, animation);
const duration = config.duration;
const x0 = triggeredTwice ? // If animation is triggered twice we want to continue the previous animation
// form the previous starting point
previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.startValue : Number(animation.toValue) - value;
if (previousAnimation) {
animation.velocity = (triggeredTwice ? previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.velocity : (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.velocity) + config.velocity) || 0;
} else {
animation.velocity = config.velocity || 0;
}
if (triggeredTwice) {
animation.zeta = (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.zeta) || 0;
animation.omega0 = (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.omega0) || 0;
animation.omega1 = (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.omega1) || 0;
} else {
if (config.useDuration) {
const actualDuration = triggeredTwice ?
// If animation is triggered twice we want to continue the previous animation
// so we need to include the time that already elapsed
duration - (((previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.lastTimestamp) || 0) - ((previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.startTimestamp) || 0)) : duration;
config.duration = actualDuration;
mass = calculateNewMassToMatchDuration(x0, config, animation.velocity);
}
const {
zeta,
omega0,
omega1
} = initialCalculations(mass, config);
animation.zeta = zeta;
animation.omega0 = omega0;
animation.omega1 = omega1;
if (config.clamp !== undefined) {
animation.zeta = scaleZetaToMatchClamps(animation, config.clamp);
}
}
animation.lastTimestamp = (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.lastTimestamp) || now;
animation.startTimestamp = triggeredTwice ? (previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.startTimestamp) || now : now;
}
return {
onFrame: springOnFrame,
onStart,
toValue,
velocity: config.velocity || 0,
current: toValue,
startValue: 0,
callback,
lastTimestamp: 0,
startTimestamp: 0,
zeta: 0,
omega0: 0,
omega1: 0,
reduceMotion: getReduceMotionForAnimation(config.reduceMotion)
};
});
};
//# sourceMappingURL=spring.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,270 @@
'use strict';
/**
* Spring animation configuration.
*
* @param mass - The weight of the spring. Reducing this value makes the animation faster. Defaults to 1.
* @param damping - How quickly a spring slows down. Higher damping means the spring will come to rest faster. Defaults to 10.
* @param duration - Length of the animation (in milliseconds). Defaults to 2000.
* @param dampingRatio - How damped the spring is. Value 1 means the spring is critically damped, and value \>1 means the spring is overdamped. Defaults to 0.5.
* @param stiffness - How bouncy the spring is. Defaults to 100.
* @param velocity - Initial velocity applied to the spring equation. Defaults to 0.
* @param overshootClamping - Whether a spring can bounce over the `toValue`. Defaults to false.
* @param restDisplacementThreshold - The displacement below which the spring will snap to toValue without further oscillations. Defaults to 0.01.
* @param restSpeedThreshold - The speed in pixels per second from which the spring will snap to toValue without further oscillations. Defaults to 2.
* @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withSpring/#config-
*/
// This type contains all the properties from SpringConfig, which are changed to be required,
// except for optional 'reduceMotion' and 'clamp'
export function checkIfConfigIsValid(config) {
'worklet';
var _config$clamp, _config$clamp2;
let errorMessage = '';
['stiffness', 'damping', 'dampingRatio', 'restDisplacementThreshold', 'restSpeedThreshold', 'mass'].forEach(prop => {
const value = config[prop];
if (value <= 0) {
errorMessage += `, ${prop} must be grater than zero but got ${value}`;
}
});
if (config.duration < 0) {
errorMessage += `, duration can't be negative, got ${config.duration}`;
}
if ((_config$clamp = config.clamp) !== null && _config$clamp !== void 0 && _config$clamp.min && (_config$clamp2 = config.clamp) !== null && _config$clamp2 !== void 0 && _config$clamp2.max && config.clamp.min > config.clamp.max) {
errorMessage += `, clamp.min should be lower than clamp.max, got clamp: {min: ${config.clamp.min}, max: ${config.clamp.max}} `;
}
if (errorMessage !== '') {
console.warn('[Reanimated] Invalid spring config' + errorMessage);
}
return errorMessage === '';
}
// ts-prune-ignore-next This function is exported to be tested
export function bisectRoot({
min,
max,
func,
maxIterations = 20
}) {
'worklet';
const ACCURACY = 0.00005;
let idx = maxIterations;
let current = (max + min) / 2;
while (Math.abs(func(current)) > ACCURACY && idx > 0) {
idx -= 1;
if (func(current) < 0) {
min = current;
} else {
max = current;
}
current = (min + max) / 2;
}
return current;
}
export function initialCalculations(mass = 0, config) {
'worklet';
if (config.skipAnimation) {
return {
zeta: 0,
omega0: 0,
omega1: 0
};
}
if (config.useDuration) {
const {
stiffness: k,
dampingRatio: zeta
} = config;
/** omega0 and omega1 denote angular frequency and natural angular frequency, see this link for formulas:
* https://courses.lumenlearning.com/suny-osuniversityphysics/chapter/15-5-damped-oscillations/
*/
const omega0 = Math.sqrt(k / mass);
const omega1 = omega0 * Math.sqrt(1 - zeta ** 2);
return {
zeta,
omega0,
omega1
};
} else {
const {
damping: c,
mass: m,
stiffness: k
} = config;
const zeta = c / (2 * Math.sqrt(k * m)); // damping ratio
const omega0 = Math.sqrt(k / m); // undamped angular frequency of the oscillator (rad/ms)
const omega1 = omega0 * Math.sqrt(1 - zeta ** 2); // exponential decay
return {
zeta,
omega0,
omega1
};
}
}
/** We make an assumption that we can manipulate zeta without changing duration of movement.
* According to theory this change is small and tests shows that we can indeed ignore it.
*/
export function scaleZetaToMatchClamps(animation, clamp) {
'worklet';
const {
zeta,
toValue,
startValue
} = animation;
const toValueNum = Number(toValue);
if (toValueNum === startValue) {
return zeta;
}
const [firstBound, secondBound] = toValueNum - startValue > 0 ? [clamp.min, clamp.max] : [clamp.max, clamp.min];
/** The extrema we get from equation below are relative (we obtain a ratio),
* To get absolute extrema we convert it as follows:
*
* AbsoluteExtremum = startValue ± RelativeExtremum * (toValue - startValue)
* Where ± denotes:
* + if extremum is over the target
* - otherwise
*/
const relativeExtremum1 = secondBound !== undefined ? Math.abs((secondBound - toValueNum) / (toValueNum - startValue)) : undefined;
const relativeExtremum2 = firstBound !== undefined ? Math.abs((firstBound - toValueNum) / (toValueNum - startValue)) : undefined;
/** Use this formula http://hyperphysics.phy-astr.gsu.edu/hbase/oscda.html to calculate
* first two extrema. These extrema are located where cos = +- 1
*
* Therefore the first two extrema are:
*
* Math.exp(-zeta * Math.PI); (over the target)
* Math.exp(-zeta * 2 * Math.PI); (before the target)
*/
const newZeta1 = relativeExtremum1 !== undefined ? Math.abs(Math.log(relativeExtremum1) / Math.PI) : undefined;
const newZeta2 = relativeExtremum2 !== undefined ? Math.abs(Math.log(relativeExtremum2) / (2 * Math.PI)) : undefined;
const zetaSatisfyingClamp = [newZeta1, newZeta2].filter(x => x !== undefined);
// The bigger is zeta the smaller are bounces, we return the biggest one
// because it should satisfy all conditions
return Math.max(...zetaSatisfyingClamp, zeta);
}
/** Runs before initial */
export function calculateNewMassToMatchDuration(x0, config, v0) {
'worklet';
if (config.skipAnimation) {
return 0;
}
/** Use this formula: https://phys.libretexts.org/Bookshelves/University_Physics/Book%3A_University_Physics_(OpenStax)/Book%3A_University_Physics_I_-_Mechanics_Sound_Oscillations_and_Waves_(OpenStax)/15%3A_Oscillations/15.06%3A_Damped_Oscillations
* to find the asymptote and estimate the damping that gives us the expected duration
⎛ ⎛ c⎞ ⎞
⎜-⎜──⎟ ⋅ duration⎟
⎝ ⎝2m⎠ ⎠
A ⋅ e = threshold
Amplitude calculated using "Conservation of energy"
_________________
2 2
m ⋅ v0 + k ⋅ x0
amplitude = ─────────────────
╲╱ k
And replace mass with damping ratio which is provided: m = (c^2)/(4 * k * zeta^2)
*/
const {
stiffness: k,
dampingRatio: zeta,
restSpeedThreshold: threshold,
duration
} = config;
const durationForMass = mass => {
'worklet';
const amplitude = (mass * v0 * v0 + k * x0 * x0) / (Math.exp(1 - 0.5 * zeta) * k);
const c = zeta * 2 * Math.sqrt(k * mass);
return 1000 * (-2 * mass / c) * Math.log(threshold * 0.01 / amplitude) - duration;
};
// Bisection turns out to be much faster than Newton's method in our case
return bisectRoot({
min: 0,
max: 100,
func: durationForMass
});
}
export function criticallyDampedSpringCalculations(animation, precalculatedValues) {
'worklet';
const {
toValue
} = animation;
const {
v0,
x0,
omega0,
t
} = precalculatedValues;
const criticallyDampedEnvelope = Math.exp(-omega0 * t);
const criticallyDampedPosition = toValue - criticallyDampedEnvelope * (x0 + (v0 + omega0 * x0) * t);
const criticallyDampedVelocity = criticallyDampedEnvelope * (v0 * (t * omega0 - 1) + t * x0 * omega0 * omega0);
return {
position: criticallyDampedPosition,
velocity: criticallyDampedVelocity
};
}
export function underDampedSpringCalculations(animation, precalculatedValues) {
'worklet';
const {
toValue,
current,
velocity
} = animation;
const {
zeta,
t,
omega0,
omega1
} = precalculatedValues;
const v0 = -velocity;
const x0 = toValue - current;
const sin1 = Math.sin(omega1 * t);
const cos1 = Math.cos(omega1 * t);
// under damped
const underDampedEnvelope = Math.exp(-zeta * omega0 * t);
const underDampedFrag1 = underDampedEnvelope * (sin1 * ((v0 + zeta * omega0 * x0) / omega1) + x0 * cos1);
const underDampedPosition = toValue - underDampedFrag1;
// This looks crazy -- it's actually just the derivative of the oscillation function
const underDampedVelocity = zeta * omega0 * underDampedFrag1 - underDampedEnvelope * (cos1 * (v0 + zeta * omega0 * x0) - omega1 * x0 * sin1);
return {
position: underDampedPosition,
velocity: underDampedVelocity
};
}
export function isAnimationTerminatingCalculation(animation, config) {
'worklet';
const {
toValue,
velocity,
startValue,
current
} = animation;
const isOvershooting = config.overshootClamping ? current > toValue && startValue < toValue || current < toValue && startValue > toValue : false;
const isVelocity = Math.abs(velocity) < config.restSpeedThreshold;
const isDisplacement = Math.abs(toValue - current) < config.restDisplacementThreshold;
return {
isOvershooting,
isVelocity,
isDisplacement
};
}
//# sourceMappingURL=springUtils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,173 @@
'use strict';
import { defineAnimation } from './util';
import { withTiming } from './timing';
import { ColorProperties, processColor } from '../Colors';
// resolves path to value for nested objects
// if path cannot be resolved returns undefined
function resolvePath(obj, path) {
'worklet';
const keys = Array.isArray(path) ? path : [path];
return keys.reduce((acc, current) => {
if (Array.isArray(acc) && typeof current === 'number') {
return acc[current];
} else if (acc !== null && typeof acc === 'object' && current in acc) {
return acc[current];
}
return undefined;
}, obj);
}
// set value at given path
function setPath(obj, path, value) {
'worklet';
const keys = Array.isArray(path) ? path : [path];
let currObj = obj;
for (let i = 0; i < keys.length - 1; i++) {
// creates entry if there isn't one
currObj = currObj;
if (!(keys[i] in currObj)) {
// if next key is a number create an array
if (typeof keys[i + 1] === 'number') {
currObj[keys[i]] = [];
} else {
currObj[keys[i]] = {};
}
}
currObj = currObj[keys[i]];
}
currObj[keys[keys.length - 1]] = value;
}
export function withStyleAnimation(styleAnimations) {
'worklet';
return defineAnimation({}, () => {
'worklet';
const onFrame = (animation, now) => {
let stillGoing = false;
const entriesToCheck = [{
value: animation.styleAnimations,
path: []
}];
while (entriesToCheck.length > 0) {
const currentEntry = entriesToCheck.pop();
if (Array.isArray(currentEntry.value)) {
for (let index = 0; index < currentEntry.value.length; index++) {
entriesToCheck.push({
value: currentEntry.value[index],
path: currentEntry.path.concat(index)
});
}
} else if (typeof currentEntry.value === 'object' && currentEntry.value.onFrame === undefined) {
// nested object
for (const key of Object.keys(currentEntry.value)) {
entriesToCheck.push({
value: currentEntry.value[key],
path: currentEntry.path.concat(key)
});
}
} else {
const currentStyleAnimation = currentEntry.value;
if (currentStyleAnimation.finished) {
continue;
}
const finished = currentStyleAnimation.onFrame(currentStyleAnimation, now);
if (finished) {
currentStyleAnimation.finished = true;
if (currentStyleAnimation.callback) {
currentStyleAnimation.callback(true);
}
} else {
stillGoing = true;
}
// When working with animations changing colors, we need to make sure that each one of them begins with a rgba, not a processed number.
// Thus, we only set the path to a processed color, but currentStyleAnimation.current stays as rgba.
const isAnimatingColorProp = ColorProperties.includes(currentEntry.path[0]);
setPath(animation.current, currentEntry.path, isAnimatingColorProp ? processColor(currentStyleAnimation.current) : currentStyleAnimation.current);
}
}
return !stillGoing;
};
const onStart = (animation, value, now, previousAnimation) => {
const entriesToCheck = [{
value: styleAnimations,
path: []
}];
while (entriesToCheck.length > 0) {
const currentEntry = entriesToCheck.pop();
if (Array.isArray(currentEntry.value)) {
for (let index = 0; index < currentEntry.value.length; index++) {
entriesToCheck.push({
value: currentEntry.value[index],
path: currentEntry.path.concat(index)
});
}
} else if (typeof currentEntry.value === 'object' && currentEntry.value.onStart === undefined) {
for (const key of Object.keys(currentEntry.value)) {
entriesToCheck.push({
value: currentEntry.value[key],
path: currentEntry.path.concat(key)
});
}
} else {
const prevAnimation = resolvePath(previousAnimation === null || previousAnimation === void 0 ? void 0 : previousAnimation.styleAnimations, currentEntry.path);
let prevVal = resolvePath(value, currentEntry.path);
if (prevAnimation && !prevVal) {
prevVal = prevAnimation.current;
}
if (prevVal === undefined) {
console.warn(`Initial values for animation are missing for property ${currentEntry.path.join('.')}`);
}
setPath(animation.current, currentEntry.path, prevVal);
let currentAnimation;
if (typeof currentEntry.value !== 'object' || !currentEntry.value.onStart) {
currentAnimation = withTiming(currentEntry.value, {
duration: 0
}); // TODO TYPESCRIPT this temporary cast is to get rid of .d.ts file.
setPath(animation.styleAnimations, currentEntry.path, currentAnimation);
} else {
currentAnimation = currentEntry.value;
}
currentAnimation.onStart(currentAnimation, prevVal, now, prevAnimation);
}
}
};
const callback = finished => {
if (!finished) {
const animationsToCheck = [styleAnimations];
while (animationsToCheck.length > 0) {
const currentAnimation = animationsToCheck.pop();
if (Array.isArray(currentAnimation)) {
for (const element of currentAnimation) {
animationsToCheck.push(element);
}
} else if (typeof currentAnimation === 'object' && currentAnimation.onStart === undefined) {
for (const value of Object.values(currentAnimation)) {
animationsToCheck.push(value);
}
} else {
const currentStyleAnimation = currentAnimation;
if (!currentStyleAnimation.finished && currentStyleAnimation.callback) {
currentStyleAnimation.callback(false);
}
}
}
}
};
return {
isHigherOrder: true,
onFrame,
onStart,
current: {},
styleAnimations,
callback
};
});
}
//# sourceMappingURL=styleAnimation.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,93 @@
'use strict';
import { Easing } from '../Easing';
import { assertEasingIsWorklet, defineAnimation, getReduceMotionForAnimation } from './util';
/**
* The timing animation configuration.
*
* @param duration - Length of the animation (in milliseconds). Defaults to 300.
* @param easing - An easing function which defines the animation curve. Defaults to `Easing.inOut(Easing.quad)`.
* @param reduceMotion - Determines how the animation responds to the device's reduced motion accessibility setting. Default to `ReduceMotion.System` - {@link ReduceMotion}.
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withTiming#config-
*/
// TODO TYPESCRIPT This is temporary type put in here to get rid of our .d.ts file
/**
* Lets you create an animation based on duration and easing.
*
* @param toValue - The value on which the animation will come at rest - {@link AnimatableValue}.
* @param config - The timing animation configuration - {@link TimingConfig}.
* @param callback - A function called on animation complete - {@link AnimationCallback}.
* @returns An [animation object](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animation-object) which holds the current state of the animation.
* @see https://docs.swmansion.com/react-native-reanimated/docs/animations/withTiming
*/
export const withTiming = function (toValue, userConfig, callback) {
'worklet';
if (__DEV__ && userConfig !== null && userConfig !== void 0 && userConfig.easing) {
assertEasingIsWorklet(userConfig.easing);
}
return defineAnimation(toValue, () => {
'worklet';
const config = {
duration: 300,
easing: Easing.inOut(Easing.quad)
};
if (userConfig) {
Object.keys(userConfig).forEach(key => config[key] = userConfig[key]);
}
function timing(animation, now) {
// eslint-disable-next-line @typescript-eslint/no-shadow
const {
toValue,
startTime,
startValue
} = animation;
const runtime = now - startTime;
if (runtime >= config.duration) {
// reset startTime to avoid reusing finished animation config in `start` method
animation.startTime = 0;
animation.current = toValue;
return true;
}
const progress = animation.easing(runtime / config.duration);
animation.current = startValue + (toValue - startValue) * progress;
return false;
}
function onStart(animation, value, now, previousAnimation) {
if (previousAnimation && previousAnimation.type === 'timing' && previousAnimation.toValue === toValue && previousAnimation.startTime) {
// to maintain continuity of timing animations we check if we are starting
// new timing over the old one with the same parameters. If so, we want
// to copy animation timeline properties
animation.startTime = previousAnimation.startTime;
animation.startValue = previousAnimation.startValue;
} else {
animation.startTime = now;
animation.startValue = value;
}
animation.current = value;
if (typeof config.easing === 'object') {
animation.easing = config.easing.factory();
} else {
animation.easing = config.easing;
}
}
return {
type: 'timing',
onFrame: timing,
onStart: onStart,
progress: 0,
toValue,
startValue: 0,
startTime: 0,
easing: () => 0,
current: toValue,
callback,
reduceMotion: getReduceMotionForAnimation(userConfig === null || userConfig === void 0 ? void 0 : userConfig.reduceMotion)
};
});
};
//# sourceMappingURL=timing.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,200 @@
'use strict';
export function isAffineMatrixFlat(x) {
'worklet';
return Array.isArray(x) && x.length === 16 && x.every(element => typeof element === 'number' && !isNaN(element));
}
// ts-prune-ignore-next This function is exported to be tested
export function isAffineMatrix(x) {
'worklet';
return Array.isArray(x) && x.length === 4 && x.every(row => Array.isArray(row) && row.length === 4 && row.every(element => typeof element === 'number' && !isNaN(element)));
}
export function flatten(matrix) {
'worklet';
return matrix.flat();
}
// ts-prune-ignore-next This function is exported to be tested
export function unflatten(m) {
'worklet';
return [[m[0], m[1], m[2], m[3]], [m[4], m[5], m[6], m[7]], [m[8], m[9], m[10], m[11]], [m[12], m[13], m[14], m[15]]];
}
function maybeFlattenMatrix(matrix) {
'worklet';
return isAffineMatrix(matrix) ? flatten(matrix) : matrix;
}
export function multiplyMatrices(a, b) {
'worklet';
return [[a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0] + a[0][3] * b[3][0], a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1] + a[0][3] * b[3][1], a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2] + a[0][3] * b[3][2], a[0][0] * b[0][3] + a[0][1] * b[1][3] + a[0][2] * b[2][3] + a[0][3] * b[3][3]], [a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0] + a[1][3] * b[3][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1] + a[1][3] * b[3][1], a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2] + a[1][3] * b[3][2], a[1][0] * b[0][3] + a[1][1] * b[1][3] + a[1][2] * b[2][3] + a[1][3] * b[3][3]], [a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0] + a[2][3] * b[3][0], a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1] + a[2][3] * b[3][1], a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2] + a[2][3] * b[3][2], a[2][0] * b[0][3] + a[2][1] * b[1][3] + a[2][2] * b[2][3] + a[2][3] * b[3][3]], [a[3][0] * b[0][0] + a[3][1] * b[1][0] + a[3][2] * b[2][0] + a[3][3] * b[3][0], a[3][0] * b[0][1] + a[3][1] * b[1][1] + a[3][2] * b[2][1] + a[3][3] * b[3][1], a[3][0] * b[0][2] + a[3][1] * b[1][2] + a[3][2] * b[2][2] + a[3][3] * b[3][2], a[3][0] * b[0][3] + a[3][1] * b[1][3] + a[3][2] * b[2][3] + a[3][3] * b[3][3]]];
}
export function subtractMatrices(maybeFlatA, maybeFlatB) {
'worklet';
const isFlatOnStart = isAffineMatrixFlat(maybeFlatA);
const a = maybeFlattenMatrix(maybeFlatA);
const b = maybeFlattenMatrix(maybeFlatB);
const c = a.map((_, i) => a[i] - b[i]);
return isFlatOnStart ? c : unflatten(c);
}
export function addMatrices(maybeFlatA, maybeFlatB) {
'worklet';
const isFlatOnStart = isAffineMatrixFlat(maybeFlatA);
const a = maybeFlattenMatrix(maybeFlatA);
const b = maybeFlattenMatrix(maybeFlatB);
const c = a.map((_, i) => a[i] + b[i]);
return isFlatOnStart ? c : unflatten(c);
}
export function scaleMatrix(maybeFlatA, scalar) {
'worklet';
const isFlatOnStart = isAffineMatrixFlat(maybeFlatA);
const a = maybeFlattenMatrix(maybeFlatA);
const b = a.map(x => x * scalar);
return isFlatOnStart ? b : unflatten(b);
}
export function getRotationMatrix(angle, axis = 'z') {
'worklet';
const cos = Math.cos(angle);
const sin = Math.sin(angle);
switch (axis) {
case 'z':
return [[cos, sin, 0, 0], [-sin, cos, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
case 'y':
return [[cos, 0, -sin, 0], [0, 1, 0, 0], [sin, 0, cos, 0], [0, 0, 0, 1]];
case 'x':
return [[1, 0, 0, 0], [0, cos, sin, 0], [0, -sin, cos, 0], [0, 0, 0, 1]];
}
}
function norm3d(x, y, z) {
'worklet';
return Math.sqrt(x * x + y * y + z * z);
}
function transposeMatrix(matrix) {
'worklet';
const m = flatten(matrix);
return [[m[0], m[4], m[8], m[12]], [m[1], m[5], m[9], m[13]], [m[2], m[6], m[10], m[14]], [m[3], m[7], m[11], m[15]]];
}
function assertVectorsHaveEqualLengths(a, b) {
'worklet';
if (__DEV__ && a.length !== b.length) {
throw new Error(`[Reanimated] Cannot calculate inner product of two vectors of different lengths. Length of ${a.toString()} is ${a.length} and length of ${b.toString()} is ${b.length}.`);
}
}
function innerProduct(a, b) {
'worklet';
assertVectorsHaveEqualLengths(a, b);
return a.reduce((acc, _, i) => acc + a[i] * b[i], 0);
}
function projection(u, a) {
'worklet';
assertVectorsHaveEqualLengths(u, a);
const s = innerProduct(u, a) / innerProduct(u, u);
return u.map(e => e * s);
}
function subtractVectors(a, b) {
'worklet';
assertVectorsHaveEqualLengths(a, b);
return a.map((_, i) => a[i] - b[i]);
}
function scaleVector(u, a) {
'worklet';
return u.map(e => e * a);
}
function gramSchmidtAlgorithm(matrix) {
// Gram-Schmidt orthogonalization decomposes any matrix with non-zero determinant into an orthogonal and a triangular matrix
// These matrices are equal to rotation and skew matrices respectively, because we apply it to transformation matrix
// That is expected to already have extracted the remaining transforms (scale & translation)
'worklet';
const [a0, a1, a2, a3] = matrix;
const u0 = a0;
const u1 = subtractVectors(a1, projection(u0, a1));
const u2 = subtractVectors(subtractVectors(a2, projection(u0, a2)), projection(u1, a2));
const u3 = subtractVectors(subtractVectors(subtractVectors(a3, projection(u0, a3)), projection(u1, a3)), projection(u2, a3));
const [e0, e1, e2, e3] = [u0, u1, u2, u3].map(u => scaleVector(u, 1 / Math.sqrt(innerProduct(u, u))));
const rotationMatrix = [[e0[0], e1[0], e2[0], e3[0]], [e0[1], e1[1], e2[1], e3[1]], [e0[2], e1[2], e2[2], e3[2]], [e0[3], e1[3], e2[3], e3[3]]];
const skewMatrix = [[innerProduct(e0, a0), innerProduct(e0, a1), innerProduct(e0, a2), innerProduct(e0, a3)], [0, innerProduct(e1, a1), innerProduct(e1, a2), innerProduct(e1, a3)], [0, 0, innerProduct(e2, a2), innerProduct(e2, a3)], [0, 0, 0, innerProduct(e3, a3)]];
return {
rotationMatrix: transposeMatrix(rotationMatrix),
skewMatrix: transposeMatrix(skewMatrix)
};
}
// ts-prune-ignore-next This function is exported to be tested
export function decomposeMatrix(unknownTypeMatrix) {
'worklet';
const matrix = maybeFlattenMatrix(unknownTypeMatrix);
// normalize matrix
if (matrix[15] === 0) {
throw new Error('[Reanimated] Invalid transform matrix.');
}
matrix.forEach((_, i) => matrix[i] /= matrix[15]);
const translationMatrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [matrix[12], matrix[13], matrix[14], 1]];
const sx = matrix[15] * norm3d(matrix[0], matrix[4], matrix[8]);
const sy = matrix[15] * norm3d(matrix[1], matrix[5], matrix[9]);
const sz = matrix[15] * norm3d(matrix[2], matrix[6], matrix[10]);
// eslint-disable-next-line @typescript-eslint/no-shadow
const scaleMatrix = [[sx, 0, 0, 0], [0, sy, 0, 0], [0, 0, sz, 0], [0, 0, 0, 1]];
const rotationAndSkewMatrix = [[matrix[0] / sx, matrix[1] / sx, matrix[2] / sx, 0], [matrix[4] / sy, matrix[5] / sy, matrix[6] / sy, 0], [matrix[8] / sz, matrix[9] / sz, matrix[10] / sz, 0], [0, 0, 0, 1]];
const {
rotationMatrix,
skewMatrix
} = gramSchmidtAlgorithm(rotationAndSkewMatrix);
return {
translationMatrix,
scaleMatrix,
rotationMatrix,
skewMatrix
};
}
export function decomposeMatrixIntoMatricesAndAngles(matrix) {
'worklet';
// eslint-disable-next-line @typescript-eslint/no-shadow
const {
scaleMatrix,
rotationMatrix,
translationMatrix,
skewMatrix
} = decomposeMatrix(matrix);
const sinRy = -rotationMatrix[0][2];
const ry = Math.asin(sinRy);
let rx;
let rz;
if (sinRy === 1 || sinRy === -1) {
rz = 0;
rx = Math.atan2(sinRy * rotationMatrix[0][1], sinRy * rotationMatrix[0][2]);
} else {
rz = Math.atan2(rotationMatrix[0][1], rotationMatrix[0][0]);
rx = Math.atan2(rotationMatrix[1][2], rotationMatrix[2][2]);
}
return {
scaleMatrix,
rotationMatrix,
translationMatrix,
skewMatrix,
rx: rx || 0,
ry: ry || 0,
rz: rz || 0
};
}
//# sourceMappingURL=matrixUtils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,341 @@
/* eslint-disable @typescript-eslint/no-shadow */
'use strict';
import { isColor, convertToRGBA, rgbaArrayToRGBAColor, toGammaSpace, toLinearSpace } from '../Colors';
import { ReduceMotion, isWorkletFunction } from '../commonTypes';
import { flatten, multiplyMatrices, scaleMatrix, addMatrices, decomposeMatrixIntoMatricesAndAngles, isAffineMatrixFlat, subtractMatrices, getRotationMatrix } from './transformationMatrix/matrixUtils';
import { isReducedMotion, shouldBeUseWeb } from '../PlatformChecker';
let IN_STYLE_UPDATER = false;
const IS_REDUCED_MOTION = isReducedMotion();
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
if (__DEV__ && IS_REDUCED_MOTION) {
console.warn(`[Reanimated] Reduced motion setting is enabled on this device. This warning is visible only in the development mode. Some animations will be disabled by default. You can override the behavior for individual animations, see https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#reduced-motion-setting-is-enabled-on-this-device.`);
}
export function assertEasingIsWorklet(easing) {
'worklet';
if (_WORKLET) {
// If this is called on UI (for example from gesture handler with worklets), we don't get easing,
// but its bound copy, which is not a worklet. We don't want to throw any error then.
return;
}
if (SHOULD_BE_USE_WEB) {
// It is possible to run reanimated on web without plugin, so let's skip this check on web
return;
}
// @ts-ignore typescript wants us to use `in` instead, which doesn't work with host objects
if (easing !== null && easing !== void 0 && easing.factory) {
return;
}
if (!isWorkletFunction(easing)) {
throw new Error('[Reanimated] The easing function is not a worklet. Please make sure you import `Easing` from react-native-reanimated.');
}
}
export function initialUpdaterRun(updater) {
IN_STYLE_UPDATER = true;
const result = updater();
IN_STYLE_UPDATER = false;
return result;
}
export function recognizePrefixSuffix(value) {
'worklet';
if (typeof value === 'string') {
const match = value.match(/([A-Za-z]*)(-?\d*\.?\d*)([eE][-+]?[0-9]+)?([A-Za-z%]*)/);
if (!match) {
throw new Error("[Reanimated] Couldn't parse animation value.");
}
const prefix = match[1];
const suffix = match[4];
// number with scientific notation
const number = match[2] + (match[3] ?? '');
return {
prefix,
suffix,
strippedValue: parseFloat(number)
};
} else {
return {
strippedValue: value
};
}
}
/**
* Returns whether the motion should be reduced for a specified config.
* By default returns the system setting.
*/
export function getReduceMotionFromConfig(config) {
'worklet';
return !config || config === ReduceMotion.System ? IS_REDUCED_MOTION : config === ReduceMotion.Always;
}
/**
* Returns the value that should be assigned to `animation.reduceMotion`
* for a given config. If the config is not defined, `undefined` is returned.
*/
export function getReduceMotionForAnimation(config) {
'worklet';
// if the config is not defined, we want `reduceMotion` to be undefined,
// so the parent animation knows if it should overwrite it
if (!config) {
return undefined;
}
return getReduceMotionFromConfig(config);
}
function applyProgressToMatrix(progress, a, b) {
'worklet';
return addMatrices(a, scaleMatrix(subtractMatrices(b, a), progress));
}
function applyProgressToNumber(progress, a, b) {
'worklet';
return a + progress * (b - a);
}
function decorateAnimation(animation) {
'worklet';
const baseOnStart = animation.onStart;
const baseOnFrame = animation.onFrame;
if (animation.isHigherOrder) {
animation.onStart = (animation, value, timestamp, previousAnimation) => {
if (animation.reduceMotion === undefined) {
animation.reduceMotion = getReduceMotionFromConfig();
}
return baseOnStart(animation, value, timestamp, previousAnimation);
};
return;
}
const animationCopy = Object.assign({}, animation);
delete animationCopy.callback;
const prefNumberSuffOnStart = (animation, value, timestamp, previousAnimation) => {
// recognize prefix, suffix, and updates stripped value on animation start
const {
prefix,
suffix,
strippedValue
} = recognizePrefixSuffix(value);
animation.__prefix = prefix;
animation.__suffix = suffix;
animation.strippedCurrent = strippedValue;
const {
strippedValue: strippedToValue
} = recognizePrefixSuffix(animation.toValue);
animation.current = strippedValue;
animation.startValue = strippedValue;
animation.toValue = strippedToValue;
if (previousAnimation && previousAnimation !== animation) {
const {
prefix: paPrefix,
suffix: paSuffix,
strippedValue: paStrippedValue
} = recognizePrefixSuffix(previousAnimation.current);
previousAnimation.current = paStrippedValue;
previousAnimation.__prefix = paPrefix;
previousAnimation.__suffix = paSuffix;
}
baseOnStart(animation, strippedValue, timestamp, previousAnimation);
animation.current = (animation.__prefix ?? '') + animation.current + (animation.__suffix ?? '');
if (previousAnimation && previousAnimation !== animation) {
previousAnimation.current = (previousAnimation.__prefix ?? '') +
// FIXME
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
previousAnimation.current + (previousAnimation.__suffix ?? '');
}
};
const prefNumberSuffOnFrame = (animation, timestamp) => {
animation.current = animation.strippedCurrent;
const res = baseOnFrame(animation, timestamp);
animation.strippedCurrent = animation.current;
animation.current = (animation.__prefix ?? '') + animation.current + (animation.__suffix ?? '');
return res;
};
const tab = ['R', 'G', 'B', 'A'];
const colorOnStart = (animation, value, timestamp, previousAnimation) => {
let RGBAValue;
let RGBACurrent;
let RGBAToValue;
const res = [];
if (isColor(value)) {
RGBACurrent = toLinearSpace(convertToRGBA(animation.current));
RGBAValue = toLinearSpace(convertToRGBA(value));
if (animation.toValue) {
RGBAToValue = toLinearSpace(convertToRGBA(animation.toValue));
}
}
tab.forEach((i, index) => {
animation[i] = Object.assign({}, animationCopy);
animation[i].current = RGBACurrent[index];
animation[i].toValue = RGBAToValue ? RGBAToValue[index] : undefined;
animation[i].onStart(animation[i], RGBAValue[index], timestamp, previousAnimation ? previousAnimation[i] : undefined);
res.push(animation[i].current);
});
animation.current = rgbaArrayToRGBAColor(toGammaSpace(res));
};
const colorOnFrame = (animation, timestamp) => {
const RGBACurrent = toLinearSpace(convertToRGBA(animation.current));
const res = [];
let finished = true;
tab.forEach((i, index) => {
animation[i].current = RGBACurrent[index];
const result = animation[i].onFrame(animation[i], timestamp);
// We really need to assign this value to result, instead of passing it directly - otherwise once "finished" is false, onFrame won't be called
finished = finished && result;
res.push(animation[i].current);
});
animation.current = rgbaArrayToRGBAColor(toGammaSpace(res));
return finished;
};
const transformationMatrixOnStart = (animation, value, timestamp, previousAnimation) => {
const toValue = animation.toValue;
animation.startMatrices = decomposeMatrixIntoMatricesAndAngles(value);
animation.stopMatrices = decomposeMatrixIntoMatricesAndAngles(toValue);
// We create an animation copy to animate single value between 0 and 100
// We set limits from 0 to 100 (instead of 0-1) to make spring look good
// with default thresholds.
animation[0] = Object.assign({}, animationCopy);
animation[0].current = 0;
animation[0].toValue = 100;
animation[0].onStart(animation[0], 0, timestamp, previousAnimation ? previousAnimation[0] : undefined);
animation.current = value;
};
const transformationMatrixOnFrame = (animation, timestamp) => {
let finished = true;
const result = animation[0].onFrame(animation[0], timestamp);
// We really need to assign this value to result, instead of passing it directly - otherwise once "finished" is false, onFrame won't be called
finished = finished && result;
const progress = animation[0].current / 100;
const transforms = ['translationMatrix', 'scaleMatrix', 'skewMatrix'];
const mappedTransforms = [];
transforms.forEach((key, _) => mappedTransforms.push(applyProgressToMatrix(progress, animation.startMatrices[key], animation.stopMatrices[key])));
const [currentTranslation, currentScale, skewMatrix] = mappedTransforms;
const rotations = ['x', 'y', 'z'];
const mappedRotations = [];
rotations.forEach((key, _) => {
const angle = applyProgressToNumber(progress, animation.startMatrices['r' + key], animation.stopMatrices['r' + key]);
mappedRotations.push(getRotationMatrix(angle, key));
});
const [rotationMatrixX, rotationMatrixY, rotationMatrixZ] = mappedRotations;
const rotationMatrix = multiplyMatrices(rotationMatrixX, multiplyMatrices(rotationMatrixY, rotationMatrixZ));
const updated = flatten(multiplyMatrices(multiplyMatrices(currentScale, multiplyMatrices(skewMatrix, rotationMatrix)), currentTranslation));
animation.current = updated;
return finished;
};
const arrayOnStart = (animation, value, timestamp, previousAnimation) => {
value.forEach((v, i) => {
animation[i] = Object.assign({}, animationCopy);
animation[i].current = v;
animation[i].toValue = animation.toValue[i];
animation[i].onStart(animation[i], v, timestamp, previousAnimation ? previousAnimation[i] : undefined);
});
animation.current = value;
};
const arrayOnFrame = (animation, timestamp) => {
let finished = true;
animation.current.forEach((_, i) => {
const result = animation[i].onFrame(animation[i], timestamp);
// We really need to assign this value to result, instead of passing it directly - otherwise once "finished" is false, onFrame won't be called
finished = finished && result;
animation.current[i] = animation[i].current;
});
return finished;
};
const objectOnStart = (animation, value, timestamp, previousAnimation) => {
for (const key in value) {
animation[key] = Object.assign({}, animationCopy);
animation[key].onStart = animation.onStart;
animation[key].current = value[key];
animation[key].toValue = animation.toValue[key];
animation[key].onStart(animation[key], value[key], timestamp, previousAnimation ? previousAnimation[key] : undefined);
}
animation.current = value;
};
const objectOnFrame = (animation, timestamp) => {
let finished = true;
const newObject = {};
for (const key in animation.current) {
const result = animation[key].onFrame(animation[key], timestamp);
// We really need to assign this value to result, instead of passing it directly - otherwise once "finished" is false, onFrame won't be called
finished = finished && result;
newObject[key] = animation[key].current;
}
animation.current = newObject;
return finished;
};
animation.onStart = (animation, value, timestamp, previousAnimation) => {
if (animation.reduceMotion === undefined) {
animation.reduceMotion = getReduceMotionFromConfig();
}
if (animation.reduceMotion) {
if (animation.toValue !== undefined) {
animation.current = animation.toValue;
} else {
// if there is no `toValue`, then the base function is responsible for setting the current value
baseOnStart(animation, value, timestamp, previousAnimation);
}
animation.startTime = 0;
animation.onFrame = () => true;
return;
}
if (isColor(value)) {
colorOnStart(animation, value, timestamp, previousAnimation);
animation.onFrame = colorOnFrame;
return;
} else if (isAffineMatrixFlat(value)) {
transformationMatrixOnStart(animation, value, timestamp, previousAnimation);
animation.onFrame = transformationMatrixOnFrame;
return;
} else if (Array.isArray(value)) {
arrayOnStart(animation, value, timestamp, previousAnimation);
animation.onFrame = arrayOnFrame;
return;
} else if (typeof value === 'string') {
prefNumberSuffOnStart(animation, value, timestamp, previousAnimation);
animation.onFrame = prefNumberSuffOnFrame;
return;
} else if (typeof value === 'object' && value !== null) {
objectOnStart(animation, value, timestamp, previousAnimation);
animation.onFrame = objectOnFrame;
return;
}
baseOnStart(animation, value, timestamp, previousAnimation);
};
}
export function defineAnimation(starting, factory) {
'worklet';
if (IN_STYLE_UPDATER) {
return starting;
}
const create = () => {
'worklet';
const animation = factory();
decorateAnimation(animation);
return animation;
};
if (_WORKLET || SHOULD_BE_USE_WEB) {
return create();
}
// @ts-ignore: eslint-disable-line
return create;
}
/**
* Lets you cancel a running animation paired to a shared value.
*
* @param sharedValue - The shared value of a running animation that you want to cancel.
* @see https://docs.swmansion.com/react-native-reanimated/docs/core/cancelAnimation
*/
export function cancelAnimation(sharedValue) {
'worklet';
// setting the current value cancels the animation if one is currently running
sharedValue.value = sharedValue.value; // eslint-disable-line no-self-assign
}
//# sourceMappingURL=util.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,107 @@
'use strict';
/**
* A value that can be used both on the [JavaScript thread](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#javascript-thread) and the [UI thread](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#ui-thread).
*
* Shared values are defined using [useSharedValue](https://docs.swmansion.com/react-native-reanimated/docs/core/useSharedValue) hook. You access and modify shared values by their `.value` property.
*/
// The below type is used for HostObjects returned by the JSI API that don't have
// any accessible fields or methods but can carry data that is accessed from the
// c++ side. We add a field to the type to make it possible for typescript to recognize
// which JSI methods accept those types as arguments and to be able to correctly type
// check other methods that may use them. However, this field is not actually defined
// nor should be used for anything else as assigning any data to those objects will
// throw an error.
// In case of objects with depth or arrays of objects or arrays of arrays etc.
// we add this utility type that makes it a SharaebleRef of the outermost type.
/**
* This function allows you to determine if a given function is a worklet. It only works
* with Reanimated Babel plugin enabled. Unless you are doing something with internals of
* Reanimated you shouldn't need to use this function.
*
* ### Note
* Do not call it before the worklet is declared, as it will always return false then. E.g.:
*
* ```ts
* isWorkletFunction(myWorklet); // Will always return false.
*
* function myWorklet() {
* 'worklet';
* };
* ```
*
* ### Maintainer note
* This function works well on the JS thread performance-wise, since the JIT can inline it.
* However, on other threads it will not get optimized and we will get a function call overhead.
* We want to change it in the future, but it's not feasible at the moment.
*/
export function isWorkletFunction(value) {
'worklet';
// Since host objects always return true for `in` operator, we have to use dot notation to check if the property exists.
// See https://github.com/facebook/hermes/blob/340726ef8cf666a7cce75bc60b02fa56b3e54560/lib/VM/JSObject.cpp#L1276.
return typeof value === 'function' && !!value.__workletHash;
}
export let SensorType = /*#__PURE__*/function (SensorType) {
SensorType[SensorType["ACCELEROMETER"] = 1] = "ACCELEROMETER";
SensorType[SensorType["GYROSCOPE"] = 2] = "GYROSCOPE";
SensorType[SensorType["GRAVITY"] = 3] = "GRAVITY";
SensorType[SensorType["MAGNETIC_FIELD"] = 4] = "MAGNETIC_FIELD";
SensorType[SensorType["ROTATION"] = 5] = "ROTATION";
return SensorType;
}({});
export let IOSReferenceFrame = /*#__PURE__*/function (IOSReferenceFrame) {
IOSReferenceFrame[IOSReferenceFrame["XArbitraryZVertical"] = 0] = "XArbitraryZVertical";
IOSReferenceFrame[IOSReferenceFrame["XArbitraryCorrectedZVertical"] = 1] = "XArbitraryCorrectedZVertical";
IOSReferenceFrame[IOSReferenceFrame["XMagneticNorthZVertical"] = 2] = "XMagneticNorthZVertical";
IOSReferenceFrame[IOSReferenceFrame["XTrueNorthZVertical"] = 3] = "XTrueNorthZVertical";
IOSReferenceFrame[IOSReferenceFrame["Auto"] = 4] = "Auto";
return IOSReferenceFrame;
}({});
/**
* A function called upon animation completion. If the animation is cancelled, the callback will receive `false` as the argument; otherwise, it will receive `true`.
*/
export let InterfaceOrientation = /*#__PURE__*/function (InterfaceOrientation) {
InterfaceOrientation[InterfaceOrientation["ROTATION_0"] = 0] = "ROTATION_0";
InterfaceOrientation[InterfaceOrientation["ROTATION_90"] = 90] = "ROTATION_90";
InterfaceOrientation[InterfaceOrientation["ROTATION_180"] = 180] = "ROTATION_180";
InterfaceOrientation[InterfaceOrientation["ROTATION_270"] = 270] = "ROTATION_270";
return InterfaceOrientation;
}({});
export let KeyboardState = /*#__PURE__*/function (KeyboardState) {
KeyboardState[KeyboardState["UNKNOWN"] = 0] = "UNKNOWN";
KeyboardState[KeyboardState["OPENING"] = 1] = "OPENING";
KeyboardState[KeyboardState["OPEN"] = 2] = "OPEN";
KeyboardState[KeyboardState["CLOSING"] = 3] = "CLOSING";
KeyboardState[KeyboardState["CLOSED"] = 4] = "CLOSED";
return KeyboardState;
}({});
/**
* @param x - A number representing X coordinate relative to the parent component.
* @param y - A number representing Y coordinate relative to the parent component.
* @param width - A number representing the width of the component.
* @param height - A number representing the height of the component.
* @param pageX - A number representing X coordinate relative to the screen.
* @param pageY - A number representing Y coordinate relative to the screen.
* @see https://docs.swmansion.com/react-native-reanimated/docs/advanced/measure#returns
*/
/**
* @param System - If the `Reduce motion` accessibility setting is enabled on the device, disable the animation. Otherwise, enable the animation.
* @param Always - Disable the animation.
* @param Never - Enable the animation.
* @see https://docs.swmansion.com/react-native-reanimated/docs/guides/accessibility
*/
export let ReduceMotion = /*#__PURE__*/function (ReduceMotion) {
ReduceMotion["System"] = "system";
ReduceMotion["Always"] = "always";
ReduceMotion["Never"] = "never";
return ReduceMotion;
}({});
//# sourceMappingURL=commonTypes.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,63 @@
'use strict';
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { forwardRef, useRef } from 'react';
import { FlatList } from 'react-native';
import { AnimatedView } from './View';
import { createAnimatedComponent } from '../../createAnimatedComponent';
import { LayoutAnimationConfig } from './LayoutAnimationConfig';
const AnimatedFlatList = createAnimatedComponent(FlatList);
const createCellRendererComponent = itemLayoutAnimationRef => {
const CellRendererComponent = props => {
return /*#__PURE__*/React.createElement(AnimatedView
// TODO TYPESCRIPT This is temporary cast is to get rid of .d.ts file.
, {
layout: itemLayoutAnimationRef === null || itemLayoutAnimationRef === void 0 ? void 0 : itemLayoutAnimationRef.current,
onLayout: props.onLayout,
style: props.style
}, props.children);
};
return CellRendererComponent;
};
// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,
// but not things like NativeMethods, etc. we need to add them manually by extending the type.
// We need explicit any here, because this is the exact same type that is used in React Native types.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const FlatListForwardRefRender = function (props, ref) {
const {
itemLayoutAnimation,
skipEnteringExitingAnimations,
...restProps
} = props;
// Set default scrollEventThrottle, because user expects
// to have continuous scroll events and
// react-native defaults it to 50 for FlatLists.
// We set it to 1, so we have peace until
// there are 960 fps screens.
if (!('scrollEventThrottle' in restProps)) {
restProps.scrollEventThrottle = 1;
}
const itemLayoutAnimationRef = useRef(itemLayoutAnimation);
itemLayoutAnimationRef.current = itemLayoutAnimation;
const CellRendererComponent = React.useMemo(() => createCellRendererComponent(itemLayoutAnimationRef), [itemLayoutAnimationRef]);
const animatedFlatList =
/*#__PURE__*/
// @ts-expect-error In its current type state, createAnimatedComponent cannot create generic components.
React.createElement(AnimatedFlatList, _extends({
ref: ref
}, restProps, {
CellRendererComponent: CellRendererComponent
}));
if (skipEnteringExitingAnimations === undefined) {
return animatedFlatList;
}
return /*#__PURE__*/React.createElement(LayoutAnimationConfig, {
skipEntering: true,
skipExiting: true
}, animatedFlatList);
};
export const ReanimatedFlatList = /*#__PURE__*/forwardRef(FlatListForwardRefRender);
//# sourceMappingURL=FlatList.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
'use strict';
import { Image } from 'react-native';
import { createAnimatedComponent } from '../../createAnimatedComponent';
// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,
// but not things like NativeMethods, etc. we need to add them manually by extending the type.
export const AnimatedImage = createAnimatedComponent(Image);
//# sourceMappingURL=Image.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Image","createAnimatedComponent","AnimatedImage"],"sources":["Image.ts"],"sourcesContent":["'use strict';\nimport { Image } from 'react-native';\nimport { createAnimatedComponent } from '../../createAnimatedComponent';\n\n// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,\n// but not things like NativeMethods, etc. we need to add them manually by extending the type.\ninterface AnimatedImageComplement extends Image {\n getNode(): Image;\n}\n\nexport const AnimatedImage = createAnimatedComponent(Image);\n\nexport type AnimatedImage = typeof AnimatedImage & AnimatedImageComplement;\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,KAAK,QAAQ,cAAc;AACpC,SAASC,uBAAuB,QAAQ,+BAA+B;;AAEvE;AACA;;AAKA,OAAO,MAAMC,aAAa,GAAGD,uBAAuB,CAACD,KAAK,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,64 @@
'use strict';
import React, { Children, Component, createContext, useEffect, useRef } from 'react';
import { setShouldAnimateExitingForTag } from '../core';
import { findNodeHandle } from 'react-native';
export const SkipEnteringContext = /*#__PURE__*/createContext(null);
// skipEntering - don't animate entering of children on wrapper mount
// skipExiting - don't animate exiting of children on wrapper unmount
function SkipEntering(props) {
const skipValueRef = useRef(props.shouldSkip);
useEffect(() => {
skipValueRef.current = false;
}, [skipValueRef]);
return /*#__PURE__*/React.createElement(SkipEnteringContext.Provider, {
value: skipValueRef
}, props.children);
}
// skipExiting (unlike skipEntering) cannot be done by conditionally
// configuring the animation in `createAnimatedComponent`, since at this stage
// we don't know if the wrapper is going to be unmounted or not.
// That's why we need to pass the skipExiting flag to the native side
// when the wrapper is unmounted to prevent the animation.
// Since `ReactNode` can be a list of nodes, we wrap every child with our wrapper
// so we are able to access its tag with `findNodeHandle`.
/**
* A component that lets you skip entering and exiting animations.
*
* @param skipEntering - A boolean indicating whether children's entering animations should be skipped when `LayoutAnimationConfig` is mounted.
* @param skipExiting - A boolean indicating whether children's exiting animations should be skipped when LayoutAnimationConfig is unmounted.
* @see https://docs.swmansion.com/react-native-reanimated/docs/layout-animations/layout-animation-config/
*/
export class LayoutAnimationConfig extends Component {
getMaybeWrappedChildren() {
return Children.count(this.props.children) > 1 && this.props.skipExiting ? Children.map(this.props.children, child => /*#__PURE__*/React.createElement(LayoutAnimationConfig, {
skipExiting: true
}, child)) : this.props.children;
}
setShouldAnimateExiting() {
if (Children.count(this.props.children) === 1) {
const tag = findNodeHandle(this);
if (tag) {
setShouldAnimateExitingForTag(tag, !this.props.skipExiting);
}
}
}
componentWillUnmount() {
if (this.props.skipExiting !== undefined) {
this.setShouldAnimateExiting();
}
}
render() {
const children = this.getMaybeWrappedChildren();
if (this.props.skipEntering === undefined) {
return children;
}
return /*#__PURE__*/React.createElement(SkipEntering, {
shouldSkip: this.props.skipEntering
}, children);
}
}
//# sourceMappingURL=LayoutAnimationConfig.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,169 @@
'use strict';
import React, { useEffect, useRef } from 'react';
import { TextInput, StyleSheet, View } from 'react-native';
import { useSharedValue, useAnimatedProps, useFrameCallback } from '../hook';
import { createAnimatedComponent } from '../../createAnimatedComponent';
import { addWhitelistedNativeProps } from '../../ConfigHelper';
function createCircularDoublesBuffer(size) {
'worklet';
return {
next: 0,
buffer: new Float32Array(size),
size,
count: 0,
push(value) {
const oldValue = this.buffer[this.next];
const oldCount = this.count;
this.buffer[this.next] = value;
this.next = (this.next + 1) % this.size;
this.count = Math.min(this.size, this.count + 1);
return oldCount === this.size ? oldValue : null;
},
front() {
const notEmpty = this.count > 0;
if (notEmpty) {
const current = this.next - 1;
const index = current < 0 ? this.size - 1 : current;
return this.buffer[index];
}
return null;
},
back() {
const notEmpty = this.count > 0;
return notEmpty ? this.buffer[this.next] : null;
}
};
}
const DEFAULT_BUFFER_SIZE = 60;
addWhitelistedNativeProps({
text: true
});
const AnimatedTextInput = createAnimatedComponent(TextInput);
function loopAnimationFrame(fn) {
let lastTime = 0;
function loop() {
requestAnimationFrame(time => {
if (lastTime > 0) {
fn(lastTime, time);
}
lastTime = time;
requestAnimationFrame(loop);
});
}
loop();
}
function getFps(renderTimeInMs) {
'worklet';
return 1000 / renderTimeInMs;
}
function getTimeDelta(timestamp, previousTimestamp) {
'worklet';
return previousTimestamp !== null ? timestamp - previousTimestamp : 0;
}
function completeBufferRoutine(buffer, timestamp, previousTimestamp, totalRenderTime) {
'worklet';
timestamp = Math.round(timestamp);
previousTimestamp = Math.round(previousTimestamp) ?? timestamp;
const droppedTimestamp = buffer.push(timestamp);
const nextToDrop = buffer.back();
const delta = getTimeDelta(timestamp, previousTimestamp);
const droppedDelta = getTimeDelta(nextToDrop, droppedTimestamp);
totalRenderTime.value += delta - droppedDelta;
return getFps(totalRenderTime.value / buffer.count);
}
function JsPerformance() {
const jsFps = useSharedValue(null);
const totalRenderTime = useSharedValue(0);
const circularBuffer = useRef(createCircularDoublesBuffer(DEFAULT_BUFFER_SIZE));
useEffect(() => {
loopAnimationFrame((_, timestamp) => {
timestamp = Math.round(timestamp);
const previousTimestamp = circularBuffer.current.front() ?? timestamp;
const currentFps = completeBufferRoutine(circularBuffer.current, timestamp, previousTimestamp, totalRenderTime);
// JS fps have to be measured every 2nd frame,
// thus 2x multiplication has to occur here
jsFps.value = (currentFps * 2).toFixed(0);
});
}, []);
const animatedProps = useAnimatedProps(() => {
const text = 'JS: ' + jsFps.value ?? 'N/A';
return {
text,
defaultValue: text
};
});
return /*#__PURE__*/React.createElement(View, {
style: styles.container
}, /*#__PURE__*/React.createElement(AnimatedTextInput, {
style: styles.text,
animatedProps: animatedProps,
editable: false
}));
}
function UiPerformance() {
const uiFps = useSharedValue(null);
const totalRenderTime = useSharedValue(0);
const circularBuffer = useSharedValue(null);
useFrameCallback(({
timestamp
}) => {
if (circularBuffer.value === null) {
circularBuffer.value = createCircularDoublesBuffer(DEFAULT_BUFFER_SIZE);
}
timestamp = Math.round(timestamp);
const previousTimestamp = circularBuffer.value.front() ?? timestamp;
const currentFps = completeBufferRoutine(circularBuffer.value, timestamp, previousTimestamp, totalRenderTime);
uiFps.value = currentFps.toFixed(0);
});
const animatedProps = useAnimatedProps(() => {
const text = 'UI: ' + uiFps.value ?? 'N/A';
return {
text,
defaultValue: text
};
});
return /*#__PURE__*/React.createElement(View, {
style: styles.container
}, /*#__PURE__*/React.createElement(AnimatedTextInput, {
style: styles.text,
animatedProps: animatedProps,
editable: false
}));
}
export function PerformanceMonitor() {
return /*#__PURE__*/React.createElement(View, {
style: styles.monitor
}, /*#__PURE__*/React.createElement(JsPerformance, null), /*#__PURE__*/React.createElement(UiPerformance, null));
}
const styles = StyleSheet.create({
monitor: {
flexDirection: 'row',
position: 'absolute',
backgroundColor: '#0006',
zIndex: 1000
},
header: {
fontSize: 14,
color: '#ffff',
paddingHorizontal: 5
},
text: {
fontSize: 13,
color: '#ffff',
fontFamily: 'monospace',
paddingHorizontal: 3
},
container: {
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
flexWrap: 'wrap'
}
});
//# sourceMappingURL=PerformanceMonitor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
'use strict';
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { forwardRef } from 'react';
import { ScrollView } from 'react-native';
import { createAnimatedComponent } from '../../createAnimatedComponent';
import { useAnimatedRef, useScrollViewOffset } from '../hook';
// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,
// but not things like NativeMethods, etc. we need to add them manually by extending the type.
const AnimatedScrollViewComponent = createAnimatedComponent(ScrollView);
export const AnimatedScrollView = /*#__PURE__*/forwardRef((props, ref) => {
const {
scrollViewOffset,
...restProps
} = props;
const animatedRef = ref === null ?
// eslint-disable-next-line react-hooks/rules-of-hooks
useAnimatedRef() : ref;
if (scrollViewOffset) {
// eslint-disable-next-line react-hooks/rules-of-hooks
useScrollViewOffset(animatedRef, scrollViewOffset);
}
// Set default scrollEventThrottle, because user expects
// to have continuous scroll events.
// We set it to 1 so we have peace until
// there are 960 fps screens.
if (!('scrollEventThrottle' in restProps)) {
restProps.scrollEventThrottle = 1;
}
return /*#__PURE__*/React.createElement(AnimatedScrollViewComponent, _extends({
ref: animatedRef
}, restProps));
});
//# sourceMappingURL=ScrollView.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_extends","Object","assign","bind","target","i","arguments","length","source","key","prototype","hasOwnProperty","call","apply","React","forwardRef","ScrollView","createAnimatedComponent","useAnimatedRef","useScrollViewOffset","AnimatedScrollViewComponent","AnimatedScrollView","props","ref","scrollViewOffset","restProps","animatedRef","scrollEventThrottle","createElement"],"sources":["ScrollView.tsx"],"sourcesContent":["'use strict';\nimport type { ForwardedRef } from 'react';\nimport React, { forwardRef } from 'react';\nimport type { ScrollViewProps } from 'react-native';\nimport { ScrollView } from 'react-native';\nimport { createAnimatedComponent } from '../../createAnimatedComponent';\nimport type { SharedValue } from '../commonTypes';\nimport type { AnimatedRef } from '../hook';\nimport { useAnimatedRef, useScrollViewOffset } from '../hook';\nimport type { AnimatedProps } from '../helperTypes';\n\nexport interface AnimatedScrollViewProps\n extends AnimatedProps<ScrollViewProps> {\n scrollViewOffset?: SharedValue<number>;\n}\n\n// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,\n// but not things like NativeMethods, etc. we need to add them manually by extending the type.\ninterface AnimatedScrollViewComplement extends ScrollView {\n getNode(): ScrollView;\n}\n\nconst AnimatedScrollViewComponent = createAnimatedComponent(ScrollView);\n\nexport const AnimatedScrollView = forwardRef(\n (props: AnimatedScrollViewProps, ref: ForwardedRef<AnimatedScrollView>) => {\n const { scrollViewOffset, ...restProps } = props;\n const animatedRef = (\n ref === null\n ? // eslint-disable-next-line react-hooks/rules-of-hooks\n useAnimatedRef<ScrollView>()\n : ref\n ) as AnimatedRef<AnimatedScrollView>;\n\n if (scrollViewOffset) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useScrollViewOffset(animatedRef, scrollViewOffset);\n }\n\n // Set default scrollEventThrottle, because user expects\n // to have continuous scroll events.\n // We set it to 1 so we have peace until\n // there are 960 fps screens.\n if (!('scrollEventThrottle' in restProps)) {\n restProps.scrollEventThrottle = 1;\n }\n\n return <AnimatedScrollViewComponent ref={animatedRef} {...restProps} />;\n }\n);\n\nexport type AnimatedScrollView = AnimatedScrollViewComplement &\n typeof AnimatedScrollViewComponent;\n"],"mappings":"AAAA,YAAY;;AAAC,SAAAA,SAAA,IAAAA,QAAA,GAAAC,MAAA,CAAAC,MAAA,GAAAD,MAAA,CAAAC,MAAA,CAAAC,IAAA,eAAAC,MAAA,aAAAC,CAAA,MAAAA,CAAA,GAAAC,SAAA,CAAAC,MAAA,EAAAF,CAAA,UAAAG,MAAA,GAAAF,SAAA,CAAAD,CAAA,YAAAI,GAAA,IAAAD,MAAA,QAAAP,MAAA,CAAAS,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAJ,MAAA,EAAAC,GAAA,KAAAL,MAAA,CAAAK,GAAA,IAAAD,MAAA,CAAAC,GAAA,gBAAAL,MAAA,YAAAJ,QAAA,CAAAa,KAAA,OAAAP,SAAA;AAEb,OAAOQ,KAAK,IAAIC,UAAU,QAAQ,OAAO;AAEzC,SAASC,UAAU,QAAQ,cAAc;AACzC,SAASC,uBAAuB,QAAQ,+BAA+B;AAGvE,SAASC,cAAc,EAAEC,mBAAmB,QAAQ,SAAS;;AAQ7D;AACA;;AAKA,MAAMC,2BAA2B,GAAGH,uBAAuB,CAACD,UAAU,CAAC;AAEvE,OAAO,MAAMK,kBAAkB,gBAAGN,UAAU,CAC1C,CAACO,KAA8B,EAAEC,GAAqC,KAAK;EACzE,MAAM;IAAEC,gBAAgB;IAAE,GAAGC;EAAU,CAAC,GAAGH,KAAK;EAChD,MAAMI,WAAW,GACfH,GAAG,KAAK,IAAI;EACR;EACAL,cAAc,CAAa,CAAC,GAC5BK,GAC8B;EAEpC,IAAIC,gBAAgB,EAAE;IACpB;IACAL,mBAAmB,CAACO,WAAW,EAAEF,gBAAgB,CAAC;EACpD;;EAEA;EACA;EACA;EACA;EACA,IAAI,EAAE,qBAAqB,IAAIC,SAAS,CAAC,EAAE;IACzCA,SAAS,CAACE,mBAAmB,GAAG,CAAC;EACnC;EAEA,oBAAOb,KAAA,CAAAc,aAAA,CAACR,2BAA2B,EAAApB,QAAA;IAACuB,GAAG,EAAEG;EAAY,GAAKD,SAAS,CAAG,CAAC;AACzE,CACF,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,10 @@
'use strict';
import { Text } from 'react-native';
import { createAnimatedComponent } from '../../createAnimatedComponent';
// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,
// but not things like NativeMethods, etc. we need to add them manually by extending the type.
export const AnimatedText = createAnimatedComponent(Text);
//# sourceMappingURL=Text.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Text","createAnimatedComponent","AnimatedText"],"sources":["Text.ts"],"sourcesContent":["'use strict';\nimport { Text } from 'react-native';\nimport { createAnimatedComponent } from '../../createAnimatedComponent';\n\n// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,\n// but not things like NativeMethods, etc. we need to add them manually by extending the type.\ninterface AnimatedTextComplement extends Text {\n getNode(): Text;\n}\n\nexport const AnimatedText = createAnimatedComponent(Text);\n\nexport type AnimatedText = typeof AnimatedText & AnimatedTextComplement;\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,IAAI,QAAQ,cAAc;AACnC,SAASC,uBAAuB,QAAQ,+BAA+B;;AAEvE;AACA;;AAKA,OAAO,MAAMC,YAAY,GAAGD,uBAAuB,CAACD,IAAI,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,10 @@
'use strict';
import { View } from 'react-native';
import { createAnimatedComponent } from '../../createAnimatedComponent';
// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,
// but not things like NativeMethods, etc. we need to add them manually by extending the type.
export const AnimatedView = createAnimatedComponent(View);
//# sourceMappingURL=View.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["View","createAnimatedComponent","AnimatedView"],"sources":["View.ts"],"sourcesContent":["'use strict';\nimport { View } from 'react-native';\nimport { createAnimatedComponent } from '../../createAnimatedComponent';\n\n// Since createAnimatedComponent return type is ComponentClass that has the props of the argument,\n// but not things like NativeMethods, etc. we need to add them manually by extending the type.\ninterface AnimatedViewComplement extends View {\n getNode(): View;\n}\n\nexport const AnimatedView = createAnimatedComponent(View);\n\nexport type AnimatedView = typeof AnimatedView & AnimatedViewComplement;\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,IAAI,QAAQ,cAAc;AACnC,SAASC,uBAAuB,QAAQ,+BAA+B;;AAEvE;AACA;;AAKA,OAAO,MAAMC,YAAY,GAAGD,uBAAuB,CAACD,IAAI,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,132 @@
'use strict';
import NativeReanimatedModule from './NativeReanimated';
import { isWeb, shouldBeUseWeb, isFabric } from './PlatformChecker';
import { makeShareableCloneRecursive } from './shareables';
import { initializeUIRuntime } from './initializers';
import { SensorContainer } from './SensorContainer';
export { startMapper, stopMapper } from './mappers';
export { runOnJS, runOnUI, executeOnUIRuntimeSync } from './threads';
export { createWorkletRuntime, runOnRuntime } from './runtimes';
export { makeShareable, makeShareableCloneRecursive } from './shareables';
export { makeMutable } from './mutables';
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
/**
* @returns `true` in Reanimated 3, doesn't exist in Reanimated 2 or 1
*/
export const isReanimated3 = () => true;
// Superseded by check in `/src/threads.ts`.
// Used by `react-navigation` to detect if using Reanimated 2 or 3.
/**
* @deprecated This function was superseded by other checks.
* We keep it here for backward compatibility reasons.
* If you need to check if you are using Reanimated 3 or Reanimated 2
* please use `isReanimated3` function instead.
* @returns `true` in Reanimated 3, doesn't exist in Reanimated 2
*/
export const isConfigured = isReanimated3;
// this is for web implementation
if (SHOULD_BE_USE_WEB) {
global._WORKLET = false;
global._log = console.log;
global._getAnimationTimestamp = () => performance.now();
}
export function getViewProp(viewTag, propName, component) {
if (isFabric() && !component) {
throw new Error('[Reanimated] Function `getViewProp` requires a component to be passed as an argument on Fabric.');
}
// eslint-disable-next-line @typescript-eslint/no-misused-promises
return new Promise((resolve, reject) => {
return NativeReanimatedModule.getViewProp(viewTag, propName, component, result => {
if (typeof result === 'string' && result.substr(0, 6) === 'error:') {
reject(result);
} else {
resolve(result);
}
});
});
}
function getSensorContainer() {
if (!global.__sensorContainer) {
global.__sensorContainer = new SensorContainer();
}
return global.__sensorContainer;
}
export function registerEventHandler(eventHandler, eventName, emitterReactTag = -1) {
function handleAndFlushAnimationFrame(eventTimestamp, event) {
'worklet';
global.__frameTimestamp = eventTimestamp;
eventHandler(event);
global.__flushAnimationFrame(eventTimestamp);
global.__frameTimestamp = undefined;
}
return NativeReanimatedModule.registerEventHandler(makeShareableCloneRecursive(handleAndFlushAnimationFrame), eventName, emitterReactTag);
}
export function unregisterEventHandler(id) {
return NativeReanimatedModule.unregisterEventHandler(id);
}
export function subscribeForKeyboardEvents(eventHandler, options) {
// TODO: this should really go with the same code path as other events, that is
// via registerEventHandler. For now we are copying the code from there.
function handleAndFlushAnimationFrame(state, height) {
'worklet';
const now = global._getAnimationTimestamp();
global.__frameTimestamp = now;
eventHandler(state, height);
global.__flushAnimationFrame(now);
global.__frameTimestamp = undefined;
}
return NativeReanimatedModule.subscribeForKeyboardEvents(makeShareableCloneRecursive(handleAndFlushAnimationFrame), options.isStatusBarTranslucentAndroid ?? false);
}
export function unsubscribeFromKeyboardEvents(listenerId) {
return NativeReanimatedModule.unsubscribeFromKeyboardEvents(listenerId);
}
export function registerSensor(sensorType, config, eventHandler) {
const sensorContainer = getSensorContainer();
return sensorContainer.registerSensor(sensorType, config, makeShareableCloneRecursive(eventHandler));
}
export function initializeSensor(sensorType, config) {
const sensorContainer = getSensorContainer();
return sensorContainer.initializeSensor(sensorType, config);
}
export function unregisterSensor(sensorId) {
const sensorContainer = getSensorContainer();
return sensorContainer.unregisterSensor(sensorId);
}
if (!isWeb()) {
initializeUIRuntime();
}
let featuresConfig = {
enableLayoutAnimations: false,
setByUser: false
};
export function enableLayoutAnimations(flag, isCallByUser = true) {
if (isCallByUser) {
featuresConfig = {
enableLayoutAnimations: flag,
setByUser: true
};
NativeReanimatedModule.enableLayoutAnimations(flag);
} else if (!featuresConfig.setByUser && featuresConfig.enableLayoutAnimations !== flag) {
featuresConfig.enableLayoutAnimations = flag;
NativeReanimatedModule.enableLayoutAnimations(flag);
}
}
export function configureLayoutAnimationBatch(layoutAnimationsBatch) {
NativeReanimatedModule.configureLayoutAnimationBatch(layoutAnimationsBatch);
}
export function setShouldAnimateExitingForTag(viewTag, shouldAnimate) {
NativeReanimatedModule.setShouldAnimateExitingForTag(viewTag, shouldAnimate);
}
export function jsiConfigureProps(uiProps, nativeProps) {
if (!SHOULD_BE_USE_WEB) {
NativeReanimatedModule.configureProps(uiProps, nativeProps);
}
}
//# sourceMappingURL=core.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,49 @@
'use strict';
const _workletStackDetails = new Map();
export function registerWorkletStackDetails(hash, stackDetails) {
_workletStackDetails.set(hash, stackDetails);
}
function getBundleOffset(error) {
var _error$stack;
const frame = (_error$stack = error.stack) === null || _error$stack === void 0 || (_error$stack = _error$stack.split('\n')) === null || _error$stack === void 0 ? void 0 : _error$stack[0];
if (frame) {
const parsedFrame = /@([^@]+):(\d+):(\d+)/.exec(frame);
if (parsedFrame) {
const [, file, line, col] = parsedFrame;
return [file, Number(line), Number(col)];
}
}
return ['unknown', 0, 0];
}
function processStack(stack) {
const workletStackEntries = stack.match(/worklet_(\d+):(\d+):(\d+)/g);
let result = stack;
workletStackEntries === null || workletStackEntries === void 0 || workletStackEntries.forEach(match => {
const [, hash, origLine, origCol] = match.split(/:|_/).map(Number);
const errorDetails = _workletStackDetails.get(hash);
if (!errorDetails) {
return;
}
const [error, lineOffset, colOffset] = errorDetails;
const [bundleFile, bundleLine, bundleCol] = getBundleOffset(error);
const line = origLine + bundleLine + lineOffset;
const col = origCol + bundleCol + colOffset;
result = result.replace(match, `${bundleFile}:${line}:${col}`);
});
return result;
}
export function reportFatalErrorOnJS({
message,
stack
}) {
const error = new Error();
error.message = message;
error.stack = stack ? processStack(stack) : undefined;
error.name = 'ReanimatedError';
// @ts-ignore React Native's ErrorUtils implementation extends the Error type with jsEngine field
error.jsEngine = 'reanimated';
// @ts-ignore the reportFatalError method is an internal method of ErrorUtils not exposed in the type definitions
global.ErrorUtils.reportFatalError(error);
}
//# sourceMappingURL=errors.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_workletStackDetails","Map","registerWorkletStackDetails","hash","stackDetails","set","getBundleOffset","error","_error$stack","frame","stack","split","parsedFrame","exec","file","line","col","Number","processStack","workletStackEntries","match","result","forEach","origLine","origCol","map","errorDetails","get","lineOffset","colOffset","bundleFile","bundleLine","bundleCol","replace","reportFatalErrorOnJS","message","Error","undefined","name","jsEngine","global","ErrorUtils","reportFatalError"],"sources":["errors.ts"],"sourcesContent":["'use strict';\nimport type { WorkletStackDetails } from './commonTypes';\n\nconst _workletStackDetails = new Map<number, WorkletStackDetails>();\n\nexport function registerWorkletStackDetails(\n hash: number,\n stackDetails: WorkletStackDetails\n) {\n _workletStackDetails.set(hash, stackDetails);\n}\n\nfunction getBundleOffset(error: Error): [string, number, number] {\n const frame = error.stack?.split('\\n')?.[0];\n if (frame) {\n const parsedFrame = /@([^@]+):(\\d+):(\\d+)/.exec(frame);\n if (parsedFrame) {\n const [, file, line, col] = parsedFrame;\n return [file, Number(line), Number(col)];\n }\n }\n return ['unknown', 0, 0];\n}\n\nfunction processStack(stack: string): string {\n const workletStackEntries = stack.match(/worklet_(\\d+):(\\d+):(\\d+)/g);\n let result = stack;\n workletStackEntries?.forEach((match) => {\n const [, hash, origLine, origCol] = match.split(/:|_/).map(Number);\n const errorDetails = _workletStackDetails.get(hash);\n if (!errorDetails) {\n return;\n }\n const [error, lineOffset, colOffset] = errorDetails;\n const [bundleFile, bundleLine, bundleCol] = getBundleOffset(error);\n const line = origLine + bundleLine + lineOffset;\n const col = origCol + bundleCol + colOffset;\n\n result = result.replace(match, `${bundleFile}:${line}:${col}`);\n });\n return result;\n}\n\nexport function reportFatalErrorOnJS({\n message,\n stack,\n}: {\n message: string;\n stack?: string;\n}) {\n const error = new Error();\n error.message = message;\n error.stack = stack ? processStack(stack) : undefined;\n error.name = 'ReanimatedError';\n // @ts-ignore React Native's ErrorUtils implementation extends the Error type with jsEngine field\n error.jsEngine = 'reanimated';\n // @ts-ignore the reportFatalError method is an internal method of ErrorUtils not exposed in the type definitions\n global.ErrorUtils.reportFatalError(error);\n}\n"],"mappings":"AAAA,YAAY;;AAGZ,MAAMA,oBAAoB,GAAG,IAAIC,GAAG,CAA8B,CAAC;AAEnE,OAAO,SAASC,2BAA2BA,CACzCC,IAAY,EACZC,YAAiC,EACjC;EACAJ,oBAAoB,CAACK,GAAG,CAACF,IAAI,EAAEC,YAAY,CAAC;AAC9C;AAEA,SAASE,eAAeA,CAACC,KAAY,EAA4B;EAAA,IAAAC,YAAA;EAC/D,MAAMC,KAAK,IAAAD,YAAA,GAAGD,KAAK,CAACG,KAAK,cAAAF,YAAA,gBAAAA,YAAA,GAAXA,YAAA,CAAaG,KAAK,CAAC,IAAI,CAAC,cAAAH,YAAA,uBAAxBA,YAAA,CAA2B,CAAC,CAAC;EAC3C,IAAIC,KAAK,EAAE;IACT,MAAMG,WAAW,GAAG,sBAAsB,CAACC,IAAI,CAACJ,KAAK,CAAC;IACtD,IAAIG,WAAW,EAAE;MACf,MAAM,GAAGE,IAAI,EAAEC,IAAI,EAAEC,GAAG,CAAC,GAAGJ,WAAW;MACvC,OAAO,CAACE,IAAI,EAAEG,MAAM,CAACF,IAAI,CAAC,EAAEE,MAAM,CAACD,GAAG,CAAC,CAAC;IAC1C;EACF;EACA,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;AAC1B;AAEA,SAASE,YAAYA,CAACR,KAAa,EAAU;EAC3C,MAAMS,mBAAmB,GAAGT,KAAK,CAACU,KAAK,CAAC,4BAA4B,CAAC;EACrE,IAAIC,MAAM,GAAGX,KAAK;EAClBS,mBAAmB,aAAnBA,mBAAmB,eAAnBA,mBAAmB,CAAEG,OAAO,CAAEF,KAAK,IAAK;IACtC,MAAM,GAAGjB,IAAI,EAAEoB,QAAQ,EAAEC,OAAO,CAAC,GAAGJ,KAAK,CAACT,KAAK,CAAC,KAAK,CAAC,CAACc,GAAG,CAACR,MAAM,CAAC;IAClE,MAAMS,YAAY,GAAG1B,oBAAoB,CAAC2B,GAAG,CAACxB,IAAI,CAAC;IACnD,IAAI,CAACuB,YAAY,EAAE;MACjB;IACF;IACA,MAAM,CAACnB,KAAK,EAAEqB,UAAU,EAAEC,SAAS,CAAC,GAAGH,YAAY;IACnD,MAAM,CAACI,UAAU,EAAEC,UAAU,EAAEC,SAAS,CAAC,GAAG1B,eAAe,CAACC,KAAK,CAAC;IAClE,MAAMQ,IAAI,GAAGQ,QAAQ,GAAGQ,UAAU,GAAGH,UAAU;IAC/C,MAAMZ,GAAG,GAAGQ,OAAO,GAAGQ,SAAS,GAAGH,SAAS;IAE3CR,MAAM,GAAGA,MAAM,CAACY,OAAO,CAACb,KAAK,EAAG,GAAEU,UAAW,IAAGf,IAAK,IAAGC,GAAI,EAAC,CAAC;EAChE,CAAC,CAAC;EACF,OAAOK,MAAM;AACf;AAEA,OAAO,SAASa,oBAAoBA,CAAC;EACnCC,OAAO;EACPzB;AAIF,CAAC,EAAE;EACD,MAAMH,KAAK,GAAG,IAAI6B,KAAK,CAAC,CAAC;EACzB7B,KAAK,CAAC4B,OAAO,GAAGA,OAAO;EACvB5B,KAAK,CAACG,KAAK,GAAGA,KAAK,GAAGQ,YAAY,CAACR,KAAK,CAAC,GAAG2B,SAAS;EACrD9B,KAAK,CAAC+B,IAAI,GAAG,iBAAiB;EAC9B;EACA/B,KAAK,CAACgC,QAAQ,GAAG,YAAY;EAC7B;EACAC,MAAM,CAACC,UAAU,CAACC,gBAAgB,CAACnC,KAAK,CAAC;AAC3C","ignoreList":[]}

View File

@@ -0,0 +1,43 @@
'use strict';
/* eslint-disable */
let findHostInstance_DEPRECATED;
let getInternalInstanceHandleFromPublicInstance;
export function getShadowNodeWrapperFromRef(ref) {
var _ref$getScrollRespond, _ref$getScrollRespond2, _ref$getNativeScrollR, _ref$__internalInstan;
// load findHostInstance_DEPRECATED lazily because it may not be available before render
if (findHostInstance_DEPRECATED === undefined) {
try {
findHostInstance_DEPRECATED = require('react-native/Libraries/Renderer/shims/ReactFabric').findHostInstance_DEPRECATED;
} catch (e) {
findHostInstance_DEPRECATED = _ref => null;
}
}
if (getInternalInstanceHandleFromPublicInstance === undefined) {
try {
getInternalInstanceHandleFromPublicInstance = require('react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance').getInternalInstanceHandleFromPublicInstance ?? (_ref => _ref._internalInstanceHandle);
} catch (e) {
getInternalInstanceHandleFromPublicInstance = _ref => _ref._internalInstanceHandle;
}
}
// taken from https://github.com/facebook/react-native/commit/803bb16531697233686efd475f004c1643e03617#diff-d8172256c6d63b5d32db10e54d7b10f37a26b337d5280d89f5bfd7bcea778292R196
// @ts-ignore some weird stuff on RN 0.74 - see examples with scrollView
const scrollViewRef = ref === null || ref === void 0 || (_ref$getScrollRespond = ref.getScrollResponder) === null || _ref$getScrollRespond === void 0 || (_ref$getScrollRespond = _ref$getScrollRespond.call(ref)) === null || _ref$getScrollRespond === void 0 || (_ref$getScrollRespond2 = _ref$getScrollRespond.getNativeScrollRef) === null || _ref$getScrollRespond2 === void 0 ? void 0 : _ref$getScrollRespond2.call(_ref$getScrollRespond);
// @ts-ignore some weird stuff on RN 0.74 - see examples with scrollView
const otherScrollViewRef = ref === null || ref === void 0 || (_ref$getNativeScrollR = ref.getNativeScrollRef) === null || _ref$getNativeScrollR === void 0 ? void 0 : _ref$getNativeScrollR.call(ref);
// @ts-ignore some weird stuff on RN 0.74 - see setNativeProps example
const textInputRef = ref === null || ref === void 0 || (_ref$__internalInstan = ref.__internalInstanceHandle) === null || _ref$__internalInstan === void 0 || (_ref$__internalInstan = _ref$__internalInstan.stateNode) === null || _ref$__internalInstan === void 0 ? void 0 : _ref$__internalInstan.node;
let resolvedRef;
if (scrollViewRef) {
resolvedRef = scrollViewRef.__internalInstanceHandle.stateNode.node;
} else if (otherScrollViewRef) {
resolvedRef = otherScrollViewRef.__internalInstanceHandle.stateNode.node;
} else if (textInputRef) {
resolvedRef = textInputRef;
} else {
resolvedRef = getInternalInstanceHandleFromPublicInstance(findHostInstance_DEPRECATED(ref)).stateNode.node;
}
return resolvedRef;
}
//# sourceMappingURL=fabricUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["findHostInstance_DEPRECATED","getInternalInstanceHandleFromPublicInstance","getShadowNodeWrapperFromRef","ref","_ref$getScrollRespond","_ref$getScrollRespond2","_ref$getNativeScrollR","_ref$__internalInstan","undefined","require","e","_ref","_internalInstanceHandle","scrollViewRef","getScrollResponder","call","getNativeScrollRef","otherScrollViewRef","textInputRef","__internalInstanceHandle","stateNode","node","resolvedRef"],"sources":["fabricUtils.ts"],"sourcesContent":["'use strict';\n/* eslint-disable */\n\nimport type { ShadowNodeWrapper } from './commonTypes';\n\nlet findHostInstance_DEPRECATED: (ref: unknown) => void;\nlet getInternalInstanceHandleFromPublicInstance: (ref: unknown) => {\n stateNode: { node: unknown };\n};\n\nexport function getShadowNodeWrapperFromRef(\n ref: React.Component\n): ShadowNodeWrapper {\n // load findHostInstance_DEPRECATED lazily because it may not be available before render\n if (findHostInstance_DEPRECATED === undefined) {\n try {\n findHostInstance_DEPRECATED =\n require('react-native/Libraries/Renderer/shims/ReactFabric').findHostInstance_DEPRECATED;\n } catch (e) {\n findHostInstance_DEPRECATED = (_ref: unknown) => null;\n }\n }\n\n if (getInternalInstanceHandleFromPublicInstance === undefined) {\n try {\n getInternalInstanceHandleFromPublicInstance =\n require('react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance')\n .getInternalInstanceHandleFromPublicInstance ??\n ((_ref: any) => _ref._internalInstanceHandle);\n } catch (e) {\n getInternalInstanceHandleFromPublicInstance = (_ref: any) =>\n _ref._internalInstanceHandle;\n }\n }\n\n // taken from https://github.com/facebook/react-native/commit/803bb16531697233686efd475f004c1643e03617#diff-d8172256c6d63b5d32db10e54d7b10f37a26b337d5280d89f5bfd7bcea778292R196\n // @ts-ignore some weird stuff on RN 0.74 - see examples with scrollView\n const scrollViewRef = ref?.getScrollResponder?.()?.getNativeScrollRef?.();\n // @ts-ignore some weird stuff on RN 0.74 - see examples with scrollView\n const otherScrollViewRef = ref?.getNativeScrollRef?.();\n // @ts-ignore some weird stuff on RN 0.74 - see setNativeProps example\n const textInputRef = ref?.__internalInstanceHandle?.stateNode?.node;\n\n let resolvedRef;\n if (scrollViewRef) {\n resolvedRef = scrollViewRef.__internalInstanceHandle.stateNode.node;\n } else if (otherScrollViewRef) {\n resolvedRef = otherScrollViewRef.__internalInstanceHandle.stateNode.node;\n } else if (textInputRef) {\n resolvedRef = textInputRef;\n } else {\n resolvedRef = getInternalInstanceHandleFromPublicInstance(\n findHostInstance_DEPRECATED(ref)\n ).stateNode.node;\n }\n\n return resolvedRef;\n}\n"],"mappings":"AAAA,YAAY;;AACZ;AAIA,IAAIA,2BAAmD;AACvD,IAAIC,2CAEH;AAED,OAAO,SAASC,2BAA2BA,CACzCC,GAAoB,EACD;EAAA,IAAAC,qBAAA,EAAAC,sBAAA,EAAAC,qBAAA,EAAAC,qBAAA;EACnB;EACA,IAAIP,2BAA2B,KAAKQ,SAAS,EAAE;IAC7C,IAAI;MACFR,2BAA2B,GACzBS,OAAO,CAAC,mDAAmD,CAAC,CAACT,2BAA2B;IAC5F,CAAC,CAAC,OAAOU,CAAC,EAAE;MACVV,2BAA2B,GAAIW,IAAa,IAAK,IAAI;IACvD;EACF;EAEA,IAAIV,2CAA2C,KAAKO,SAAS,EAAE;IAC7D,IAAI;MACFP,2CAA2C,GACzCQ,OAAO,CAAC,wFAAwF,CAAC,CAC9FR,2CAA2C,KAC5CU,IAAS,IAAKA,IAAI,CAACC,uBAAuB,CAAC;IACjD,CAAC,CAAC,OAAOF,CAAC,EAAE;MACVT,2CAA2C,GAAIU,IAAS,IACtDA,IAAI,CAACC,uBAAuB;IAChC;EACF;;EAEA;EACA;EACA,MAAMC,aAAa,GAAGV,GAAG,aAAHA,GAAG,gBAAAC,qBAAA,GAAHD,GAAG,CAAEW,kBAAkB,cAAAV,qBAAA,gBAAAA,qBAAA,GAAvBA,qBAAA,CAAAW,IAAA,CAAAZ,GAA0B,CAAC,cAAAC,qBAAA,gBAAAC,sBAAA,GAA3BD,qBAAA,CAA6BY,kBAAkB,cAAAX,sBAAA,uBAA/CA,sBAAA,CAAAU,IAAA,CAAAX,qBAAkD,CAAC;EACzE;EACA,MAAMa,kBAAkB,GAAGd,GAAG,aAAHA,GAAG,gBAAAG,qBAAA,GAAHH,GAAG,CAAEa,kBAAkB,cAAAV,qBAAA,uBAAvBA,qBAAA,CAAAS,IAAA,CAAAZ,GAA0B,CAAC;EACtD;EACA,MAAMe,YAAY,GAAGf,GAAG,aAAHA,GAAG,gBAAAI,qBAAA,GAAHJ,GAAG,CAAEgB,wBAAwB,cAAAZ,qBAAA,gBAAAA,qBAAA,GAA7BA,qBAAA,CAA+Ba,SAAS,cAAAb,qBAAA,uBAAxCA,qBAAA,CAA0Cc,IAAI;EAEnE,IAAIC,WAAW;EACf,IAAIT,aAAa,EAAE;IACjBS,WAAW,GAAGT,aAAa,CAACM,wBAAwB,CAACC,SAAS,CAACC,IAAI;EACrE,CAAC,MAAM,IAAIJ,kBAAkB,EAAE;IAC7BK,WAAW,GAAGL,kBAAkB,CAACE,wBAAwB,CAACC,SAAS,CAACC,IAAI;EAC1E,CAAC,MAAM,IAAIH,YAAY,EAAE;IACvBI,WAAW,GAAGJ,YAAY;EAC5B,CAAC,MAAM;IACLI,WAAW,GAAGrB,2CAA2C,CACvDD,2BAA2B,CAACG,GAAG,CACjC,CAAC,CAACiB,SAAS,CAACC,IAAI;EAClB;EAEA,OAAOC,WAAW;AACpB","ignoreList":[]}

View File

@@ -0,0 +1,6 @@
'use strict';
export function getShadowNodeWrapperFromRef() {
throw new Error('[Reanimated] Trying to call `getShadowNodeWrapperFromRef` on web.');
}
//# sourceMappingURL=fabricUtils.web.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["getShadowNodeWrapperFromRef","Error"],"sources":["fabricUtils.web.ts"],"sourcesContent":["'use strict';\nexport function getShadowNodeWrapperFromRef() {\n throw new Error(\n '[Reanimated] Trying to call `getShadowNodeWrapperFromRef` on web.'\n );\n}\n"],"mappings":"AAAA,YAAY;;AACZ,OAAO,SAASA,2BAA2BA,CAAA,EAAG;EAC5C,MAAM,IAAIC,KAAK,CACb,mEACF,CAAC;AACH","ignoreList":[]}

View File

@@ -0,0 +1,35 @@
'use strict';
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { runOnUI } from '../core';
import { prepareUIRegistry } from './FrameCallbackRegistryUI';
export default class FrameCallbackRegistryJS {
constructor() {
_defineProperty(this, "nextCallbackId", 0);
prepareUIRegistry();
}
registerFrameCallback(callback) {
if (!callback) {
return -1;
}
const callbackId = this.nextCallbackId;
this.nextCallbackId++;
runOnUI(() => {
global._frameCallbackRegistry.registerFrameCallback(callback, callbackId);
})();
return callbackId;
}
unregisterFrameCallback(callbackId) {
runOnUI(() => {
global._frameCallbackRegistry.unregisterFrameCallback(callbackId);
})();
}
manageStateFrameCallback(callbackId, state) {
runOnUI(() => {
global._frameCallbackRegistry.manageStateFrameCallback(callbackId, state);
})();
}
}
//# sourceMappingURL=FrameCallbackRegistryJS.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["_defineProperty","obj","key","value","_toPropertyKey","Object","defineProperty","enumerable","configurable","writable","t","i","_toPrimitive","r","e","Symbol","toPrimitive","call","TypeError","String","Number","runOnUI","prepareUIRegistry","FrameCallbackRegistryJS","constructor","registerFrameCallback","callback","callbackId","nextCallbackId","global","_frameCallbackRegistry","unregisterFrameCallback","manageStateFrameCallback","state"],"sources":["FrameCallbackRegistryJS.ts"],"sourcesContent":["'use strict';\nimport { runOnUI } from '../core';\nimport type { FrameInfo } from './FrameCallbackRegistryUI';\nimport { prepareUIRegistry } from './FrameCallbackRegistryUI';\n\nexport default class FrameCallbackRegistryJS {\n private nextCallbackId = 0;\n\n constructor() {\n prepareUIRegistry();\n }\n\n registerFrameCallback(callback: (frameInfo: FrameInfo) => void): number {\n if (!callback) {\n return -1;\n }\n\n const callbackId = this.nextCallbackId;\n this.nextCallbackId++;\n\n runOnUI(() => {\n global._frameCallbackRegistry.registerFrameCallback(callback, callbackId);\n })();\n\n return callbackId;\n }\n\n unregisterFrameCallback(callbackId: number): void {\n runOnUI(() => {\n global._frameCallbackRegistry.unregisterFrameCallback(callbackId);\n })();\n }\n\n manageStateFrameCallback(callbackId: number, state: boolean): void {\n runOnUI(() => {\n global._frameCallbackRegistry.manageStateFrameCallback(callbackId, state);\n })();\n }\n}\n"],"mappings":"AAAA,YAAY;;AAAC,SAAAA,gBAAAC,GAAA,EAAAC,GAAA,EAAAC,KAAA,IAAAD,GAAA,GAAAE,cAAA,CAAAF,GAAA,OAAAA,GAAA,IAAAD,GAAA,IAAAI,MAAA,CAAAC,cAAA,CAAAL,GAAA,EAAAC,GAAA,IAAAC,KAAA,EAAAA,KAAA,EAAAI,UAAA,QAAAC,YAAA,QAAAC,QAAA,oBAAAR,GAAA,CAAAC,GAAA,IAAAC,KAAA,WAAAF,GAAA;AAAA,SAAAG,eAAAM,CAAA,QAAAC,CAAA,GAAAC,YAAA,CAAAF,CAAA,uCAAAC,CAAA,GAAAA,CAAA,GAAAA,CAAA;AAAA,SAAAC,aAAAF,CAAA,EAAAG,CAAA,2BAAAH,CAAA,KAAAA,CAAA,SAAAA,CAAA,MAAAI,CAAA,GAAAJ,CAAA,CAAAK,MAAA,CAAAC,WAAA,kBAAAF,CAAA,QAAAH,CAAA,GAAAG,CAAA,CAAAG,IAAA,CAAAP,CAAA,EAAAG,CAAA,uCAAAF,CAAA,SAAAA,CAAA,YAAAO,SAAA,yEAAAL,CAAA,GAAAM,MAAA,GAAAC,MAAA,EAAAV,CAAA;AACb,SAASW,OAAO,QAAQ,SAAS;AAEjC,SAASC,iBAAiB,QAAQ,2BAA2B;AAE7D,eAAe,MAAMC,uBAAuB,CAAC;EAG3CC,WAAWA,CAAA,EAAG;IAAAxB,eAAA,yBAFW,CAAC;IAGxBsB,iBAAiB,CAAC,CAAC;EACrB;EAEAG,qBAAqBA,CAACC,QAAwC,EAAU;IACtE,IAAI,CAACA,QAAQ,EAAE;MACb,OAAO,CAAC,CAAC;IACX;IAEA,MAAMC,UAAU,GAAG,IAAI,CAACC,cAAc;IACtC,IAAI,CAACA,cAAc,EAAE;IAErBP,OAAO,CAAC,MAAM;MACZQ,MAAM,CAACC,sBAAsB,CAACL,qBAAqB,CAACC,QAAQ,EAAEC,UAAU,CAAC;IAC3E,CAAC,CAAC,CAAC,CAAC;IAEJ,OAAOA,UAAU;EACnB;EAEAI,uBAAuBA,CAACJ,UAAkB,EAAQ;IAChDN,OAAO,CAAC,MAAM;MACZQ,MAAM,CAACC,sBAAsB,CAACC,uBAAuB,CAACJ,UAAU,CAAC;IACnE,CAAC,CAAC,CAAC,CAAC;EACN;EAEAK,wBAAwBA,CAACL,UAAkB,EAAEM,KAAc,EAAQ;IACjEZ,OAAO,CAAC,MAAM;MACZQ,MAAM,CAACC,sBAAsB,CAACE,wBAAwB,CAACL,UAAU,EAAEM,KAAK,CAAC;IAC3E,CAAC,CAAC,CAAC,CAAC;EACN;AACF","ignoreList":[]}

View File

@@ -0,0 +1,87 @@
'use strict';
import { runOnUIImmediately } from '../threads';
export const prepareUIRegistry = runOnUIImmediately(() => {
'worklet';
const frameCallbackRegistry = {
frameCallbackRegistry: new Map(),
activeFrameCallbacks: new Set(),
previousFrameTimestamp: null,
nextCallId: 0,
runCallbacks(callId) {
const loop = timestamp => {
if (callId !== this.nextCallId) {
return;
}
if (this.previousFrameTimestamp === null) {
this.previousFrameTimestamp = timestamp;
}
const delta = timestamp - this.previousFrameTimestamp;
this.activeFrameCallbacks.forEach(callbackId => {
const callbackDetails = this.frameCallbackRegistry.get(callbackId);
const {
startTime
} = callbackDetails;
if (startTime === null) {
// First frame
callbackDetails.startTime = timestamp;
callbackDetails.callback({
timestamp,
timeSincePreviousFrame: null,
timeSinceFirstFrame: 0
});
} else {
// Next frame
callbackDetails.callback({
timestamp,
timeSincePreviousFrame: delta,
timeSinceFirstFrame: timestamp - startTime
});
}
});
if (this.activeFrameCallbacks.size > 0) {
this.previousFrameTimestamp = timestamp;
requestAnimationFrame(loop);
} else {
this.previousFrameTimestamp = null;
}
};
// runCallback() should only be called after registering a callback,
// so if there is only one active callback, then it means that there were
// zero previously and the loop isn't running yet.
if (this.activeFrameCallbacks.size === 1 && callId === this.nextCallId) {
requestAnimationFrame(loop);
}
},
registerFrameCallback(callback, callbackId) {
this.frameCallbackRegistry.set(callbackId, {
callback,
startTime: null
});
},
unregisterFrameCallback(callbackId) {
this.manageStateFrameCallback(callbackId, false);
this.frameCallbackRegistry.delete(callbackId);
},
manageStateFrameCallback(callbackId, state) {
if (callbackId === -1) {
return;
}
if (state) {
this.activeFrameCallbacks.add(callbackId);
this.runCallbacks(this.nextCallId);
} else {
const callback = this.frameCallbackRegistry.get(callbackId);
callback.startTime = null;
this.activeFrameCallbacks.delete(callbackId);
if (this.activeFrameCallbacks.size === 0) {
this.nextCallId += 1;
}
}
}
};
global._frameCallbackRegistry = frameCallbackRegistry;
});
//# sourceMappingURL=FrameCallbackRegistryUI.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
'use strict';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["'use strict';\nexport type { FrameInfo } from './FrameCallbackRegistryUI';\n"],"mappings":"AAAA,YAAY","ignoreList":[]}

View File

@@ -0,0 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-var */
'use strict';
export {};
//# sourceMappingURL=globals.d.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["globals.d.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-var */\n'use strict';\nimport type {\n StyleProps,\n MeasuredDimensions,\n MapperRegistry,\n ShareableRef,\n ShadowNodeWrapper,\n FlatShareableRef,\n} from './commonTypes';\nimport type { AnimatedStyle } from './helperTypes';\nimport type { FrameCallbackRegistryUI } from './frameCallback/FrameCallbackRegistryUI';\nimport type { NativeReanimatedModule } from './NativeReanimated/NativeReanimated';\nimport type { SensorContainer } from './SensorContainer';\nimport type { LayoutAnimationsManager } from './layoutReanimation/animationsManager';\nimport type { ProgressTransitionRegister } from './layoutReanimation/sharedTransitions';\nimport type { UpdatePropsManager } from './UpdateProps';\nimport type { callGuardDEV } from './initializers';\nimport type { WorkletRuntime } from './runtimes';\nimport type { RNScreensTurboModuleType } from './screenTransition/commonTypes';\n\ndeclare global {\n var _REANIMATED_IS_REDUCED_MOTION: boolean | undefined;\n var _IS_FABRIC: boolean | undefined;\n var _REANIMATED_VERSION_CPP: string | undefined;\n var _REANIMATED_VERSION_JS: string | undefined;\n var __reanimatedModuleProxy: NativeReanimatedModule | undefined;\n var __callGuardDEV: typeof callGuardDEV | undefined;\n var evalWithSourceMap:\n | ((js: string, sourceURL: string, sourceMap: string) => any)\n | undefined;\n var evalWithSourceUrl: ((js: string, sourceURL: string) => any) | undefined;\n var _log: (value: unknown) => void;\n var _toString: (value: unknown) => string;\n var _notifyAboutProgress: (\n tag: number,\n value: Record<string, unknown>,\n isSharedTransition: boolean\n ) => void;\n var _notifyAboutEnd: (tag: number, removeView: boolean) => void;\n var _setGestureState: (handlerTag: number, newState: number) => void;\n var _makeShareableClone: <T>(\n value: T,\n nativeStateSource?: object\n ) => FlatShareableRef<T>;\n var _scheduleOnJS: (fun: (...args: A) => R, args?: A) => void;\n var _scheduleOnRuntime: (\n runtime: WorkletRuntime,\n worklet: ShareableRef<() => void>\n ) => void;\n var _updatePropsPaper:\n | ((\n operations: {\n tag: number;\n name: string | null;\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n updates: StyleProps | AnimatedStyle<any>;\n }[]\n ) => void)\n | undefined;\n var _updatePropsFabric:\n | ((\n operations: {\n shadowNodeWrapper: ShadowNodeWrapper;\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n updates: StyleProps | AnimatedStyle<any>;\n }[]\n ) => void)\n | undefined;\n var _removeFromPropsRegistry: (viewTags: number[]) => void | undefined;\n var _measurePaper:\n | ((viewTag: number | null) => MeasuredDimensions)\n | undefined;\n var _measureFabric:\n | ((shadowNodeWrapper: ShadowNodeWrapper | null) => MeasuredDimensions)\n | undefined;\n var _scrollToPaper:\n | ((viewTag: number, x: number, y: number, animated: boolean) => void)\n | undefined;\n var _dispatchCommandPaper:\n | ((viewTag: number, commandName: string, args: Array<unknown>) => void)\n | undefined;\n var _dispatchCommandFabric:\n | ((\n shadowNodeWrapper: ShadowNodeWrapper,\n commandName: string,\n args: Array<unknown>\n ) => void)\n | undefined;\n var _getAnimationTimestamp: () => number;\n var __ErrorUtils: {\n reportFatalError: (error: Error) => void;\n };\n var _frameCallbackRegistry: FrameCallbackRegistryUI;\n var console: Console;\n var __frameTimestamp: number | undefined;\n var __flushAnimationFrame: (timestamp: number) => void;\n var __workletsCache: Map<string, any>;\n var __handleCache: WeakMap<object, any>;\n var __callMicrotasks: () => void;\n var __mapperRegistry: MapperRegistry;\n var __sensorContainer: SensorContainer;\n var _maybeFlushUIUpdatesQueue: () => void;\n var LayoutAnimationsManager: LayoutAnimationsManager;\n var UpdatePropsManager: UpdatePropsManager;\n var ProgressTransitionRegister: ProgressTransitionRegister;\n var updateJSProps: (viewTag: number, props: Record<string, unknown>) => void;\n var RNScreensTurboModule: RNScreensTurboModuleType | undefined;\n var _obtainPropPaper: (viewTag: number, propName: string) => string;\n var _obtainPropFabric: (\n shadowNodeWrapper: ShadowNodeWrapper,\n propName: string\n ) => string;\n}\n"],"mappings":"AAAA;AACA;AACA,YAAY;;AAAC","ignoreList":[]}

View File

@@ -0,0 +1,11 @@
'use strict';
/*
This file is a legacy remainder of manual types from react-native-reanimated.d.ts file.
I wasn't able to get rid of all of them from the code.
They should be treated as a temporary solution
until time comes to refactor the code and get necessary types right.
This will not be easy though!
*/
export {};
//# sourceMappingURL=helperTypes.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
'use strict';
export {};
//# sourceMappingURL=commonTypes.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["commonTypes.ts"],"sourcesContent":["'use strict';\nimport type { Component, MutableRefObject } from 'react';\nimport type {\n AnimatedPropsAdapterFunction,\n ShadowNodeWrapper,\n SharedValue,\n WorkletFunction,\n} from '../commonTypes';\nimport type {\n ImageStyle,\n NativeSyntheticEvent,\n TextStyle,\n ViewStyle,\n NativeScrollEvent,\n} from 'react-native';\nimport type { ViewDescriptorsSet, ViewRefSet } from '../ViewDescriptorsSet';\nimport type { AnimatedStyle } from '../helperTypes';\n\nexport type DependencyList = Array<unknown> | undefined;\n\nexport interface Descriptor {\n tag: number;\n name: string;\n shadowNodeWrapper: ShadowNodeWrapper;\n}\n\nexport interface AnimatedRef<T extends Component> {\n (component?: T):\n | number // Paper\n | ShadowNodeWrapper // Fabric\n | HTMLElement; // web\n current: T | null;\n getTag: () => number;\n}\n\n// Might make that type generic if it's ever needed.\nexport type AnimatedRefOnJS = AnimatedRef<Component>;\n\n/**\n * `AnimatedRef` is mapped to this type on the UI thread via a shareable handle.\n */\nexport type AnimatedRefOnUI = {\n (): number | ShadowNodeWrapper | null;\n /**\n * @remarks `viewName` is required only on iOS with Paper and it's value is null on other platforms.\n */\n viewName: SharedValue<string | null>;\n};\n\ntype ReanimatedPayload = {\n eventName: string;\n};\n\n/**\n * This utility type is to convert type of events that would normally be\n * sent by React Native (they have `nativeEvent` field) to the type\n * that is sent by Reanimated.\n */\nexport type ReanimatedEvent<Event extends object> = ReanimatedPayload &\n (Event extends {\n nativeEvent: infer NativeEvent extends object;\n }\n ? NativeEvent\n : Event);\n\nexport type EventPayload<Event extends object> = Event extends {\n nativeEvent: infer NativeEvent extends object;\n}\n ? NativeEvent\n : Omit<Event, 'eventName'>;\n\nexport type NativeEventWrapper<Event extends object> = {\n nativeEvent: Event;\n};\n\nexport type DefaultStyle = ViewStyle | ImageStyle | TextStyle;\n\nexport type RNNativeScrollEvent = NativeSyntheticEvent<NativeScrollEvent>;\n\nexport type ReanimatedScrollEvent = ReanimatedEvent<RNNativeScrollEvent>;\n\nexport interface IWorkletEventHandler<Event extends object> {\n updateEventHandler: (\n newWorklet: (event: ReanimatedEvent<Event>) => void,\n newEvents: string[]\n ) => void;\n registerForEvents: (viewTag: number, fallbackEventName?: string) => void;\n unregisterFromEvents: (viewTag: number) => void;\n}\n\nexport interface AnimatedStyleHandle<\n Style extends DefaultStyle = DefaultStyle\n> {\n viewDescriptors: ViewDescriptorsSet;\n initial: {\n value: AnimatedStyle<Style>;\n updater: () => AnimatedStyle<Style>;\n };\n /**\n * @remarks `viewsRef` is only defined in Web implementation.\n */\n viewsRef: ViewRefSet<unknown> | undefined;\n}\n\nexport interface JestAnimatedStyleHandle<\n Style extends DefaultStyle = DefaultStyle\n> extends AnimatedStyleHandle<Style> {\n jestAnimatedStyle: MutableRefObject<AnimatedStyle<Style>>;\n}\n\nexport type UseAnimatedStyleInternal<Style extends DefaultStyle> = (\n updater: WorkletFunction<[], Style> | (() => Style),\n dependencies?: DependencyList | null,\n adapters?:\n | AnimatedPropsAdapterFunction\n | AnimatedPropsAdapterFunction[]\n | null,\n isAnimatedProps?: boolean\n) => AnimatedStyleHandle<Style> | JestAnimatedStyleHandle<Style>;\n"],"mappings":"AAAA,YAAY;;AAAC","ignoreList":[]}

Some files were not shown because too many files have changed in this diff Show More