cineview 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +284 -0
- package/README.zh-CN.md +284 -0
- package/dist/animations/animationParser.d.ts +24 -0
- package/dist/animations/composer.d.ts +13 -0
- package/dist/animations/presets/blink.d.ts +18 -0
- package/dist/animations/presets/blur.d.ts +18 -0
- package/dist/animations/presets/bounce.d.ts +18 -0
- package/dist/animations/presets/elastic.d.ts +23 -0
- package/dist/animations/presets/fade.d.ts +18 -0
- package/dist/animations/presets/flip.d.ts +18 -0
- package/dist/animations/presets/index.d.ts +38 -0
- package/dist/animations/presets/rotate.d.ts +23 -0
- package/dist/animations/presets/shake.d.ts +28 -0
- package/dist/animations/presets/slide.d.ts +23 -0
- package/dist/animations/presets/special.d.ts +38 -0
- package/dist/animations/presets/zoom.d.ts +23 -0
- package/dist/animations/registry.d.ts +51 -0
- package/dist/artifacts.json +40 -0
- package/dist/blink-BGmsrTwW.mjs +81 -0
- package/dist/blur-CQoB_VWp.mjs +52 -0
- package/dist/bounce-B_QJxgOq.mjs +64 -0
- package/dist/cineview-dev.css +2 -0
- package/dist/cineview-dev.es.mjs +2 -0
- package/dist/cineview-drag.umd.js +2 -0
- package/dist/cineview-scroll.umd.js +2 -0
- package/dist/cineview.es.mjs +2 -0
- package/dist/cineview.umd.js +2 -0
- package/dist/components/Animate/Animate.d.ts +67 -0
- package/dist/components/Animate/AnimateRenderBridge.d.ts +16 -0
- package/dist/components/Animate/AnimateVideo.d.ts +59 -0
- package/dist/components/Animate/StaggerContainer.d.ts +35 -0
- package/dist/components/Animate/__fixtures__/animate-media-public-path.fixture.d.ts +1 -0
- package/dist/components/Animate/animateInterpolation.d.ts +41 -0
- package/dist/components/Animate/animateRenderState.d.ts +23 -0
- package/dist/components/Animate/animateSemantics.d.ts +39 -0
- package/dist/components/Animate/animateTimeline.d.ts +14 -0
- package/dist/components/Animate/dragVisualState.d.ts +26 -0
- package/dist/components/Animate/index.d.ts +6 -0
- package/dist/components/Animate/useAnimateArrival.d.ts +35 -0
- package/dist/components/Animate/useAnimateDrag.d.ts +34 -0
- package/dist/components/Animate/useAnimatePublicTimeline.d.ts +16 -0
- package/dist/components/Animate/useAnimateScroll.d.ts +83 -0
- package/dist/components/Animate/useAnimatedPropertyLanes.d.ts +30 -0
- package/dist/components/Animate/visibilityScheduler.d.ts +12 -0
- package/dist/components/CineView/CineView.d.ts +48 -0
- package/dist/components/CineView/CineViewDispatch.d.ts +2 -0
- package/dist/components/CineView/DirectScrollCineView.d.ts +5 -0
- package/dist/components/CineView/DragSceneStack.d.ts +55 -0
- package/dist/components/CineView/ScrollSceneSlot.d.ts +42 -0
- package/dist/components/CineView/ScrollSceneStack.d.ts +13 -0
- package/dist/components/CineView/ScrollbarOverlay.d.ts +24 -0
- package/dist/components/CineView/directScrollHelpers.d.ts +75 -0
- package/dist/components/CineView/index.d.ts +5 -0
- package/dist/components/CineView/preloadTargets.d.ts +18 -0
- package/dist/components/CineView/regroupCallbacks.d.ts +10 -0
- package/dist/components/CineView/useCineViewImperativeApi.d.ts +21 -0
- package/dist/components/CineView/useNativeScrollController.d.ts +38 -0
- package/dist/components/CineView/useScrollInputBindings.d.ts +9 -0
- package/dist/components/CineView/useScrollSceneLayout.d.ts +24 -0
- package/dist/components/CineView/useScrollSceneSnapshots.d.ts +32 -0
- package/dist/components/CineView/useScrollViewport.d.ts +20 -0
- package/dist/components/CineView/useScrollZoneRegistry.d.ts +34 -0
- package/dist/components/Container/Container.d.ts +2 -0
- package/dist/components/Container/index.d.ts +1 -0
- package/dist/components/Image/Image.d.ts +12 -0
- package/dist/components/Image/index.d.ts +2 -0
- package/dist/components/Position/Position.d.ts +13 -0
- package/dist/components/Position/index.d.ts +1 -0
- package/dist/components/Scene/Scene.d.ts +10 -0
- package/dist/components/Scene/SceneFixedLayer.d.ts +14 -0
- package/dist/components/Scene/__fixtures__/scene-grouped-public-path.fixture.d.ts +1 -0
- package/dist/components/Scene/dragPreparedState.d.ts +49 -0
- package/dist/components/Scene/helpers.d.ts +101 -0
- package/dist/components/Scene/index.d.ts +1 -0
- package/dist/components/Scene/sceneScrollBudget.d.ts +36 -0
- package/dist/components/Scene/sceneScrollRuntime.d.ts +66 -0
- package/dist/components/Scene/types.d.ts +189 -0
- package/dist/components/Scene/useDragSceneEngine.d.ts +67 -0
- package/dist/components/Scene/useElementTrack.d.ts +82 -0
- package/dist/components/Scene/useNativePointerDrag.d.ts +25 -0
- package/dist/components/Scene/useSceneAnimationRegistry.d.ts +56 -0
- package/dist/components/Scene/useScenePointerInput.d.ts +28 -0
- package/dist/components/Scene/useSceneRuntimeState.d.ts +17 -0
- package/dist/components/Scene/useSceneScrollTakeover.d.ts +14 -0
- package/dist/components/Scene/useScrollSceneEngine.d.ts +28 -0
- package/dist/components/runtime/runtimeContext.d.ts +14 -0
- package/dist/components/runtime/scrollExternalStore.d.ts +13 -0
- package/dist/components/runtime/scrollSceneFrameStore.d.ts +29 -0
- package/dist/context/CineViewContext.d.ts +25 -0
- package/dist/dev/PerfPanel.d.ts +16 -0
- package/dist/dev/index.d.ts +14 -0
- package/dist/dev/usePerfMonitor.d.ts +9 -0
- package/dist/drag-scene-engine-y8Wj9ivV.mjs +270 -0
- package/dist/elastic-CBP_FdRv.mjs +129 -0
- package/dist/element-track-Du10P12_.mjs +316 -0
- package/dist/entry-drag.d.ts +14 -0
- package/dist/entry-scroll.d.ts +14 -0
- package/dist/fade-DXxFsgxR.mjs +22 -0
- package/dist/flip-CrCoNIws.mjs +49 -0
- package/dist/hooks/imagePreloadCache.d.ts +4 -0
- package/dist/hooks/mediaPreloadCache.d.ts +31 -0
- package/dist/hooks/useFirstSceneEnter.d.ts +65 -0
- package/dist/hooks/useImagePreloader.d.ts +31 -0
- package/dist/hooks/usePrefersReducedMotion.d.ts +12 -0
- package/dist/hooks/useSceneManager.d.ts +78 -0
- package/dist/index.d.ts +17 -0
- package/dist/media/VideoFrameRenderer.d.ts +48 -0
- package/dist/media/videoPlaybackOwnership.d.ts +63 -0
- package/dist/performance-monitor-AlOOwzY_.mjs +73 -0
- package/dist/public-api.d.ts +12 -0
- package/dist/rotate-BMEBKDk5.mjs +69 -0
- package/dist/scene-animation-registry-8b0m_IaZ.mjs +422 -0
- package/dist/shake-BV6SdR9O.mjs +171 -0
- package/dist/slide-DWmVtj0L.mjs +63 -0
- package/dist/special-DDz8BopB.mjs +224 -0
- package/dist/types/index.d.ts +555 -0
- package/dist/utils/animationHelpers.d.ts +15 -0
- package/dist/utils/debounce.d.ts +18 -0
- package/dist/utils/devLog.d.ts +16 -0
- package/dist/utils/dragTimelineMapping.d.ts +30 -0
- package/dist/utils/gestureDetector.d.ts +67 -0
- package/dist/utils/performanceMonitor.d.ts +66 -0
- package/dist/utils/styleConvert.d.ts +7 -0
- package/dist/utils/useIsomorphicLayoutEffect.d.ts +22 -0
- package/dist/utils/useStructurallyStableValue.d.ts +5 -0
- package/dist/zoom-CuAthpqd.mjs +63 -0
- package/package.json +167 -0
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactElement, ReactNode } from 'react';
|
|
2
|
+
import { MotionValue } from 'framer-motion';
|
|
3
|
+
export type SlideDirection = 'x' | 'y';
|
|
4
|
+
export type ScrollMode = 'drag' | 'scroll';
|
|
5
|
+
/**
|
|
6
|
+
* Scene timeline phase for scroll-mode scenes. `hold` is the steady middle
|
|
7
|
+
* phase between enter and exit; it is NOT a virtual scroll-track coordinate.
|
|
8
|
+
*/
|
|
9
|
+
export type SceneTimelinePhase = 'before' | 'enter' | 'hold' | 'exit' | 'after';
|
|
10
|
+
export type SceneAnchor = 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
11
|
+
export type SceneStackMode = 'replace' | 'cover';
|
|
12
|
+
export interface DragThresholdConfig {
|
|
13
|
+
minVelocity?: number;
|
|
14
|
+
maxVelocity?: number;
|
|
15
|
+
minRatio?: number;
|
|
16
|
+
maxRatio?: number;
|
|
17
|
+
}
|
|
18
|
+
export type DragTimelineUnit = 'time' | 'percent';
|
|
19
|
+
export interface SceneDragConfig {
|
|
20
|
+
/** Whether this Scene may become the target of a user drag. Defaults to true. */
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
/** Drag-distance mapping unit. Defaults to `time`. */
|
|
23
|
+
unit?: DragTimelineUnit;
|
|
24
|
+
/**
|
|
25
|
+
* Per-drag-percent scale. `time` means milliseconds; `percent` means percent of
|
|
26
|
+
* this Scene's compiled element timeline. Defaults to 10 / 1 respectively.
|
|
27
|
+
*/
|
|
28
|
+
scale?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface DragModeConfig {
|
|
31
|
+
direction?: SlideDirection;
|
|
32
|
+
transitionDuration?: number;
|
|
33
|
+
threshold?: DragThresholdConfig;
|
|
34
|
+
/** Root default mapping unit for Scene element timelines. */
|
|
35
|
+
unit?: DragTimelineUnit;
|
|
36
|
+
/** Root default mapping scale; interpreted according to `unit`. */
|
|
37
|
+
scale?: number;
|
|
38
|
+
firstSceneTimeout?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface ScrollModeConfig {
|
|
41
|
+
direction?: SlideDirection;
|
|
42
|
+
zoneTrigger?: 'center-lock';
|
|
43
|
+
sceneSizing?: 'content' | 'screen';
|
|
44
|
+
/** Enable runtime parameter diagnostics for scroll layout and zone geometry. */
|
|
45
|
+
debug?: boolean;
|
|
46
|
+
enterMargin?: number;
|
|
47
|
+
exitMargin?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Accessibility configuration.
|
|
51
|
+
*
|
|
52
|
+
* Only one field exists because the other three accessibility behaviors have no
|
|
53
|
+
* configurable space: hiding inactive scenes from assistive technology, announcing
|
|
54
|
+
* scene changes via `aria-live`, and drag keyboard navigation are compliance
|
|
55
|
+
* requirements, not preferences. "Reduce motion" reads from system settings and
|
|
56
|
+
* similarly accepts no component-level override.
|
|
57
|
+
*/
|
|
58
|
+
export interface A11yConfig {
|
|
59
|
+
/**
|
|
60
|
+
* Accessible name for the drag root container (`aria-label`). Defaults to `'Scenes'`.
|
|
61
|
+
* When multiple CineView instances exist on one page, each must have a unique label
|
|
62
|
+
* so they can be distinguished in screen reader landmark lists.
|
|
63
|
+
*/
|
|
64
|
+
label?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface ScrollbarConfig {
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
ariaLabel?: string;
|
|
69
|
+
width?: number;
|
|
70
|
+
radius?: number;
|
|
71
|
+
inset?: number;
|
|
72
|
+
trackColor?: string;
|
|
73
|
+
thumbColor?: string;
|
|
74
|
+
thumbHoverColor?: string;
|
|
75
|
+
autoHide?: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface SceneChangeDetail {
|
|
78
|
+
fromIndex: number;
|
|
79
|
+
toIndex: number;
|
|
80
|
+
direction?: 'forward' | 'backward' | null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Error codes emitted by the framework at runtime. Consumers can switch on `code`
|
|
84
|
+
* in `onError` to get autocomplete and exhaustiveness checking (no longer a bare string).
|
|
85
|
+
*
|
|
86
|
+
* - `EMPTY_SCENES`: CineView has no Scene children (`context.scope` is default),
|
|
87
|
+
* or a Scene has no children (`context.scope === 'scene'`, includes `sceneIndex`).
|
|
88
|
+
* - `IMAGE_LOAD_FAILED`: Image preload failed.
|
|
89
|
+
* - `FIRST_SCENE_TIMEOUT`: First-screen priority resource wait timed out (recoverable, includes preventDefault).
|
|
90
|
+
* - `INVALID_ANIMATION`: Animate's after points to a nonexistent component.
|
|
91
|
+
* - `CIRCULAR_DEPENDENCY`: Animate's after chain contains a cycle.
|
|
92
|
+
* - `INVALID_COMPONENT_HIERARCHY`: Duplicate animateId or authored scroll zone identity in component tree.
|
|
93
|
+
* - `INVALID_DRAG_CONFIG`: Drag unit / scale / enabled config is invalid (recoverable).
|
|
94
|
+
* - `ANIMATION_ASSET_LOAD_FAILED`: Animation preset asset load failed (retryable).
|
|
95
|
+
*/
|
|
96
|
+
export type CineViewErrorCode = 'EMPTY_SCENES' | 'IMAGE_LOAD_FAILED' | 'FIRST_SCENE_TIMEOUT' | 'INVALID_ANIMATION' | 'CIRCULAR_DEPENDENCY' | 'INVALID_COMPONENT_HIERARCHY' | 'INVALID_DRAG_CONFIG' | 'ANIMATION_ASSET_LOAD_FAILED';
|
|
97
|
+
export interface CineViewErrorDetail {
|
|
98
|
+
code: CineViewErrorCode;
|
|
99
|
+
message: string;
|
|
100
|
+
context?: Record<string, unknown>;
|
|
101
|
+
preventDefault?: () => void;
|
|
102
|
+
}
|
|
103
|
+
export interface DragDetail {
|
|
104
|
+
sceneIndex: number;
|
|
105
|
+
progress: number;
|
|
106
|
+
direction?: 'forward' | 'backward' | null;
|
|
107
|
+
}
|
|
108
|
+
export interface DragStartDetail extends Omit<DragDetail, 'direction'> {
|
|
109
|
+
direction: 'forward' | 'backward';
|
|
110
|
+
}
|
|
111
|
+
export interface DragBlockedDetail {
|
|
112
|
+
fromIndex: number;
|
|
113
|
+
targetSceneIndex: number;
|
|
114
|
+
direction: 'forward' | 'backward';
|
|
115
|
+
}
|
|
116
|
+
export interface DragEndDetail extends DragDetail {
|
|
117
|
+
targetSceneIndex: number;
|
|
118
|
+
elapsedMs: number;
|
|
119
|
+
timelineDurationMs: number;
|
|
120
|
+
}
|
|
121
|
+
export interface ZoneDetail {
|
|
122
|
+
zoneId: string;
|
|
123
|
+
sceneIndex: number;
|
|
124
|
+
}
|
|
125
|
+
export interface ZoneProgressDetail extends ZoneDetail {
|
|
126
|
+
progress: number;
|
|
127
|
+
}
|
|
128
|
+
export interface SceneVisibilityDetail {
|
|
129
|
+
sceneIndex?: number;
|
|
130
|
+
visible: boolean;
|
|
131
|
+
progress: number;
|
|
132
|
+
}
|
|
133
|
+
export interface CineViewCommonCallbacks {
|
|
134
|
+
onReady?: (api: CineViewRef) => void;
|
|
135
|
+
onLoadProgress?: (progress: number) => void;
|
|
136
|
+
onSceneEnter?: (detail: SceneChangeDetail) => void;
|
|
137
|
+
onSceneLeave?: (detail: SceneChangeDetail) => void;
|
|
138
|
+
onError?: (detail: CineViewErrorDetail) => void;
|
|
139
|
+
}
|
|
140
|
+
export interface CineViewDragCallbacks {
|
|
141
|
+
/** Fires only after the first direction-qualified move acquires drag ownership. */
|
|
142
|
+
onDragStart?: (detail: DragStartDetail) => void;
|
|
143
|
+
onDragProgress?: (detail: DragDetail) => void;
|
|
144
|
+
onDragBlocked?: (detail: DragBlockedDetail) => void;
|
|
145
|
+
onDragEnd?: (detail: DragEndDetail) => void;
|
|
146
|
+
onDragCancel?: (detail: DragDetail) => void;
|
|
147
|
+
}
|
|
148
|
+
export interface CineViewScrollCallbacks {
|
|
149
|
+
onZoneEnter?: (detail: ZoneDetail) => void;
|
|
150
|
+
onZoneLeave?: (detail: ZoneDetail) => void;
|
|
151
|
+
onZoneProgress?: (detail: ZoneProgressDetail) => void;
|
|
152
|
+
onSceneVisibilityChange?: (detail: SceneVisibilityDetail) => void;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Flat callbacks accepted in drag mode (mode="drag" or omitted).
|
|
156
|
+
*
|
|
157
|
+
* The `[K in keyof CineViewScrollCallbacks]?: never` cross-exclusion closes a
|
|
158
|
+
* discrimination hole: without it, TS's excess-property check only rejects
|
|
159
|
+
* wrong-mode callbacks written as an INLINE object literal. A caller who first
|
|
160
|
+
* extracts callbacks into a variable that mixes a valid drag callback with a
|
|
161
|
+
* scroll-only one (e.g. `{ onDragEnd, onZoneProgress }`) would slip past the
|
|
162
|
+
* check, because a variable is not subject to excess-property checking and the
|
|
163
|
+
* weak-type check is satisfied by the shared valid key. Marking every scroll-only
|
|
164
|
+
* key as optional-`never` makes assigning a real function to it a type error on
|
|
165
|
+
* both the inline and the extracted-variable paths.
|
|
166
|
+
*/
|
|
167
|
+
export type DragModeCallbacks = CineViewCommonCallbacks & CineViewDragCallbacks & {
|
|
168
|
+
[K in keyof CineViewScrollCallbacks]?: never;
|
|
169
|
+
};
|
|
170
|
+
/** Flat callbacks accepted in scroll mode (mode="scroll"). Mirror cross-exclusion of drag-only keys — see DragModeCallbacks. */
|
|
171
|
+
export type ScrollModeCallbacks = CineViewCommonCallbacks & CineViewScrollCallbacks & {
|
|
172
|
+
[K in keyof CineViewDragCallbacks]?: never;
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Back-compat alias. The shape changed from the old nested
|
|
176
|
+
* `{ common, drag, scroll }` to the flat per-mode union, so this is a breaking
|
|
177
|
+
* change at the value level, but the NAME is preserved to avoid breaking
|
|
178
|
+
* type-only imports.
|
|
179
|
+
*/
|
|
180
|
+
export type CineViewCallbacks = DragModeCallbacks | ScrollModeCallbacks;
|
|
181
|
+
export type PresetAnimation = 'fade' | 'fade-in' | 'fade-out' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'zoom-in' | 'zoom-out' | 'scale-up' | 'scale-down' | 'rotate' | 'rotate-in' | 'rotate-out' | 'spin' | 'flip' | 'flip-x' | 'flip-y' | 'bounce' | 'bounce-in' | 'bounce-out' | 'blink' | 'flash' | 'pulse' | 'shake' | 'shake-x' | 'shake-y' | 'vibrate' | 'jello' | 'blur-in' | 'blur-out' | 'focus-in' | 'elastic' | 'rubber-band' | 'wobble' | 'swing' | 'heartbeat' | 'tada' | 'wave' | 'roll-in' | 'roll-out' | 'hinge' | 'jack-in-the-box';
|
|
182
|
+
export interface ParsedAnimationVariant {
|
|
183
|
+
initial: Record<string, unknown>;
|
|
184
|
+
animate: Record<string, unknown>;
|
|
185
|
+
exit: Record<string, unknown>;
|
|
186
|
+
}
|
|
187
|
+
export interface CustomAnimation {
|
|
188
|
+
initial?: Record<string, unknown>;
|
|
189
|
+
animate?: Record<string, unknown>;
|
|
190
|
+
exit?: Record<string, unknown>;
|
|
191
|
+
}
|
|
192
|
+
export interface ComposedAnimation {
|
|
193
|
+
animations: (PresetAnimation | CustomAnimation)[];
|
|
194
|
+
mode: 'sequential' | 'parallel';
|
|
195
|
+
delays?: number[];
|
|
196
|
+
}
|
|
197
|
+
export type AnimationType = PresetAnimation | CustomAnimation | ComposedAnimation;
|
|
198
|
+
/**
|
|
199
|
+
* Shared CineView props, independent of `mode`. Mode-specific fields are added
|
|
200
|
+
* by the per-mode branches below; the `mode`/`callbacks` pair closes the
|
|
201
|
+
* discriminated union so both the callback surface and the mode-specific config
|
|
202
|
+
* fields are constrained by the active mode.
|
|
203
|
+
*/
|
|
204
|
+
export interface CineViewBaseProps {
|
|
205
|
+
/**
|
|
206
|
+
* Design viewport width baseline (design px). The single site-wide conversion
|
|
207
|
+
* ruler: `scale = viewportWidth / designWidth`. All design lengths (Position
|
|
208
|
+
* coordinates, Container box model, etc.) are multiplied by the same `scale`
|
|
209
|
+
* (width-only, never distorted). Scroll takeover time budget is still settled
|
|
210
|
+
* at `1ms = 1px`; scene absolute spans fall back to measured DOM, without
|
|
211
|
+
* introducing a second height ruler.
|
|
212
|
+
*
|
|
213
|
+
* Aligns with common Figma / design file standards: set to the design file
|
|
214
|
+
* width (default 750, standard mobile viewport), then all design px values
|
|
215
|
+
* are scaled to any viewport from this baseline. No separate height baseline —
|
|
216
|
+
* vertical overflow is left to natural document flow / scroll extension.
|
|
217
|
+
*/
|
|
218
|
+
designWidth?: number;
|
|
219
|
+
scrollbar?: false | ScrollbarConfig;
|
|
220
|
+
monitor?: boolean;
|
|
221
|
+
a11y?: A11yConfig;
|
|
222
|
+
children: ReactNode;
|
|
223
|
+
}
|
|
224
|
+
/** Drag-branch-only config keys cannot appear on scroll root (and vice versa) — same cross-exclusion as callbacks. */
|
|
225
|
+
type ScrollOnlyConfigKeys = 'zoneTrigger' | 'sceneSizing' | 'enterMargin' | 'exitMargin' | 'debug';
|
|
226
|
+
type DragOnlyConfigKeys = 'transitionDuration' | 'threshold' | 'unit' | 'scale' | 'firstSceneTimeout';
|
|
227
|
+
/**
|
|
228
|
+
* CineView drag branch Props: `mode` defaults to drag. Mode-specific fields are
|
|
229
|
+
* flattened at root level (no `modes.drag` wrapper); scroll-specific fields are
|
|
230
|
+
* excluded as `never`.
|
|
231
|
+
*/
|
|
232
|
+
export type CineViewDragModeProps = CineViewBaseProps & DragModeConfig & {
|
|
233
|
+
mode?: 'drag';
|
|
234
|
+
callbacks?: DragModeCallbacks;
|
|
235
|
+
} & {
|
|
236
|
+
[K in ScrollOnlyConfigKeys]?: never;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* CineView scroll branch Props: scroll-specific fields are flattened at root
|
|
240
|
+
* level (no `modes.scroll` wrapper); drag-specific fields are excluded as `never`.
|
|
241
|
+
*/
|
|
242
|
+
export type CineViewScrollModeProps = CineViewBaseProps & ScrollModeConfig & {
|
|
243
|
+
mode: 'scroll';
|
|
244
|
+
callbacks?: ScrollModeCallbacks;
|
|
245
|
+
} & {
|
|
246
|
+
[K in DragOnlyConfigKeys]?: never;
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* CineView component Props — discriminated on `mode`. Drag mode (the default when
|
|
250
|
+
* `mode` is omitted) accepts common + drag callbacks and flat drag config
|
|
251
|
+
* fields; scroll mode accepts common + scroll callbacks and flat scroll config
|
|
252
|
+
* fields. Passing a callback or config field from the wrong mode is a type
|
|
253
|
+
* error (TS excess-property check on the flat objects).
|
|
254
|
+
*/
|
|
255
|
+
export type CineViewProps = CineViewDragModeProps | CineViewScrollModeProps;
|
|
256
|
+
/**
|
|
257
|
+
* Performance metrics for monitoring runtime behavior.
|
|
258
|
+
*/
|
|
259
|
+
export interface PerformanceMetrics {
|
|
260
|
+
fps: number;
|
|
261
|
+
avgFrameTime: number;
|
|
262
|
+
memoryUsage?: number;
|
|
263
|
+
bundleSize: number;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Scene asset preload target.
|
|
267
|
+
* - number: zero-based scene index
|
|
268
|
+
* - string: Scene.sceneId; in scroll mode it can also match Scene.scroll.zoneId
|
|
269
|
+
*/
|
|
270
|
+
export type CineViewPreloadTarget = number | string;
|
|
271
|
+
/**
|
|
272
|
+
* CineView Ref methods.
|
|
273
|
+
*
|
|
274
|
+
* These 5 methods exist in both drag and scroll modes, so they are required —
|
|
275
|
+
* call sites no longer need `ref.current?.refreshLayout?.()` per-method null checks.
|
|
276
|
+
* `goToZone` is scroll-mode-only (drag mode has no zone concept), so it remains optional;
|
|
277
|
+
* scroll consumers can switch to {@link CineViewScrollRef} for a view with `goToZone` required.
|
|
278
|
+
*/
|
|
279
|
+
export interface CineViewRef {
|
|
280
|
+
goToScene: (index: number, animated?: boolean) => void;
|
|
281
|
+
refreshLayout: () => void;
|
|
282
|
+
preload: (targets?: CineViewPreloadTarget[]) => Promise<void>;
|
|
283
|
+
getCurrentIndex: () => number;
|
|
284
|
+
getPerformanceMetrics: () => PerformanceMetrics;
|
|
285
|
+
/** Scroll mode only: jump to specified zone. Not available in drag mode. */
|
|
286
|
+
goToZone?: (zoneId: string, options?: {
|
|
287
|
+
align?: 'center';
|
|
288
|
+
animated?: boolean;
|
|
289
|
+
}) => void;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* CineView Ref in scroll mode — `goToZone` is required here.
|
|
293
|
+
* Usage: `const ref = useRef<CineViewScrollRef>(null)`, with `mode="scroll"`.
|
|
294
|
+
*/
|
|
295
|
+
export interface CineViewScrollRef extends CineViewRef {
|
|
296
|
+
goToZone: (zoneId: string, options?: {
|
|
297
|
+
align?: 'center';
|
|
298
|
+
animated?: boolean;
|
|
299
|
+
}) => void;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Scene component Props
|
|
303
|
+
*/
|
|
304
|
+
export interface SceneProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
305
|
+
sceneId?: string;
|
|
306
|
+
layout?: {
|
|
307
|
+
width?: number | string;
|
|
308
|
+
height?: number | string;
|
|
309
|
+
anchor?: SceneAnchor;
|
|
310
|
+
overflow?: 'hidden' | 'visible' | 'clip';
|
|
311
|
+
/**
|
|
312
|
+
* Stacking strategy (formerly `stack.mode`): which scene acts as background
|
|
313
|
+
* when this scene and adjacent scenes share the screen.
|
|
314
|
+
* Defaults to 'replace' in drag mode, 'cover' in scroll mode.
|
|
315
|
+
*/
|
|
316
|
+
overlap?: SceneStackMode;
|
|
317
|
+
/** Stacking z-order (formerly `stack.zIndex`). */
|
|
318
|
+
zIndex?: number;
|
|
319
|
+
};
|
|
320
|
+
transition?: {
|
|
321
|
+
enterAnimation?: AnimationType;
|
|
322
|
+
exitAnimation?: AnimationType;
|
|
323
|
+
exitDuration?: number;
|
|
324
|
+
};
|
|
325
|
+
assets?: {
|
|
326
|
+
preloadImages?: string[];
|
|
327
|
+
};
|
|
328
|
+
drag?: SceneDragConfig;
|
|
329
|
+
scroll?: {
|
|
330
|
+
zoneId?: string;
|
|
331
|
+
trigger?: 'center-lock';
|
|
332
|
+
};
|
|
333
|
+
callbacks?: {
|
|
334
|
+
onVisibilityChange?: (detail: SceneVisibilityDetail) => void;
|
|
335
|
+
};
|
|
336
|
+
children: ReactNode;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Animate component Props
|
|
340
|
+
*/
|
|
341
|
+
interface AnimateBaseProps {
|
|
342
|
+
animateId?: string;
|
|
343
|
+
exitAnimation?: AnimationType;
|
|
344
|
+
duration?: {
|
|
345
|
+
enter?: number;
|
|
346
|
+
exit?: number;
|
|
347
|
+
};
|
|
348
|
+
timeline?: {
|
|
349
|
+
/**
|
|
350
|
+
* Timeline driver. Defaults to `'scene'` (graceful inference):
|
|
351
|
+
*
|
|
352
|
+
* - **`'scene'` + inside a `Scene` with `scroll` takeover config (inherits zoneId)** → driven by
|
|
353
|
+
* that zone's real scroll budget (progressPx), works with `phase` (scroll takeover).
|
|
354
|
+
* - **`'scene'` + scroll mode but not inside a zone** → gracefully degrades to visibility gate,
|
|
355
|
+
* triggered by element entering/exiting viewport.
|
|
356
|
+
* - **`'scene'` + drag mode** → driven by Scene's shared element timeline.
|
|
357
|
+
* - **`'clock'` + scroll mode** → forces independent visibility gate, not taken over by zone even when inside one.
|
|
358
|
+
* - **`'clock'` + drag mode** → after Scene officially arrives, plays independently on real clock;
|
|
359
|
+
* does not participate in Scene registry, `after`, or `T_self`, and ignores `exitAnimation`.
|
|
360
|
+
*/
|
|
361
|
+
driver?: 'scene' | 'clock';
|
|
362
|
+
delay?: number;
|
|
363
|
+
/** Wait for a specific animateId to finish before entering. */
|
|
364
|
+
after?: string;
|
|
365
|
+
zoneId?: string;
|
|
366
|
+
phase?: {
|
|
367
|
+
start?: number;
|
|
368
|
+
end?: number;
|
|
369
|
+
};
|
|
370
|
+
};
|
|
371
|
+
visibility?: {
|
|
372
|
+
/** Whether to replay enter animation when element re-enters (formerly `replay`, defaults to true). */
|
|
373
|
+
replay?: boolean;
|
|
374
|
+
enterMargin?: number;
|
|
375
|
+
exitMargin?: number;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Exposes enter trigger function for manual enter timing control (e.g., show content
|
|
379
|
+
* immediately on async event success).
|
|
380
|
+
*
|
|
381
|
+
* **Behavior rules:**
|
|
382
|
+
* - **Calling `enterRef.current()`**: plays enter animation immediately, interrupting any pending `after`/`delay`.
|
|
383
|
+
* - **Passed `enterRef` + passed `timeline.after/delay`**: if user doesn't call ref, framework will
|
|
384
|
+
* **fallback trigger** enter after `after`/`delay` completes.
|
|
385
|
+
* - **Passed `enterRef`, but no `after/delay`**: never auto-triggers, must manually call `enterRef.current()` to enter.
|
|
386
|
+
*
|
|
387
|
+
* **Typical use:** Show content immediately on API success, rely on `delay` fallback on failure.
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```tsx
|
|
391
|
+
* const contentEnterRef = useRef<(() => void) | null>(null);
|
|
392
|
+
*
|
|
393
|
+
* useEffect(() => {
|
|
394
|
+
* fetch('/api/data')
|
|
395
|
+
* .then(data => {
|
|
396
|
+
* setContent(data);
|
|
397
|
+
* contentEnterRef.current?.(); // success → show immediately
|
|
398
|
+
* })
|
|
399
|
+
* .catch(() => {
|
|
400
|
+
* // failure → don't call ref, wait 3s fallback trigger
|
|
401
|
+
* });
|
|
402
|
+
* }, []);
|
|
403
|
+
*
|
|
404
|
+
* <Animate
|
|
405
|
+
* enterRef={contentEnterRef}
|
|
406
|
+
* timeline={{ delay: 3000 }} // fallback: show after 3s regardless
|
|
407
|
+
* enterAnimation="fade-in"
|
|
408
|
+
* >
|
|
409
|
+
* {content || <EmptyState />}
|
|
410
|
+
* </Animate>
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
enterRef?: React.MutableRefObject<(() => void) | null>;
|
|
414
|
+
/**
|
|
415
|
+
* Exposes exit trigger function for manual exit timing control.
|
|
416
|
+
*
|
|
417
|
+
* **Behavior rules:**
|
|
418
|
+
* - **Passed `exitRef`**: disables framework's auto-exit mechanism (scroll leaving zone / drag switching scene),
|
|
419
|
+
* must manually call `exitRef.current()` to exit.
|
|
420
|
+
* - **Calling `exitRef.current()`**: plays exit animation immediately, interrupting any pending enter (if any).
|
|
421
|
+
*
|
|
422
|
+
* **Note:** `exitRef` does not support `timeline.delay` fallback mechanism (exit has no "timeout then auto-exit" semantics).
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```tsx
|
|
426
|
+
* const modalExitRef = useRef<(() => void) | null>(null);
|
|
427
|
+
*
|
|
428
|
+
* <Animate
|
|
429
|
+
* exitRef={modalExitRef}
|
|
430
|
+
* enterAnimation="fade-in"
|
|
431
|
+
* exitAnimation="fade-out"
|
|
432
|
+
* >
|
|
433
|
+
* <Modal onClose={() => modalExitRef.current?.()} />
|
|
434
|
+
* </Animate>
|
|
435
|
+
* ```
|
|
436
|
+
*/
|
|
437
|
+
exitRef?: React.MutableRefObject<(() => void) | null>;
|
|
438
|
+
}
|
|
439
|
+
export interface AnimateStaggerConfig {
|
|
440
|
+
each?: number;
|
|
441
|
+
from?: 'first' | 'last' | 'center';
|
|
442
|
+
}
|
|
443
|
+
type EnterAnimationRequired = {
|
|
444
|
+
enterAnimation: AnimationType;
|
|
445
|
+
loopAnimation?: AnimationType;
|
|
446
|
+
};
|
|
447
|
+
type LoopOnly = {
|
|
448
|
+
enterAnimation?: never;
|
|
449
|
+
loopAnimation: AnimationType;
|
|
450
|
+
};
|
|
451
|
+
export type AnimateProps = (AnimateBaseProps & EnterAnimationRequired & {
|
|
452
|
+
/**
|
|
453
|
+
* Staggered enter choreography for child elements. When set, each **direct child**
|
|
454
|
+
* of `children` is revealed sequentially by framer's native `staggerChildren`,
|
|
455
|
+
* using `enterAnimation`'s variants (bypasses enter/exit's 10-property whitelist,
|
|
456
|
+
* can animate any framer-animatable property like `clipPath`/`width`).
|
|
457
|
+
*
|
|
458
|
+
* Time-driven, does not scrub with scroll/drag (for scrub-based per-element reveal,
|
|
459
|
+
* use render-prop `enterProgress` instead). Used for visibility enter: typewriter,
|
|
460
|
+
* list cascade, letter wave, etc.
|
|
461
|
+
*/
|
|
462
|
+
stagger: AnimateStaggerConfig;
|
|
463
|
+
children: ReactElement;
|
|
464
|
+
}) | (AnimateBaseProps & (EnterAnimationRequired | LoopOnly) & {
|
|
465
|
+
stagger?: never;
|
|
466
|
+
children: ReactNode | ((state: AnimateRenderState) => ReactNode);
|
|
467
|
+
});
|
|
468
|
+
/**
|
|
469
|
+
* Render-prop children receives animation state. Progress naturally follows
|
|
470
|
+
* current timeline source: visibility advances by time, scroll/drag scrubs
|
|
471
|
+
* with scroll/drag.
|
|
472
|
+
*/
|
|
473
|
+
export interface AnimateRenderState {
|
|
474
|
+
enterProgress: number;
|
|
475
|
+
phase: 'idle' | 'waiting' | 'entering' | 'entered' | 'exiting' | 'exited';
|
|
476
|
+
}
|
|
477
|
+
export type AnimatePhase = AnimateRenderState['phase'];
|
|
478
|
+
export type AnimateTimelineLane = 'drag' | 'scroll' | 'visibility';
|
|
479
|
+
export type AnimateTimelineSource = 'idle' | 'gesture' | 'continuation' | 'programmatic' | 'scroll' | 'visibility';
|
|
480
|
+
export interface AnimateTimelineFrame {
|
|
481
|
+
progress: number;
|
|
482
|
+
signedProgress: number;
|
|
483
|
+
phase: AnimatePhase;
|
|
484
|
+
source: AnimateTimelineSource;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Stable, read-only zero-render view of the nearest Animate timeline.
|
|
488
|
+
* MotionValue updates bypass React rendering; the object exposes no writer.
|
|
489
|
+
*/
|
|
490
|
+
export interface AnimateTimeline {
|
|
491
|
+
readonly mode: ScrollMode;
|
|
492
|
+
/** Public-side timeline.driver normalized to runtime lane ('drag' | 'scroll' | 'visibility'). */
|
|
493
|
+
readonly lane: AnimateTimelineLane;
|
|
494
|
+
readonly progress: MotionValue<number>;
|
|
495
|
+
readonly signedProgress: MotionValue<number>;
|
|
496
|
+
readonly phase: MotionValue<AnimatePhase>;
|
|
497
|
+
/** Atomic progress/phase/ownership snapshot for imperative consumers. */
|
|
498
|
+
readonly frame: MotionValue<AnimateTimelineFrame>;
|
|
499
|
+
}
|
|
500
|
+
export interface ScrollTimelineState {
|
|
501
|
+
phase: SceneTimelinePhase;
|
|
502
|
+
enterProgress: number;
|
|
503
|
+
exitProgress: number;
|
|
504
|
+
sceneProgress: number;
|
|
505
|
+
rangeStart: number;
|
|
506
|
+
rangeEnd: number;
|
|
507
|
+
rangeLength: number;
|
|
508
|
+
enterLength: number;
|
|
509
|
+
exitLength: number;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Position component Props
|
|
513
|
+
*/
|
|
514
|
+
export interface PositionProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'style' | 'className'> {
|
|
515
|
+
at?: {
|
|
516
|
+
x?: number;
|
|
517
|
+
y?: number;
|
|
518
|
+
offsetX?: number;
|
|
519
|
+
offsetY?: number;
|
|
520
|
+
/**
|
|
521
|
+
* Centering anchor. When set, element centers relative to viewport without
|
|
522
|
+
* manually writing `translate(-50%)`:
|
|
523
|
+
* - `'center'`: horizontal + vertical centering
|
|
524
|
+
* - `'center-x'`: horizontal centering only (`y` remains absolute design coordinate)
|
|
525
|
+
* - `'center-y'`: vertical centering only (`x` remains absolute design coordinate)
|
|
526
|
+
*
|
|
527
|
+
* After centering, `x` / `y` become "offset from center" (design px, converted via
|
|
528
|
+
* single-ruler `scale`): e.g. `anchor: 'center', x: 0, y: -100` means horizontally
|
|
529
|
+
* centered, vertically centered then moved up 100. The centered axis ignores
|
|
530
|
+
* `offsetX` / `offsetY` relative positioning chain.
|
|
531
|
+
*/
|
|
532
|
+
anchor?: 'center' | 'center-x' | 'center-y';
|
|
533
|
+
};
|
|
534
|
+
/** Scene-scoped fixed layer mount (former `layer: { fixed: true }` wrapper removed). */
|
|
535
|
+
fixed?: boolean;
|
|
536
|
+
children: ReactNode;
|
|
537
|
+
style?: React.CSSProperties;
|
|
538
|
+
className?: string;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Container component Props — px2vw box model conversion container.
|
|
542
|
+
* width/height and all length values inside style (padding/margin/gap/borderRadius/fontSize/...)
|
|
543
|
+
* are converted from design px via single-ruler `convert`.
|
|
544
|
+
*/
|
|
545
|
+
export interface ContainerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'style' | 'className'> {
|
|
546
|
+
width?: number;
|
|
547
|
+
height?: number;
|
|
548
|
+
children: ReactNode;
|
|
549
|
+
style?: React.CSSProperties;
|
|
550
|
+
className?: string;
|
|
551
|
+
}
|
|
552
|
+
export type GestureType = 'swipe-up' | 'swipe-down' | 'swipe-left' | 'swipe-right' | 'none';
|
|
553
|
+
export declare const DEFAULT_SLIDE_DURATION = 800;
|
|
554
|
+
export declare const DEFAULT_ANIMATION_DURATION = 600;
|
|
555
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CineViewErrorCode, ParsedAnimationVariant, CustomAnimation, ComposedAnimation } from '../types';
|
|
2
|
+
import { PresetAnimation } from '../animations/presets';
|
|
3
|
+
export interface AnimationParseFailure {
|
|
4
|
+
code: Extract<CineViewErrorCode, 'INVALID_ANIMATION' | 'ANIMATION_ASSET_LOAD_FAILED'>;
|
|
5
|
+
message: string;
|
|
6
|
+
context: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Parse animation with error handling
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseAnimationSafely(animation: string | CustomAnimation | ComposedAnimation | undefined, componentId: string, animationType: 'enter' | 'exit' | 'loop', onFailure?: (failure: AnimationParseFailure) => void): Promise<ParsedAnimationVariant | PresetAnimation | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Interpolate between two animation variants based on progress
|
|
14
|
+
*/
|
|
15
|
+
export declare function interpolateVariant(start: Record<string, unknown>, end: Record<string, unknown>, progress: number): Record<string, unknown>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debounce function
|
|
3
|
+
* Executes the function only after no further calls within the specified time
|
|
4
|
+
* @param fn - Function to debounce
|
|
5
|
+
* @param delay - Delay time in milliseconds
|
|
6
|
+
* @returns Debounced function
|
|
7
|
+
*/
|
|
8
|
+
export declare function debounce<T extends (...args: never[]) => unknown>(fn: T, delay: number): (...args: Parameters<T>) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Cancelable debounce function
|
|
11
|
+
* @param fn - Function to debounce
|
|
12
|
+
* @param delay - Delay time in milliseconds
|
|
13
|
+
* @returns Object containing the debounced function and cancel function
|
|
14
|
+
*/
|
|
15
|
+
export declare function debounceCancelable<T extends (...args: never[]) => unknown>(fn: T, delay: number): {
|
|
16
|
+
debounced: (...args: Parameters<T>) => void;
|
|
17
|
+
cancel: () => void;
|
|
18
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Development logging utility: outputs only when `NODE_ENV === 'development'`, silent in production.
|
|
3
|
+
*
|
|
4
|
+
* Background: the animations layer historically had raw `console.warn/error` calls scattered throughout
|
|
5
|
+
* (no NODE_ENV guard). While `esbuild.drop:['console']` removes console calls from production bundles,
|
|
6
|
+
* dev builds and SSR scenarios that depend on the library source still log. This utility centralizes
|
|
7
|
+
* the gate, aligning with existing guard patterns in context/Scene modules.
|
|
8
|
+
*
|
|
9
|
+
* Uniform prefix `[CineView]` for consistency with other developer-facing diagnostic messages.
|
|
10
|
+
*/
|
|
11
|
+
export declare function devWarn(...args: unknown[]): void;
|
|
12
|
+
export declare function devError(...args: unknown[]): void;
|
|
13
|
+
/** Cross-instance deduplicated devWarn: warns once per key across the entire session, replacing per-module once flags. */
|
|
14
|
+
export declare function devWarnOnce(key: string, ...args: unknown[]): void;
|
|
15
|
+
/** Cross-instance deduplicated devError: same semantics as devWarnOnce. */
|
|
16
|
+
export declare function devErrorOnce(key: string, ...args: unknown[]): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { DragModeConfig, DragTimelineUnit, SceneDragConfig } from '../types';
|
|
2
|
+
export declare const DEFAULT_DRAG_TIMELINE_UNIT: DragTimelineUnit;
|
|
3
|
+
export declare const DEFAULT_DRAG_TIMELINE_SCALE: {
|
|
4
|
+
readonly time: 10;
|
|
5
|
+
readonly percent: 1;
|
|
6
|
+
};
|
|
7
|
+
export declare const DEFAULT_DRAG_TIMELINE_CONFIG: ResolvedDragTimelineConfig;
|
|
8
|
+
export interface ResolvedDragTimelineConfig {
|
|
9
|
+
unit: DragTimelineUnit;
|
|
10
|
+
scale: number;
|
|
11
|
+
}
|
|
12
|
+
export type InvalidDragTimelineField = 'unit' | 'scale';
|
|
13
|
+
export interface InvalidDragTimelineConfig {
|
|
14
|
+
field: InvalidDragTimelineField;
|
|
15
|
+
value: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface ResolvedDragTimelineMapping extends ResolvedDragTimelineConfig {
|
|
18
|
+
msPerDragPercent: number;
|
|
19
|
+
map: (dragPercent: number) => number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolves the authored root/Scene mapping as one group. A Scene that provides
|
|
23
|
+
* either `unit` or `scale` stops inheriting the root mapping; its omitted field
|
|
24
|
+
* falls back to the framework default for the resolved unit.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveDragTimelineConfig(root: Pick<DragModeConfig, 'unit' | 'scale'> | undefined, scene?: SceneDragConfig, onInvalid?: (issue: InvalidDragTimelineConfig) => void): ResolvedDragTimelineConfig;
|
|
27
|
+
/** Allocation-free authoritative drag-percent → element-elapsed conversion. */
|
|
28
|
+
export declare function mapDragPercentToElapsed(config: ResolvedDragTimelineConfig, timelineDurationMs: number, dragPercent: number): number;
|
|
29
|
+
/** Creates the diagnostic/readable mapping object outside animation hot paths. */
|
|
30
|
+
export declare function createDragTimelineMapping(config: ResolvedDragTimelineConfig, timelineDurationMs: number): ResolvedDragTimelineMapping;
|