@wix/interact 1.93.0 → 2.0.0-rc.2

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.
Files changed (179) hide show
  1. package/dist/cjs/index.js +2 -23
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/react.js +15 -0
  4. package/dist/cjs/react.js.map +1 -0
  5. package/dist/cjs/web.js +2 -0
  6. package/dist/cjs/web.js.map +1 -0
  7. package/dist/es/index.js +8 -0
  8. package/dist/es/index.js.map +1 -0
  9. package/dist/es/react.js +650 -0
  10. package/dist/es/react.js.map +1 -0
  11. package/dist/es/web.js +56 -0
  12. package/dist/es/web.js.map +1 -0
  13. package/dist/index-C8QxOkui.mjs +7940 -0
  14. package/dist/index-C8QxOkui.mjs.map +1 -0
  15. package/dist/index-DEPRHaUt.js +18 -0
  16. package/dist/index-DEPRHaUt.js.map +1 -0
  17. package/dist/tsconfig.build.tsbuildinfo +1 -0
  18. package/dist/types/core/Interact.d.ts +17 -7
  19. package/dist/types/core/Interact.d.ts.map +1 -0
  20. package/dist/types/core/InteractionController.d.ts +19 -0
  21. package/dist/types/core/InteractionController.d.ts.map +1 -0
  22. package/dist/types/core/add.d.ts +4 -3
  23. package/dist/types/core/add.d.ts.map +1 -0
  24. package/dist/types/core/css.d.ts +3 -0
  25. package/dist/types/core/css.d.ts.map +1 -0
  26. package/dist/types/core/remove.d.ts +3 -1
  27. package/dist/types/core/remove.d.ts.map +1 -0
  28. package/dist/types/core/utilities.d.ts +1 -0
  29. package/dist/types/core/utilities.d.ts.map +1 -0
  30. package/dist/types/dom/api.d.ts +3 -0
  31. package/dist/types/dom/api.d.ts.map +1 -0
  32. package/dist/types/handlers/animationEnd.d.ts +3 -2
  33. package/dist/types/handlers/animationEnd.d.ts.map +1 -0
  34. package/dist/types/handlers/click.d.ts +3 -2
  35. package/dist/types/handlers/click.d.ts.map +1 -0
  36. package/dist/types/handlers/hover.d.ts +3 -2
  37. package/dist/types/handlers/hover.d.ts.map +1 -0
  38. package/dist/types/handlers/index.d.ts +1 -0
  39. package/dist/types/handlers/index.d.ts.map +1 -0
  40. package/dist/types/handlers/pointerMove.d.ts +3 -2
  41. package/dist/types/handlers/pointerMove.d.ts.map +1 -0
  42. package/dist/types/handlers/utilities.d.ts +1 -0
  43. package/dist/types/handlers/utilities.d.ts.map +1 -0
  44. package/dist/types/handlers/viewEnter.d.ts +3 -2
  45. package/dist/types/handlers/viewEnter.d.ts.map +1 -0
  46. package/dist/types/handlers/viewProgress.d.ts +4 -3
  47. package/dist/types/handlers/viewProgress.d.ts.map +1 -0
  48. package/dist/types/index.d.ts +3 -2
  49. package/dist/types/index.d.ts.map +1 -0
  50. package/dist/types/react/Interaction.d.ts +10 -0
  51. package/dist/types/react/Interaction.d.ts.map +1 -0
  52. package/dist/types/react/index.d.ts +8 -0
  53. package/dist/types/react/index.d.ts.map +1 -0
  54. package/dist/types/react/interactRef.d.ts +3 -0
  55. package/dist/types/react/interactRef.d.ts.map +1 -0
  56. package/dist/types/types.d.ts +23 -10
  57. package/dist/types/types.d.ts.map +1 -0
  58. package/dist/types/utils.d.ts +2 -1
  59. package/dist/types/utils.d.ts.map +1 -0
  60. package/dist/types/{InteractElement.d.ts → web/InteractElement.d.ts} +115 -77
  61. package/dist/types/web/InteractElement.d.ts.map +1 -0
  62. package/dist/types/web/defineInteractElement.d.ts +2 -0
  63. package/dist/types/web/defineInteractElement.d.ts.map +1 -0
  64. package/dist/types/web/index.d.ts +6 -0
  65. package/dist/types/web/index.d.ts.map +1 -0
  66. package/docs/README.md +211 -0
  67. package/docs/advanced/README.md +164 -0
  68. package/docs/api/README.md +157 -0
  69. package/docs/api/element-selection.md +607 -0
  70. package/docs/api/functions.md +638 -0
  71. package/docs/api/interact-class.md +663 -0
  72. package/docs/api/interact-element.md +565 -0
  73. package/docs/api/interaction-controller.md +450 -0
  74. package/docs/api/types.md +957 -0
  75. package/docs/examples/README.md +212 -0
  76. package/docs/examples/click-interactions.md +977 -0
  77. package/docs/examples/entrance-animations.md +935 -0
  78. package/docs/examples/hover-effects.md +930 -0
  79. package/docs/examples/list-patterns.md +737 -0
  80. package/docs/guides/README.md +49 -0
  81. package/docs/guides/conditions-and-media-queries.md +1068 -0
  82. package/docs/guides/configuration-structure.md +726 -0
  83. package/docs/guides/custom-elements.md +327 -0
  84. package/docs/guides/effects-and-animations.md +634 -0
  85. package/docs/guides/getting-started.md +379 -0
  86. package/docs/guides/lists-and-dynamic-content.md +713 -0
  87. package/docs/guides/state-management.md +747 -0
  88. package/docs/guides/understanding-triggers.md +690 -0
  89. package/docs/integration/README.md +264 -0
  90. package/docs/integration/react.md +605 -0
  91. package/package.json +73 -56
  92. package/rules/Integration.md +255 -0
  93. package/rules/click-rules.md +533 -0
  94. package/rules/full-lean.md +346 -0
  95. package/rules/hover-rules.md +593 -0
  96. package/rules/pointermove-rules.md +1341 -0
  97. package/rules/scroll-list-rules.md +900 -0
  98. package/rules/viewenter-rules.md +1015 -0
  99. package/rules/viewprogress-rules.md +1044 -0
  100. package/dist/cjs/InteractElement.js +0 -163
  101. package/dist/cjs/InteractElement.js.map +0 -1
  102. package/dist/cjs/__tests__/interact.spec.js +0 -2094
  103. package/dist/cjs/__tests__/interact.spec.js.map +0 -1
  104. package/dist/cjs/__tests__/viewEnter.spec.js +0 -207
  105. package/dist/cjs/__tests__/viewEnter.spec.js.map +0 -1
  106. package/dist/cjs/core/Interact.js +0 -257
  107. package/dist/cjs/core/Interact.js.map +0 -1
  108. package/dist/cjs/core/add.js +0 -250
  109. package/dist/cjs/core/add.js.map +0 -1
  110. package/dist/cjs/core/remove.js +0 -35
  111. package/dist/cjs/core/remove.js.map +0 -1
  112. package/dist/cjs/core/utilities.js +0 -16
  113. package/dist/cjs/core/utilities.js.map +0 -1
  114. package/dist/cjs/external-types.d.js +0 -2
  115. package/dist/cjs/external-types.d.js.map +0 -1
  116. package/dist/cjs/handlers/animationEnd.js +0 -37
  117. package/dist/cjs/handlers/animationEnd.js.map +0 -1
  118. package/dist/cjs/handlers/click.js +0 -122
  119. package/dist/cjs/handlers/click.js.map +0 -1
  120. package/dist/cjs/handlers/hover.js +0 -147
  121. package/dist/cjs/handlers/hover.js.map +0 -1
  122. package/dist/cjs/handlers/index.js +0 -32
  123. package/dist/cjs/handlers/index.js.map +0 -1
  124. package/dist/cjs/handlers/pointerMove.js +0 -49
  125. package/dist/cjs/handlers/pointerMove.js.map +0 -1
  126. package/dist/cjs/handlers/utilities.js +0 -49
  127. package/dist/cjs/handlers/utilities.js.map +0 -1
  128. package/dist/cjs/handlers/viewEnter.js +0 -131
  129. package/dist/cjs/handlers/viewEnter.js.map +0 -1
  130. package/dist/cjs/handlers/viewProgress.js +0 -79
  131. package/dist/cjs/handlers/viewProgress.js.map +0 -1
  132. package/dist/cjs/test-types.d.js +0 -2
  133. package/dist/cjs/test-types.d.js.map +0 -1
  134. package/dist/cjs/types.js +0 -2
  135. package/dist/cjs/types.js.map +0 -1
  136. package/dist/cjs/utils.js +0 -98
  137. package/dist/cjs/utils.js.map +0 -1
  138. package/dist/esm/InteractElement.js +0 -157
  139. package/dist/esm/InteractElement.js.map +0 -1
  140. package/dist/esm/__tests__/interact.spec.js +0 -2102
  141. package/dist/esm/__tests__/interact.spec.js.map +0 -1
  142. package/dist/esm/__tests__/viewEnter.spec.js +0 -210
  143. package/dist/esm/__tests__/viewEnter.spec.js.map +0 -1
  144. package/dist/esm/core/Interact.js +0 -251
  145. package/dist/esm/core/Interact.js.map +0 -1
  146. package/dist/esm/core/add.js +0 -245
  147. package/dist/esm/core/add.js.map +0 -1
  148. package/dist/esm/core/remove.js +0 -30
  149. package/dist/esm/core/remove.js.map +0 -1
  150. package/dist/esm/core/utilities.js +0 -14
  151. package/dist/esm/core/utilities.js.map +0 -1
  152. package/dist/esm/external-types.d.js +0 -2
  153. package/dist/esm/external-types.d.js.map +0 -1
  154. package/dist/esm/handlers/animationEnd.js +0 -33
  155. package/dist/esm/handlers/animationEnd.js.map +0 -1
  156. package/dist/esm/handlers/click.js +0 -122
  157. package/dist/esm/handlers/click.js.map +0 -1
  158. package/dist/esm/handlers/hover.js +0 -147
  159. package/dist/esm/handlers/hover.js.map +0 -1
  160. package/dist/esm/handlers/index.js +0 -27
  161. package/dist/esm/handlers/index.js.map +0 -1
  162. package/dist/esm/handlers/pointerMove.js +0 -48
  163. package/dist/esm/handlers/pointerMove.js.map +0 -1
  164. package/dist/esm/handlers/utilities.js +0 -43
  165. package/dist/esm/handlers/utilities.js.map +0 -1
  166. package/dist/esm/handlers/viewEnter.js +0 -133
  167. package/dist/esm/handlers/viewEnter.js.map +0 -1
  168. package/dist/esm/handlers/viewProgress.js +0 -75
  169. package/dist/esm/handlers/viewProgress.js.map +0 -1
  170. package/dist/esm/index.js +0 -5
  171. package/dist/esm/index.js.map +0 -1
  172. package/dist/esm/test-types.d.js +0 -2
  173. package/dist/esm/test-types.d.js.map +0 -1
  174. package/dist/esm/types.js +0 -2
  175. package/dist/esm/types.js.map +0 -1
  176. package/dist/esm/utils.js +0 -92
  177. package/dist/esm/utils.js.map +0 -1
  178. package/dist/types/__tests__/interact.spec.d.ts +0 -1
  179. package/dist/types/__tests__/viewEnter.spec.d.ts +0 -0
@@ -0,0 +1,634 @@
1
+ # Effects and Animations
2
+
3
+ Effects define what visual changes happen when a trigger fires. `@wix/interact` integrates seamlessly with `@wix/motion` to provide three types of effects: **Time Effects**, **Scrub Effects**, and **Transition Effects**.
4
+
5
+ ## Overview of Effect Types
6
+
7
+ | Effect Type | Best For | Timing | Use Cases |
8
+ |-------------|----------|---------|-----------|
9
+ | **Time Effects** | Traditional animations | time-based | Entrance animations, Loop animations |
10
+ | **Scrub Effects** | Scroll-driven and Pointer-driven animations | Progress-based | Parallax effects, horizontal-sliding effect |
11
+ | **Transition Effects** | CSS property changes | Duration-based | Micro-interactions, simple state changes |
12
+
13
+ ## Time Effects
14
+
15
+ Time effects are traditional time-based animations perfect for entrance effects, hover interactions, and click responses.
16
+
17
+ ### Using Named Effects
18
+
19
+ Named effects are pre-built animations from `@wix/motion`:
20
+
21
+ ```typescript
22
+ {
23
+ key: 'my-element',
24
+ namedEffect: { type: 'FadeIn' }, // Predefined animation
25
+ duration: 800, // Animation duration in ms
26
+ easing: 'ease-out', // Animation timing curve
27
+ delay: 200, // Delay before starting
28
+ iterations: 1, // How many times to repeat
29
+ fill: 'forwards' // Animation fill mode
30
+ }
31
+ ```
32
+
33
+ ### Available Named Effects
34
+
35
+ Entrance named effects include:
36
+
37
+ - `ArcIn`
38
+ - `BlurIn`
39
+ - `BounceIn`
40
+ - `ExpandIn`
41
+ - `FadeIn`
42
+ - `FlipIn`
43
+ - `FloatIn`
44
+ - `FoldIn`
45
+ - `GlitchIn`
46
+ - `GrowIn`
47
+ - `RevealIn`
48
+ - `ShapeIn`
49
+ - `ShuttersIn`
50
+ - `SlideIn`
51
+ - `SpinIn`
52
+ - `TiltIn`
53
+ - `TurnIn`
54
+ - `WinkIn`
55
+
56
+ ### Using Keyframe Effects
57
+
58
+ For custom animations, use keyframe effects:
59
+
60
+ ```typescript
61
+ {
62
+ key: 'custom-animation',
63
+ keyframeEffect: {
64
+ name: 'custom-animation',
65
+ keyframes: [
66
+ { transform: 'scale(1) rotate(0deg)', opacity: '1', backgroundColor: '#ff0000' },
67
+ { transform: 'scale(1.2) rotate(180deg)', opacity: '0.8', backgroundColor: '#0000ff' }
68
+ ]
69
+ },
70
+ duration: 600,
71
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)'
72
+ }
73
+ ```
74
+
75
+ ### Advanced Time Effect Properties
76
+
77
+ ```typescript
78
+ {
79
+ key: 'advanced-element',
80
+ namedEffect: { type: 'SlideIn' },
81
+ duration: 1000,
82
+ easing: 'ease-in-out',
83
+ iterations: 2, // Repeat twice
84
+ alternate: true, // Reverse on alternate iterations
85
+ fill: 'both', // Keep start and end states
86
+ reversed: false, // Play backwards
87
+ delay: 500, // Wait before starting
88
+ effectId: 'my-animation' // Unique identifier for chaining
89
+ }
90
+ ```
91
+
92
+ ### Real-World Example: Card Entrance
93
+ ```typescript
94
+ {
95
+ key: 'product-card',
96
+ trigger: 'viewEnter',
97
+ params: { type: 'once', threshold: 0.3 },
98
+ effects: [
99
+ {
100
+ keyframeEffect: {
101
+ name: 'card-entrance',
102
+ keyframes: [
103
+ { opacity: '0', transform: 'translateY(60px) scale(0.9)' },
104
+ { opacity: '1', transform: 'translateY(0) scale(1)' }
105
+ ]
106
+ },
107
+ duration: 800,
108
+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)', // Custom easing
109
+ fill: 'forwards'
110
+ }
111
+ ]
112
+ }
113
+ ```
114
+
115
+ ## Scrub Effects
116
+
117
+ Scrub effects are progress-based animations that respond to scroll position or pointer position.
118
+
119
+ ### Basic Scrub Effect
120
+ ```typescript
121
+ {
122
+ key: 'parallax-bg',
123
+ keyframeEffect: {
124
+ name: 'parallax',
125
+ keyframes: [
126
+ { transform: 'translateY(0)' },
127
+ { transform: 'translateY(-200px)' }
128
+ ]
129
+ },
130
+ // No duration - controlled by scroll/pointer progress
131
+ easing: 'linear',
132
+ rangeStart: { name: 'cover', offset: { type: 'percentage', value: 0 } },
133
+ rangeEnd: { name: 'cover', offset: { type: 'percentage', value: 100 } }
134
+ }
135
+ ```
136
+
137
+ ### Range Configuration
138
+ Control when the animation starts and stops:
139
+
140
+ ```typescript
141
+ {
142
+ key: 'fade-element',
143
+ keyframeEffect: {
144
+ name: 'fade',
145
+ keyframes: [
146
+ { opacity: '1' },
147
+ { opacity: '0' }
148
+ ]
149
+ },
150
+ rangeStart: { name: 'cover', offset: { type: 'percentage', value: 30 } }, // Start at 30% scroll
151
+ rangeEnd: { name: 'cover', offset: { type: 'percentage', value: 80 } } // End at 80% scroll
152
+ }
153
+ ```
154
+
155
+ ### Advanced Pointer Properties
156
+
157
+ TBD
158
+
159
+ ### Real-World Example: Parallax Hero
160
+ ```typescript
161
+ {
162
+ key: 'hero-section',
163
+ trigger: 'viewProgress',
164
+ effects: [
165
+ // Background image moves slower
166
+ {
167
+ key: 'hero-bg',
168
+ keyframeEffect: {
169
+ name: 'image-parallax',
170
+ keyframes: [
171
+ { transform: 'translateY(0)' },
172
+ { transform: 'translateY(-150px)' }
173
+ ]
174
+ },
175
+ rangeStart: { name: 'cover', offset: { type: 'percentage', value: 0 } },
176
+ rangeEnd: { name: 'cover', offset: { type: 'percentage', value: 100 } }
177
+ },
178
+ // Text fades out faster
179
+ {
180
+ key: 'hero-text',
181
+ keyframeEffect: {
182
+ name: 'text-fade',
183
+ keyframes: [
184
+ { opacity: '1', transform: 'translateY(0)' },
185
+ { opacity: '0', transform: 'translateY(-50px)' }
186
+ ]
187
+ },
188
+ rangeStart: { name: 'cover', offset: { type: 'percentage', value: 20 } },
189
+ rangeEnd: { name: 'cover', offset: { type: 'percentage', value: 60 } }
190
+ }
191
+ ]
192
+ }
193
+ ```
194
+
195
+ ## Transition Effects
196
+
197
+ Transition effects create smooth CSS property changes with automatic transitions.
198
+
199
+ ### Basic Transition Effect
200
+ ```typescript
201
+ {
202
+ key: 'theme-button',
203
+ transition: {
204
+ duration: 300,
205
+ delay: 0,
206
+ easing: 'ease-in-out',
207
+ styleProperties: [
208
+ { name: 'backgroundColor', value: '#2563eb' },
209
+ { name: 'color', value: '#ffffff' },
210
+ { name: 'borderRadius', value: '12px' }
211
+ ]
212
+ }
213
+ }
214
+ ```
215
+
216
+ ### Individual Property Transitions
217
+ For different timing per property:
218
+
219
+ ```typescript
220
+ {
221
+ key: 'complex-transition',
222
+ transitionProperties: [
223
+ {
224
+ name: 'backgroundColor',
225
+ value: '#ef4444',
226
+ duration: 200,
227
+ delay: 0,
228
+ easing: 'ease-out'
229
+ },
230
+ {
231
+ name: 'transform',
232
+ value: 'scale(1.05)',
233
+ duration: 300,
234
+ delay: 100,
235
+ easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)'
236
+ }
237
+ ]
238
+ }
239
+ ```
240
+
241
+ ### Real-World Example: Theme Switcher
242
+ ```typescript
243
+ {
244
+ key: 'theme-toggle',
245
+ trigger: 'click',
246
+ params: { type: 'alternate' },
247
+ effects: [
248
+ {
249
+ key: 'page-body',
250
+ transition: {
251
+ duration: 400,
252
+ easing: 'ease-in-out',
253
+ styleProperties: [
254
+ { name: '--bg-color', value: '#1a1a1a' },
255
+ { name: '--text-color', value: '#ffffff' },
256
+ { name: '--accent-color', value: '#3b82f6' }
257
+ ]
258
+ },
259
+ effectId: 'theme-switch'
260
+ }
261
+ ]
262
+ }
263
+ ```
264
+
265
+ ## Custom Effects
266
+
267
+ For complete control, use custom effects with JavaScript functions:
268
+
269
+ ```typescript
270
+ {
271
+ key: 'custom-element',
272
+ customEffect: (element, progress) => {
273
+ // progress is 0-1 for scrub effects, or animation timing for time effects
274
+ const scale = 1 + (progress * 0.2);
275
+ const rotation = progress * 360;
276
+
277
+ element.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
278
+ element.style.filter = `hue-rotate(${progress * 180}deg)`;
279
+ }
280
+ }
281
+ ```
282
+
283
+ ### Advanced Custom Effect
284
+ ```typescript
285
+ {
286
+ key: 'particle-system',
287
+ customEffect: (element, progress, params) => {
288
+ const particles = element.querySelectorAll('.particle');
289
+
290
+ particles.forEach((particle, index) => {
291
+ const delay = index * 0.1;
292
+ const adjustedProgress = Math.max(0, progress - delay);
293
+
294
+ particle.style.opacity = adjustedProgress;
295
+ particle.style.transform = `
296
+ translateY(${(1 - adjustedProgress) * 50}px)
297
+ rotate(${adjustedProgress * 180}deg)
298
+ `;
299
+ });
300
+ }
301
+ }
302
+ ```
303
+
304
+ ## Combining Multiple Effects
305
+
306
+ You can apply multiple effects to different targets from a single trigger:
307
+
308
+ ```typescript
309
+ {
310
+ key: 'card-container',
311
+ trigger: 'hover',
312
+ effects: [
313
+ // Card itself
314
+ {
315
+ key: 'card-container',
316
+ keyframeEffect: {
317
+ name: 'card-shadow',
318
+ keyframes: [
319
+ { transform: 'translateY(0)', boxShadow: '0 4px 6px rgba(0,0,0,0.1)' },
320
+ { transform: 'translateY(-8px)', boxShadow: '0 20px 25px rgba(0,0,0,0.15)' }
321
+ ]
322
+ },
323
+ duration: 200,
324
+ easing: 'ease-out'
325
+ },
326
+ // Card image
327
+ {
328
+ key: 'card-image',
329
+ namedEffect: {
330
+ type: 'Scale'
331
+ },
332
+ duration: 300,
333
+ easing: 'ease-out'
334
+ },
335
+ // Card title
336
+ {
337
+ key: 'card-title',
338
+ keyframeEffect: {
339
+ name: 'title-color',
340
+ keyframes: [
341
+ { color: '#374151' },
342
+ { color: '#2563eb' }
343
+ ]
344
+ },
345
+ duration: 150
346
+ },
347
+ // Card button
348
+ {
349
+ key: 'card-button',
350
+ transition: {
351
+ duration: 200,
352
+ styleProperties: [
353
+ { name: 'opacity', value: '1' },
354
+ { name: 'transform', value: 'translateY(0)' }
355
+ ]
356
+ }
357
+ }
358
+ ]
359
+ }
360
+ ```
361
+
362
+ ## Animation Targeting
363
+
364
+ ### Self-Targeting
365
+ Most common pattern - effect applies to the trigger element:
366
+ ```typescript
367
+ {
368
+ key: 'my-button',
369
+ trigger: 'hover',
370
+ effects: [
371
+ {
372
+ // Ommitted key means same as source
373
+ namedEffect: {
374
+ type: 'Scale'
375
+ },
376
+ duration: 200
377
+ }
378
+ ]
379
+ }
380
+ ```
381
+
382
+ ### Cross-Targeting
383
+ Effect applies to different elements:
384
+ ```typescript
385
+ {
386
+ key: 'menu-trigger',
387
+ trigger: 'click',
388
+ effects: [
389
+ {
390
+ key: 'mobile-menu', // Different element
391
+ namedEffect: {
392
+ type: 'SlideIn',
393
+ direction: 'down'
394
+ },
395
+ duration: 300
396
+ },
397
+ {
398
+ key: 'menu-overlay', // Another different element
399
+ keyframeEffect: {
400
+ name: 'fade',
401
+ keyframes: [
402
+ { opacity: '0' },
403
+ { opacity: '1' }
404
+ ]
405
+ },
406
+ duration: 200
407
+ }
408
+ ]
409
+ }
410
+ ```
411
+
412
+ ### Multiple Targets with Same Effect
413
+ ```typescript
414
+ {
415
+ key: 'master-control',
416
+ trigger: 'click',
417
+ effects: [
418
+ {
419
+ key: 'item-1', // first target
420
+ namedEffect: {
421
+ type: 'FadeIn'
422
+ },
423
+ duration: 400
424
+ },
425
+ {
426
+ key: 'item-2', // second target
427
+ namedEffect: {
428
+ type: 'FadeIn'
429
+ },
430
+ duration: 400
431
+ },
432
+ {
433
+ key: 'item-3', // third target
434
+ namedEffect: {
435
+ type: 'FadeIn'
436
+ },
437
+ duration: 400
438
+ }
439
+ ]
440
+ }
441
+ ```
442
+
443
+ ## Performance Optimization
444
+
445
+ ### Use Efficient Properties
446
+ Prefer these properties for smooth animations:
447
+ - `transform` (translate, scale, rotate)
448
+ - `opacity`
449
+ - `filter`
450
+ - Custom CSS properties
451
+
452
+ Avoid animating:
453
+ - Layout properties (`width`, `height`, `margin`, `padding`)
454
+ - Position properties (`top`, `left`)
455
+ - Properties that trigger reflow
456
+
457
+ ### Named Effects vs Keyframes
458
+ ```typescript
459
+ // Preferred - optimized by @wix/motion
460
+ {
461
+ namedEffect: {
462
+ type: 'FadeIn'
463
+ },
464
+ duration: 300
465
+ }
466
+
467
+ // Use sparingly - custom keyframes
468
+ {
469
+ keyframeEffect: {
470
+ name: 'fade',
471
+ keyframes: [
472
+ { opacity: '0' },
473
+ { opacity: '1' }
474
+ ]
475
+ },
476
+ duration: 300
477
+ }
478
+ ```
479
+
480
+ ## Real-World Examples
481
+
482
+ ### Image Gallery Hover Effect
483
+ ```typescript
484
+ {
485
+ key: 'gallery-item',
486
+ trigger: 'hover',
487
+ effects: [
488
+ {
489
+ selector: 'img',
490
+ keyframeEffect: {
491
+ name: 'img-glow',
492
+ keyframes: [
493
+ { transform: 'scale(1)', filter: 'brightness(1)' },
494
+ { transform: 'scale(1.1)', filter: 'brightness(1.1)' }
495
+ ]
496
+ },
497
+ duration: 400,
498
+ easing: 'ease-out'
499
+ },
500
+ {
501
+ selector: '.overlay',
502
+ keyframeEffect: {
503
+ name: 'overlay-slide',
504
+ keyframes: [
505
+ { opacity: '0', transform: 'translateY(100%)' },
506
+ { opacity: '1', transform: 'translateY(0)' }
507
+ ]
508
+ },
509
+ duration: 300,
510
+ delay: 100
511
+ }
512
+ ]
513
+ }
514
+ ```
515
+
516
+ ### Loading Animation Sequence
517
+ ```typescript
518
+ {
519
+ key: 'app-loader',
520
+ trigger: 'viewEnter',
521
+ params: { type: 'once' },
522
+ effects: [
523
+ {
524
+ key: 'logo',
525
+ keyframeEffect: {
526
+ name: 'scale-fade',
527
+ keyframes: [
528
+ { opacity: '0', transform: 'scale(0.8)' },
529
+ { opacity: '1', transform: 'scale(1)' }
530
+ ]
531
+ },
532
+ duration: 600,
533
+ easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
534
+ effectId: 'logo-entrance'
535
+ }
536
+ ]
537
+ },
538
+ {
539
+ key: 'logo',
540
+ trigger: 'animationEnd',
541
+ params: { effectId: 'logo-entrance' },
542
+ effects: [
543
+ {
544
+ key: 'loading-text',
545
+ namedEffect: {
546
+ type: 'SlideUp'
547
+ },
548
+ duration: 400,
549
+ effectId: 'text-entrance'
550
+ }
551
+ ]
552
+ }
553
+ ```
554
+
555
+ ### Scroll-Triggered Counter
556
+ ```typescript
557
+ {
558
+ key: 'stats-section',
559
+ trigger: 'viewEnter',
560
+ params: { type: 'once', threshold: 0.5 },
561
+ effects: [
562
+ {
563
+ key: 'counter-1',
564
+ customEffect: (element, progress) => {
565
+ const targetValue = 1000;
566
+ const currentValue = Math.floor(targetValue * progress);
567
+ element.textContent = currentValue.toLocaleString();
568
+ },
569
+ duration: 2000,
570
+ easing: 'ease-out'
571
+ }
572
+ ]
573
+ }
574
+ ```
575
+
576
+ ## Best Practices
577
+
578
+ ### Animation Timing
579
+ - **Micro-interactions**: 100-300ms (hover, clicks)
580
+ - **Page transitions**: 300-500ms
581
+ - **Entrance animations**: 500-800ms
582
+ - **Complex sequences**: 800-1200ms
583
+
584
+ ### Easing Functions
585
+ - **Entrances**: `ease-out` or `cubic-bezier(0.16, 1, 0.3, 1)`
586
+ - **Exits**: `ease-in` or `cubic-bezier(0.4, 0, 1, 1)`
587
+ - **Interactions**: `ease-in-out`
588
+ - **Elastic effects**: `cubic-bezier(0.34, 1.56, 0.64, 1)`
589
+
590
+ ### Accessibility
591
+ ```typescript
592
+ // Respect user preferences
593
+ {
594
+ effects: {
595
+ 'reduced-motion-entry': {
596
+ namedEffect: {
597
+ type: 'FadeIn'
598
+ },
599
+ duration: 600
600
+ }
601
+ },
602
+ interactions: [
603
+ {
604
+ key: 'animated-element',
605
+ trigger: 'viewEnter',
606
+ effects: [
607
+ {
608
+ namedEffect: {
609
+ type: 'SlideIn'
610
+ },
611
+ duration: 600
612
+ },
613
+ {
614
+ effectId: 'reduced-motion-entry',
615
+ conditions: ['reduced-motion'] // Only animate if user allows motion
616
+ }
617
+ ]
618
+ }
619
+ ],
620
+ conditions: {
621
+ 'reduced-motion': {
622
+ type: 'media',
623
+ predicate: '(prefers-reduced-motion: reduce)'
624
+ }
625
+ }
626
+ }
627
+ ```
628
+
629
+ ## Next Steps
630
+
631
+ Now that you understand effects and animations:
632
+ - **[Configuration Structure](./configuration-structure.md)** - Organize complex interactions
633
+ - **[State Management](./state-management.md)** - Advanced state handling
634
+ - **[Conditions and Media Queries](./conditions-and-media-queries.md)** - Responsive animations