framer-motion 10.2.3 → 10.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/dom-entry.js +1 -1
- package/dist/cjs/index.js +18 -20
- package/dist/cjs/{wrap-27fda06a.js → wrap-62da7859.js} +456 -437
- package/dist/dom-entry.d.ts +485 -37
- package/dist/es/animation/GroupPlaybackControls.mjs +25 -0
- package/dist/es/animation/animate.mjs +2 -3
- package/dist/es/animation/create-instant-animation.mjs +13 -3
- package/dist/es/animation/generators/inertia.mjs +87 -0
- package/dist/es/animation/{legacy-popmotion → generators}/keyframes.mjs +8 -15
- package/dist/es/animation/{legacy-popmotion/find-spring.mjs → generators/spring/find.mjs} +6 -5
- package/dist/es/animation/generators/spring/index.mjs +129 -0
- package/dist/es/animation/generators/utils/velocity.mjs +9 -0
- package/dist/es/animation/index.mjs +2 -10
- package/dist/es/animation/js/driver-frameloop.mjs +12 -0
- package/dist/es/animation/js/index.mjs +206 -0
- package/dist/es/animation/optimized-appear/handoff.mjs +3 -1
- package/dist/es/animation/waapi/create-accelerated-animation.mjs +16 -10
- package/dist/es/frameloop/index.mjs +3 -4
- package/dist/es/gestures/pan/PanSession.mjs +2 -2
- package/dist/es/index.mjs +2 -3
- package/dist/es/render/utils/motion-values.mjs +1 -1
- package/dist/es/utils/time-conversion.mjs +2 -1
- package/dist/es/value/index.mjs +3 -3
- package/dist/es/value/use-spring.mjs +1 -1
- package/dist/es/value/use-velocity.mjs +4 -6
- package/dist/framer-motion.dev.js +475 -458
- package/dist/framer-motion.js +1 -1
- package/dist/index.d.ts +175 -218
- package/dist/projection.dev.js +5849 -5830
- package/dist/three-entry.d.ts +62 -63
- package/package.json +7 -11
- package/dist/es/animation/legacy-popmotion/decay.mjs +0 -34
- package/dist/es/animation/legacy-popmotion/index.mjs +0 -163
- package/dist/es/animation/legacy-popmotion/inertia.mjs +0 -90
- package/dist/es/animation/legacy-popmotion/spring.mjs +0 -143
- package/dist/es/frameloop/on-next-frame.mjs +0 -12
package/dist/dom-entry.d.ts
CHANGED
|
@@ -28,6 +28,176 @@ declare type Sync = {
|
|
|
28
28
|
[key in StepId]: Schedule;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Options for orchestrating the timing of animations.
|
|
33
|
+
*
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
interface Orchestration {
|
|
37
|
+
/**
|
|
38
|
+
* Delay the animation by this duration (in seconds). Defaults to `0`.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* ```javascript
|
|
42
|
+
* const transition = {
|
|
43
|
+
* delay: 0.2
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
delay?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Describes the relationship between the transition and its children. Set
|
|
52
|
+
* to `false` by default.
|
|
53
|
+
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* When using variants, the transition can be scheduled in relation to its
|
|
56
|
+
* children with either `"beforeChildren"` to finish this transition before
|
|
57
|
+
* starting children transitions, `"afterChildren"` to finish children
|
|
58
|
+
* transitions before starting this transition.
|
|
59
|
+
*
|
|
60
|
+
* ```jsx
|
|
61
|
+
* const list = {
|
|
62
|
+
* hidden: {
|
|
63
|
+
* opacity: 0,
|
|
64
|
+
* transition: { when: "afterChildren" }
|
|
65
|
+
* }
|
|
66
|
+
* }
|
|
67
|
+
*
|
|
68
|
+
* const item = {
|
|
69
|
+
* hidden: {
|
|
70
|
+
* opacity: 0,
|
|
71
|
+
* transition: { duration: 2 }
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
*
|
|
75
|
+
* return (
|
|
76
|
+
* <motion.ul variants={list} animate="hidden">
|
|
77
|
+
* <motion.li variants={item} />
|
|
78
|
+
* <motion.li variants={item} />
|
|
79
|
+
* </motion.ul>
|
|
80
|
+
* )
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
85
|
+
when?: false | "beforeChildren" | "afterChildren" | string;
|
|
86
|
+
/**
|
|
87
|
+
* When using variants, children animations will start after this duration
|
|
88
|
+
* (in seconds). You can add the `transition` property to both the `Frame` and the `variant` directly. Adding it to the `variant` generally offers more flexibility, as it allows you to customize the delay per visual state.
|
|
89
|
+
*
|
|
90
|
+
* ```jsx
|
|
91
|
+
* const container = {
|
|
92
|
+
* hidden: { opacity: 0 },
|
|
93
|
+
* show: {
|
|
94
|
+
* opacity: 1,
|
|
95
|
+
* transition: {
|
|
96
|
+
* delayChildren: 0.5
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
* }
|
|
100
|
+
*
|
|
101
|
+
* const item = {
|
|
102
|
+
* hidden: { opacity: 0 },
|
|
103
|
+
* show: { opacity: 1 }
|
|
104
|
+
* }
|
|
105
|
+
*
|
|
106
|
+
* return (
|
|
107
|
+
* <motion.ul
|
|
108
|
+
* variants={container}
|
|
109
|
+
* initial="hidden"
|
|
110
|
+
* animate="show"
|
|
111
|
+
* >
|
|
112
|
+
* <motion.li variants={item} />
|
|
113
|
+
* <motion.li variants={item} />
|
|
114
|
+
* </motion.ul>
|
|
115
|
+
* )
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @public
|
|
119
|
+
*/
|
|
120
|
+
delayChildren?: number;
|
|
121
|
+
/**
|
|
122
|
+
* When using variants, animations of child components can be staggered by this
|
|
123
|
+
* duration (in seconds).
|
|
124
|
+
*
|
|
125
|
+
* For instance, if `staggerChildren` is `0.01`, the first child will be
|
|
126
|
+
* delayed by `0` seconds, the second by `0.01`, the third by `0.02` and so
|
|
127
|
+
* on.
|
|
128
|
+
*
|
|
129
|
+
* The calculated stagger delay will be added to `delayChildren`.
|
|
130
|
+
*
|
|
131
|
+
* ```jsx
|
|
132
|
+
* const container = {
|
|
133
|
+
* hidden: { opacity: 0 },
|
|
134
|
+
* show: {
|
|
135
|
+
* opacity: 1,
|
|
136
|
+
* transition: {
|
|
137
|
+
* staggerChildren: 0.5
|
|
138
|
+
* }
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
141
|
+
*
|
|
142
|
+
* const item = {
|
|
143
|
+
* hidden: { opacity: 0 },
|
|
144
|
+
* show: { opacity: 1 }
|
|
145
|
+
* }
|
|
146
|
+
*
|
|
147
|
+
* return (
|
|
148
|
+
* <motion.ol
|
|
149
|
+
* variants={container}
|
|
150
|
+
* initial="hidden"
|
|
151
|
+
* animate="show"
|
|
152
|
+
* >
|
|
153
|
+
* <motion.li variants={item} />
|
|
154
|
+
* <motion.li variants={item} />
|
|
155
|
+
* </motion.ol>
|
|
156
|
+
* )
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* @public
|
|
160
|
+
*/
|
|
161
|
+
staggerChildren?: number;
|
|
162
|
+
/**
|
|
163
|
+
* The direction in which to stagger children.
|
|
164
|
+
*
|
|
165
|
+
* A value of `1` staggers from the first to the last while `-1`
|
|
166
|
+
* staggers from the last to the first.
|
|
167
|
+
*
|
|
168
|
+
* ```jsx
|
|
169
|
+
* const container = {
|
|
170
|
+
* hidden: { opacity: 0 },
|
|
171
|
+
* show: {
|
|
172
|
+
* opacity: 1,
|
|
173
|
+
* transition: {
|
|
174
|
+
* staggerChildren: 0.5,
|
|
175
|
+
* staggerDirection: -1
|
|
176
|
+
* }
|
|
177
|
+
* }
|
|
178
|
+
* }
|
|
179
|
+
*
|
|
180
|
+
* const item = {
|
|
181
|
+
* hidden: { opacity: 0 },
|
|
182
|
+
* show: { opacity: 1 }
|
|
183
|
+
* }
|
|
184
|
+
*
|
|
185
|
+
* return (
|
|
186
|
+
* <motion.ul
|
|
187
|
+
* variants={container}
|
|
188
|
+
* initial="hidden"
|
|
189
|
+
* animate="show"
|
|
190
|
+
* >
|
|
191
|
+
* <motion.li variants={item} size={50} />
|
|
192
|
+
* <motion.li variants={item} size={50} />
|
|
193
|
+
* </motion.ul>
|
|
194
|
+
* )
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* @public
|
|
198
|
+
*/
|
|
199
|
+
staggerDirection?: number;
|
|
200
|
+
}
|
|
31
201
|
interface Repeat {
|
|
32
202
|
/**
|
|
33
203
|
* The number of times to repeat the transition. Set to `Infinity` for perpetual repeating.
|
|
@@ -344,59 +514,298 @@ interface Spring extends Repeat {
|
|
|
344
514
|
*/
|
|
345
515
|
velocity?: number;
|
|
346
516
|
}
|
|
347
|
-
|
|
348
517
|
/**
|
|
518
|
+
* An animation that decelerates a value based on its initial velocity,
|
|
519
|
+
* usually used to implement inertial scrolling.
|
|
520
|
+
*
|
|
521
|
+
* Optionally, `min` and `max` boundaries can be defined, and inertia
|
|
522
|
+
* will snap to these with a spring animation.
|
|
523
|
+
*
|
|
524
|
+
* This animation will automatically precalculate a target value,
|
|
525
|
+
* which can be modified with the `modifyTarget` property.
|
|
526
|
+
*
|
|
527
|
+
* This allows you to add snap-to-grid or similar functionality.
|
|
528
|
+
*
|
|
529
|
+
* Inertia is also the animation used for `dragTransition`, and can be configured via that prop.
|
|
530
|
+
*
|
|
349
531
|
* @public
|
|
350
532
|
*/
|
|
351
|
-
interface
|
|
352
|
-
|
|
353
|
-
|
|
533
|
+
interface Inertia {
|
|
534
|
+
/**
|
|
535
|
+
* Set `type` to animate using the inertia animation. Set to `"tween"` by
|
|
536
|
+
* default. This can be used for natural deceleration, like momentum scrolling.
|
|
537
|
+
*
|
|
538
|
+
* ```jsx
|
|
539
|
+
* <motion.div
|
|
540
|
+
* animate={{ rotate: 180 }}
|
|
541
|
+
* transition={{ type: "inertia", velocity: 50 }}
|
|
542
|
+
* />
|
|
543
|
+
* ```
|
|
544
|
+
*
|
|
545
|
+
* @public
|
|
546
|
+
*/
|
|
547
|
+
type: "inertia";
|
|
548
|
+
/**
|
|
549
|
+
* A function that receives the automatically-calculated target and returns a new one. Useful for snapping the target to a grid.
|
|
550
|
+
*
|
|
551
|
+
* ```jsx
|
|
552
|
+
* <motion.div
|
|
553
|
+
* drag
|
|
554
|
+
* dragTransition={{
|
|
555
|
+
* power: 0,
|
|
556
|
+
* // Snap calculated target to nearest 50 pixels
|
|
557
|
+
* modifyTarget: target => Math.round(target / 50) * 50
|
|
558
|
+
* }}
|
|
559
|
+
* />
|
|
560
|
+
* ```
|
|
561
|
+
*
|
|
562
|
+
* @public
|
|
563
|
+
*/
|
|
564
|
+
modifyTarget?(v: number): number;
|
|
565
|
+
/**
|
|
566
|
+
* If `min` or `max` is set, this affects the stiffness of the bounce
|
|
567
|
+
* spring. Higher values will create more sudden movement. Set to `500` by
|
|
568
|
+
* default.
|
|
569
|
+
*
|
|
570
|
+
* ```jsx
|
|
571
|
+
* <motion.div
|
|
572
|
+
* drag
|
|
573
|
+
* dragTransition={{
|
|
574
|
+
* min: 0,
|
|
575
|
+
* max: 100,
|
|
576
|
+
* bounceStiffness: 100
|
|
577
|
+
* }}
|
|
578
|
+
* />
|
|
579
|
+
* ```
|
|
580
|
+
*
|
|
581
|
+
* @public
|
|
582
|
+
*/
|
|
583
|
+
bounceStiffness?: number;
|
|
584
|
+
/**
|
|
585
|
+
* If `min` or `max` is set, this affects the damping of the bounce spring.
|
|
586
|
+
* If set to `0`, spring will oscillate indefinitely. Set to `10` by
|
|
587
|
+
* default.
|
|
588
|
+
*
|
|
589
|
+
* ```jsx
|
|
590
|
+
* <motion.div
|
|
591
|
+
* drag
|
|
592
|
+
* dragTransition={{
|
|
593
|
+
* min: 0,
|
|
594
|
+
* max: 100,
|
|
595
|
+
* bounceDamping: 8
|
|
596
|
+
* }}
|
|
597
|
+
* />
|
|
598
|
+
* ```
|
|
599
|
+
*
|
|
600
|
+
* @public
|
|
601
|
+
*/
|
|
602
|
+
bounceDamping?: number;
|
|
603
|
+
/**
|
|
604
|
+
* A higher power value equals a further target. Set to `0.8` by default.
|
|
605
|
+
*
|
|
606
|
+
* ```jsx
|
|
607
|
+
* <motion.div
|
|
608
|
+
* drag
|
|
609
|
+
* dragTransition={{ power: 0.2 }}
|
|
610
|
+
* />
|
|
611
|
+
* ```
|
|
612
|
+
*
|
|
613
|
+
* @public
|
|
614
|
+
*/
|
|
615
|
+
power?: number;
|
|
616
|
+
/**
|
|
617
|
+
* Adjusting the time constant will change the duration of the
|
|
618
|
+
* deceleration, thereby affecting its feel. Set to `700` by default.
|
|
619
|
+
*
|
|
620
|
+
* ```jsx
|
|
621
|
+
* <motion.div
|
|
622
|
+
* drag
|
|
623
|
+
* dragTransition={{ timeConstant: 200 }}
|
|
624
|
+
* />
|
|
625
|
+
* ```
|
|
626
|
+
*
|
|
627
|
+
* @public
|
|
628
|
+
*/
|
|
629
|
+
timeConstant?: number;
|
|
630
|
+
/**
|
|
631
|
+
* End the animation if the distance to the animation target is below this value, and the absolute speed is below `restSpeed`.
|
|
632
|
+
* When the animation ends, the value gets snapped to the animation target. Set to `0.01` by default.
|
|
633
|
+
* Generally the default values provide smooth animation endings, only in rare cases should you need to customize these.
|
|
634
|
+
*
|
|
635
|
+
* ```jsx
|
|
636
|
+
* <motion.div
|
|
637
|
+
* drag
|
|
638
|
+
* dragTransition={{ restDelta: 10 }}
|
|
639
|
+
* />
|
|
640
|
+
* ```
|
|
641
|
+
*
|
|
642
|
+
* @public
|
|
643
|
+
*/
|
|
644
|
+
restDelta?: number;
|
|
645
|
+
/**
|
|
646
|
+
* Minimum constraint. If set, the value will "bump" against this value (or immediately spring to it if the animation starts as less than this value).
|
|
647
|
+
*
|
|
648
|
+
* ```jsx
|
|
649
|
+
* <motion.div
|
|
650
|
+
* drag
|
|
651
|
+
* dragTransition={{ min: 0, max: 100 }}
|
|
652
|
+
* />
|
|
653
|
+
* ```
|
|
654
|
+
*
|
|
655
|
+
* @public
|
|
656
|
+
*/
|
|
657
|
+
min?: number;
|
|
658
|
+
/**
|
|
659
|
+
* Maximum constraint. If set, the value will "bump" against this value (or immediately snap to it, if the initial animation value exceeds this value).
|
|
660
|
+
*
|
|
661
|
+
* ```jsx
|
|
662
|
+
* <motion.div
|
|
663
|
+
* drag
|
|
664
|
+
* dragTransition={{ min: 0, max: 100 }}
|
|
665
|
+
* />
|
|
666
|
+
* ```
|
|
667
|
+
*
|
|
668
|
+
* @public
|
|
669
|
+
*/
|
|
670
|
+
max?: number;
|
|
671
|
+
/**
|
|
672
|
+
* The value to animate from. By default, this is the current state of the animating value.
|
|
673
|
+
*
|
|
674
|
+
* ```jsx
|
|
675
|
+
* <Frame
|
|
676
|
+
* drag
|
|
677
|
+
* dragTransition={{ from: 50 }}
|
|
678
|
+
* />
|
|
679
|
+
* ```
|
|
680
|
+
*
|
|
681
|
+
* @public
|
|
682
|
+
*/
|
|
683
|
+
from?: number | string;
|
|
684
|
+
/**
|
|
685
|
+
* The initial velocity of the animation.
|
|
686
|
+
* By default this is the current velocity of the component.
|
|
687
|
+
*
|
|
688
|
+
* ```jsx
|
|
689
|
+
* <motion.div
|
|
690
|
+
* animate={{ rotate: 180 }}
|
|
691
|
+
* transition={{ type: 'inertia', velocity: 200 }}
|
|
692
|
+
* />
|
|
693
|
+
* ```
|
|
694
|
+
*
|
|
695
|
+
* @public
|
|
696
|
+
*/
|
|
697
|
+
velocity?: number;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Keyframes tweens between multiple `values`.
|
|
701
|
+
*
|
|
702
|
+
* These tweens can be arranged using the `duration`, `easings`, and `times` properties.
|
|
703
|
+
*/
|
|
704
|
+
interface Keyframes {
|
|
705
|
+
/**
|
|
706
|
+
* Set `type` to `"keyframes"` to animate using the keyframes animation.
|
|
707
|
+
* Set to `"tween"` by default. This can be used to animate between a series of values.
|
|
708
|
+
*
|
|
709
|
+
* @public
|
|
710
|
+
*/
|
|
711
|
+
type: "keyframes";
|
|
712
|
+
/**
|
|
713
|
+
* An array of numbers between 0 and 1, where `1` represents the `total` duration.
|
|
714
|
+
*
|
|
715
|
+
* Each value represents at which point during the animation each item in the animation target should be hit, so the array should be the same length as `values`.
|
|
716
|
+
*
|
|
717
|
+
* Defaults to an array of evenly-spread durations.
|
|
718
|
+
*
|
|
719
|
+
* @public
|
|
720
|
+
*/
|
|
721
|
+
times?: number[];
|
|
722
|
+
/**
|
|
723
|
+
* An array of easing functions for each generated tween, or a single easing function applied to all tweens.
|
|
724
|
+
*
|
|
725
|
+
* This array should be one item less than `values`, as these easings apply to the transitions *between* the `values`.
|
|
726
|
+
*
|
|
727
|
+
* ```jsx
|
|
728
|
+
* const transition = {
|
|
729
|
+
* backgroundColor: {
|
|
730
|
+
* type: 'keyframes',
|
|
731
|
+
* easings: ['circIn', 'circOut']
|
|
732
|
+
* }
|
|
733
|
+
* }
|
|
734
|
+
* ```
|
|
735
|
+
*
|
|
736
|
+
* @public
|
|
737
|
+
*/
|
|
738
|
+
ease?: Easing | Easing[];
|
|
739
|
+
/**
|
|
740
|
+
* The total duration of the animation. Set to `0.3` by default.
|
|
741
|
+
*
|
|
742
|
+
* ```jsx
|
|
743
|
+
* const transition = {
|
|
744
|
+
* type: "keyframes",
|
|
745
|
+
* duration: 2
|
|
746
|
+
* }
|
|
747
|
+
*
|
|
748
|
+
* <Frame
|
|
749
|
+
* animate={{ opacity: 0 }}
|
|
750
|
+
* transition={transition}
|
|
751
|
+
* />
|
|
752
|
+
* ```
|
|
753
|
+
*
|
|
754
|
+
* @public
|
|
755
|
+
*/
|
|
756
|
+
duration?: number;
|
|
757
|
+
/**
|
|
758
|
+
* @public
|
|
759
|
+
*/
|
|
760
|
+
repeatDelay?: number;
|
|
354
761
|
}
|
|
355
762
|
/**
|
|
356
763
|
* @public
|
|
357
764
|
*/
|
|
358
|
-
interface
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
onStop?: () => void;
|
|
765
|
+
interface Just {
|
|
766
|
+
/**
|
|
767
|
+
* @public
|
|
768
|
+
*/
|
|
769
|
+
type: "just";
|
|
364
770
|
}
|
|
365
771
|
/**
|
|
366
772
|
* @public
|
|
367
773
|
*/
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
774
|
+
interface None {
|
|
775
|
+
/**
|
|
776
|
+
* Set `type` to `false` for an instant transition.
|
|
777
|
+
*
|
|
778
|
+
* @public
|
|
779
|
+
*/
|
|
780
|
+
type: false;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* @public
|
|
784
|
+
*/
|
|
785
|
+
declare type PermissiveTransitionDefinition = {
|
|
786
|
+
[key: string]: any;
|
|
371
787
|
};
|
|
372
788
|
/**
|
|
373
|
-
*
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
*
|
|
381
|
-
* Returns `AnimationPlaybackControls`, currently just a `stop` method.
|
|
382
|
-
*
|
|
383
|
-
* ```javascript
|
|
384
|
-
* const x = useMotionValue(0)
|
|
385
|
-
*
|
|
386
|
-
* useEffect(() => {
|
|
387
|
-
* const controls = animate(x, 100, {
|
|
388
|
-
* type: "spring",
|
|
389
|
-
* stiffness: 2000,
|
|
390
|
-
* onComplete: v => {}
|
|
391
|
-
* })
|
|
392
|
-
*
|
|
393
|
-
* return controls.stop
|
|
394
|
-
* })
|
|
395
|
-
* ```
|
|
789
|
+
* @public
|
|
790
|
+
*/
|
|
791
|
+
declare type TransitionDefinition = Tween | Spring | Keyframes | Inertia | Just | None | PermissiveTransitionDefinition;
|
|
792
|
+
declare type TransitionMap = Orchestration & {
|
|
793
|
+
[key: string]: TransitionDefinition;
|
|
794
|
+
};
|
|
795
|
+
/**
|
|
796
|
+
* Transition props
|
|
396
797
|
*
|
|
397
798
|
* @public
|
|
398
799
|
*/
|
|
399
|
-
declare
|
|
800
|
+
declare type Transition = (Orchestration & Repeat & TransitionDefinition) | (Orchestration & Repeat & TransitionMap);
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* @public
|
|
804
|
+
*/
|
|
805
|
+
interface AnimationPlaybackControls {
|
|
806
|
+
currentTime: number;
|
|
807
|
+
stop: () => void;
|
|
808
|
+
}
|
|
400
809
|
|
|
401
810
|
/**
|
|
402
811
|
* @public
|
|
@@ -560,6 +969,45 @@ declare class MotionValue<V = any> {
|
|
|
560
969
|
}
|
|
561
970
|
declare function motionValue<V>(init: V, options?: MotionValueOptions): MotionValue<V>;
|
|
562
971
|
|
|
972
|
+
/**
|
|
973
|
+
* @public
|
|
974
|
+
*/
|
|
975
|
+
interface AnimationPlaybackLifecycles<V> {
|
|
976
|
+
onUpdate?: (latest: V) => void;
|
|
977
|
+
onPlay?: () => void;
|
|
978
|
+
onComplete?: () => void;
|
|
979
|
+
onRepeat?: () => void;
|
|
980
|
+
onStop?: () => void;
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* Animate a single value or a `MotionValue`.
|
|
984
|
+
*
|
|
985
|
+
* The first argument is either a `MotionValue` to animate, or an initial animation value.
|
|
986
|
+
*
|
|
987
|
+
* The second is either a value to animate to, or an array of keyframes to animate through.
|
|
988
|
+
*
|
|
989
|
+
* The third argument can be either tween or spring options, and optional lifecycle methods: `onUpdate`, `onPlay`, `onComplete`, `onRepeat` and `onStop`.
|
|
990
|
+
*
|
|
991
|
+
* Returns `AnimationPlaybackControls`, currently just a `stop` method.
|
|
992
|
+
*
|
|
993
|
+
* ```javascript
|
|
994
|
+
* const x = useMotionValue(0)
|
|
995
|
+
*
|
|
996
|
+
* useEffect(() => {
|
|
997
|
+
* const controls = animate(x, 100, {
|
|
998
|
+
* type: "spring",
|
|
999
|
+
* stiffness: 2000,
|
|
1000
|
+
* onComplete: v => {}
|
|
1001
|
+
* })
|
|
1002
|
+
*
|
|
1003
|
+
* return controls.stop
|
|
1004
|
+
* })
|
|
1005
|
+
* ```
|
|
1006
|
+
*
|
|
1007
|
+
* @public
|
|
1008
|
+
*/
|
|
1009
|
+
declare function animate<V>(from: MotionValue<V> | V, to: V | V[], transition?: Transition & AnimationPlaybackLifecycles<V>): AnimationPlaybackControls;
|
|
1010
|
+
|
|
563
1011
|
interface AxisScrollInfo {
|
|
564
1012
|
current: number;
|
|
565
1013
|
offset: number[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class GroupPlaybackControls {
|
|
2
|
+
constructor(animations) {
|
|
3
|
+
this.animations = animations.filter(Boolean);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* TODO: Filter out cancelled or stopped animations before returning
|
|
7
|
+
*/
|
|
8
|
+
get currentTime() {
|
|
9
|
+
return this.animations[0].currentTime;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* currentTime assignment could reasonably run every frame, so
|
|
13
|
+
* we iterate using a normal loop to avoid function creation.
|
|
14
|
+
*/
|
|
15
|
+
set currentTime(time) {
|
|
16
|
+
for (let i = 0; i < this.animations.length; i++) {
|
|
17
|
+
this.animations[i].currentTime = time;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
stop() {
|
|
21
|
+
this.animations.forEach((controls) => controls.stop());
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { GroupPlaybackControls };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createMotionValueAnimation } from './index.mjs';
|
|
2
2
|
import { motionValue } from '../value/index.mjs';
|
|
3
3
|
import { isMotionValue } from '../value/utils/is-motion-value.mjs';
|
|
4
|
+
import { GroupPlaybackControls } from './GroupPlaybackControls.mjs';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Animate a single value or a `MotionValue`.
|
|
@@ -32,9 +33,7 @@ import { isMotionValue } from '../value/utils/is-motion-value.mjs';
|
|
|
32
33
|
function animate(from, to, transition = {}) {
|
|
33
34
|
const value = isMotionValue(from) ? from : motionValue(from);
|
|
34
35
|
value.start(createMotionValueAnimation("", value, to, transition));
|
|
35
|
-
return
|
|
36
|
-
stop: () => value.stop(),
|
|
37
|
-
};
|
|
36
|
+
return value.animation || new GroupPlaybackControls([]);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
export { animate };
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { animateValue } from './js/index.mjs';
|
|
2
2
|
|
|
3
|
-
function createInstantAnimation({ keyframes,
|
|
3
|
+
function createInstantAnimation({ keyframes, delay: delayBy, onUpdate, onComplete, }) {
|
|
4
4
|
const setValue = () => {
|
|
5
5
|
onUpdate && onUpdate(keyframes[keyframes.length - 1]);
|
|
6
6
|
onComplete && onComplete();
|
|
7
|
+
return {
|
|
8
|
+
stop: () => { },
|
|
9
|
+
currentTime: 0,
|
|
10
|
+
};
|
|
7
11
|
};
|
|
8
|
-
return
|
|
12
|
+
return delayBy
|
|
13
|
+
? animateValue({
|
|
14
|
+
keyframes: [0, 1],
|
|
15
|
+
duration: delayBy,
|
|
16
|
+
onComplete: setValue,
|
|
17
|
+
})
|
|
18
|
+
: setValue();
|
|
9
19
|
}
|
|
10
20
|
|
|
11
21
|
export { createInstantAnimation };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { spring } from './spring/index.mjs';
|
|
2
|
+
import { calcGeneratorVelocity } from './utils/velocity.mjs';
|
|
3
|
+
|
|
4
|
+
function inertia({ keyframes, velocity = 0.0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed, }) {
|
|
5
|
+
const origin = keyframes[0];
|
|
6
|
+
const state = {
|
|
7
|
+
done: false,
|
|
8
|
+
value: origin,
|
|
9
|
+
};
|
|
10
|
+
const isOutOfBounds = (v) => (min !== undefined && v < min) || (max !== undefined && v > max);
|
|
11
|
+
const nearestBoundary = (v) => {
|
|
12
|
+
if (min === undefined)
|
|
13
|
+
return max;
|
|
14
|
+
if (max === undefined)
|
|
15
|
+
return min;
|
|
16
|
+
return Math.abs(min - v) < Math.abs(max - v) ? min : max;
|
|
17
|
+
};
|
|
18
|
+
let amplitude = power * velocity;
|
|
19
|
+
const ideal = origin + amplitude;
|
|
20
|
+
const target = modifyTarget === undefined ? ideal : modifyTarget(ideal);
|
|
21
|
+
/**
|
|
22
|
+
* If the target has changed we need to re-calculate the amplitude, otherwise
|
|
23
|
+
* the animation will start from the wrong position.
|
|
24
|
+
*/
|
|
25
|
+
if (target !== ideal)
|
|
26
|
+
amplitude = target - origin;
|
|
27
|
+
const calcDelta = (t) => -amplitude * Math.exp(-t / timeConstant);
|
|
28
|
+
const calcLatest = (t) => target + calcDelta(t);
|
|
29
|
+
const applyFriction = (t) => {
|
|
30
|
+
const delta = calcDelta(t);
|
|
31
|
+
const latest = calcLatest(t);
|
|
32
|
+
state.done = Math.abs(delta) <= restDelta;
|
|
33
|
+
state.value = state.done ? target : latest;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Ideally this would resolve for t in a stateless way, we could
|
|
37
|
+
* do that by always precalculating the animation but as we know
|
|
38
|
+
* this will be done anyway we can assume that spring will
|
|
39
|
+
* be discovered during that.
|
|
40
|
+
*/
|
|
41
|
+
let timeReachedBoundary;
|
|
42
|
+
let spring$1;
|
|
43
|
+
const checkCatchBoundary = (t) => {
|
|
44
|
+
if (!isOutOfBounds(state.value))
|
|
45
|
+
return;
|
|
46
|
+
timeReachedBoundary = t;
|
|
47
|
+
spring$1 = spring({
|
|
48
|
+
keyframes: [state.value, nearestBoundary(state.value)],
|
|
49
|
+
velocity: calcGeneratorVelocity(calcLatest, t, state.value),
|
|
50
|
+
damping: bounceDamping,
|
|
51
|
+
stiffness: bounceStiffness,
|
|
52
|
+
restDelta,
|
|
53
|
+
restSpeed,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
checkCatchBoundary(0);
|
|
57
|
+
return {
|
|
58
|
+
calculatedDuration: null,
|
|
59
|
+
next: (t) => {
|
|
60
|
+
/**
|
|
61
|
+
* We need to resolve the friction to figure out if we need a
|
|
62
|
+
* spring but we don't want to do this twice per frame. So here
|
|
63
|
+
* we flag if we updated for this frame and later if we did
|
|
64
|
+
* we can skip doing it again.
|
|
65
|
+
*/
|
|
66
|
+
let hasUpdatedFrame = false;
|
|
67
|
+
if (!spring$1 && timeReachedBoundary === undefined) {
|
|
68
|
+
hasUpdatedFrame = true;
|
|
69
|
+
applyFriction(t);
|
|
70
|
+
checkCatchBoundary(t);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* If we have a spring and the provided t is beyond the moment the friction
|
|
74
|
+
* animation crossed the min/max boundary, use the spring.
|
|
75
|
+
*/
|
|
76
|
+
if (timeReachedBoundary !== undefined && t > timeReachedBoundary) {
|
|
77
|
+
return spring$1.next(t - timeReachedBoundary);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
!hasUpdatedFrame && applyFriction(t);
|
|
81
|
+
return state;
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { inertia };
|