@lytjs/plugin-animation 6.4.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/dist/index.cjs ADDED
@@ -0,0 +1,817 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ GPU_PRESETS: () => GPU_PRESETS,
24
+ PRESETS: () => PRESETS,
25
+ PerformanceOptimizer: () => PerformanceOptimizer,
26
+ canUseGPU: () => canUseGPU,
27
+ createAnimation: () => createAnimation,
28
+ createKeyframeAnimation: () => createKeyframeAnimation,
29
+ default: () => index_default,
30
+ disableGPUAcceleration: () => disableGPUAcceleration,
31
+ enableGPUAcceleration: () => enableGPUAcceleration,
32
+ getGlobalOptimizer: () => getGlobalOptimizer,
33
+ resetGlobalOptimizer: () => resetGlobalOptimizer,
34
+ to3DTransform: () => to3DTransform,
35
+ transitionElement: () => transitionElement
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+ var import_core = require("@lytjs/core");
39
+ var import_reactivity = require("@lytjs/reactivity");
40
+
41
+ // src/gpu-acceleration.ts
42
+ var DEFAULT_GPU_OPTIONS = {
43
+ enable3D: true,
44
+ willChange: "transform",
45
+ force3D: false,
46
+ compositorThreshold: 1e-3
47
+ };
48
+ function to3DTransform(transform) {
49
+ return transform.replace(/translateX\(([^)]+)\)/g, "translate3d($1, 0, 0)").replace(/translateY\(([^)]+)\)/g, "translate3d(0, $1, 0)").replace(/translate\(([^,]+),\s*([^)]+)\)/g, "translate3d($1, $2, 0)").replace(/scale\(([^)]+)\)/g, "scale3d($1, $1, 1)").replace(/scale\(([^,]+),\s*([^)]+)\)/g, "scale3d($1, $2, 1)");
50
+ }
51
+ function canUseGPU(element) {
52
+ const el = element;
53
+ if (typeof window === "undefined") return false;
54
+ const noGPU = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
55
+ navigator.userAgent
56
+ );
57
+ if (noGPU) {
58
+ const hasGPU = el.style.transform !== void 0;
59
+ return hasGPU;
60
+ }
61
+ return true;
62
+ }
63
+ function enableGPUAcceleration(element, options = DEFAULT_GPU_OPTIONS) {
64
+ const { willChange = "transform" } = options;
65
+ element.style.willChange = willChange;
66
+ element.style.backfaceVisibility = "hidden";
67
+ element.style.perspective = "1000px";
68
+ }
69
+ function disableGPUAcceleration(element) {
70
+ element.style.willChange = "auto";
71
+ element.style.backfaceVisibility = "";
72
+ element.style.perspective = "";
73
+ }
74
+ var GPU_PRESETS = {
75
+ /**
76
+ * 快速滑入(GPU 加速)
77
+ */
78
+ gpuSlideIn: {
79
+ from: {
80
+ transform: "translate3d(0, -100%, 0)",
81
+ opacity: 0
82
+ },
83
+ to: {
84
+ transform: "translate3d(0, 0, 0)",
85
+ opacity: 1
86
+ }
87
+ },
88
+ /**
89
+ * 快速滑出(GPU 加速)
90
+ */
91
+ gpuSlideOut: {
92
+ from: {
93
+ transform: "translate3d(0, 0, 0)",
94
+ opacity: 1
95
+ },
96
+ to: {
97
+ transform: "translate3d(0, -100%, 0)",
98
+ opacity: 0
99
+ }
100
+ },
101
+ /**
102
+ * 缩放进入(GPU 加速)
103
+ */
104
+ gpuZoomIn: {
105
+ from: {
106
+ transform: "translate3d(-50%, -50%, 0) scale(0)",
107
+ opacity: 0
108
+ },
109
+ to: {
110
+ transform: "translate3d(-50%, -50%, 0) scale(1)",
111
+ opacity: 1
112
+ }
113
+ },
114
+ /**
115
+ * 缩放离开(GPU 加速)
116
+ */
117
+ gpuZoomOut: {
118
+ from: {
119
+ transform: "translate3d(-50%, -50%, 0) scale(1)",
120
+ opacity: 1
121
+ },
122
+ to: {
123
+ transform: "translate3d(-50%, -50%, 0) scale(0)",
124
+ opacity: 0
125
+ }
126
+ },
127
+ /**
128
+ * 3D 旋转进入
129
+ */
130
+ rotate3dIn: {
131
+ from: {
132
+ transform: "rotate3d(0, 1, 0, 90deg)",
133
+ opacity: 0
134
+ },
135
+ to: {
136
+ transform: "rotate3d(0, 0, 0, 0deg)",
137
+ opacity: 1
138
+ }
139
+ },
140
+ /**
141
+ * 3D 旋转离开
142
+ */
143
+ rotate3dOut: {
144
+ from: {
145
+ transform: "rotate3d(0, 0, 0, 0deg)",
146
+ opacity: 1
147
+ },
148
+ to: {
149
+ transform: "rotate3d(0, 1, 0, 90deg)",
150
+ opacity: 0
151
+ }
152
+ },
153
+ /**
154
+ * 弹性弹跳(GPU 加速)
155
+ */
156
+ elasticBounce: {
157
+ "0%": {
158
+ transform: "translate3d(0, 0, 0) scale(1)",
159
+ opacity: 1
160
+ },
161
+ "30%": {
162
+ transform: "translate3d(0, -30px, 0) scale(1.1)",
163
+ opacity: 1
164
+ },
165
+ "50%": {
166
+ transform: "translate3d(0, -15px, 0) scale(0.95)",
167
+ opacity: 1
168
+ },
169
+ "70%": {
170
+ transform: "translate3d(0, -7px, 0) scale(1.02)",
171
+ opacity: 1
172
+ },
173
+ "100%": {
174
+ transform: "translate3d(0, 0, 0) scale(1)",
175
+ opacity: 1
176
+ }
177
+ },
178
+ /**
179
+ * 翻转进入
180
+ */
181
+ flipIn: {
182
+ from: {
183
+ transform: "perspective(400px) rotate3d(1, 0, 0, 90deg)",
184
+ opacity: 0
185
+ },
186
+ "40%": {
187
+ transform: "perspective(400px) rotate3d(1, 0, 0, -10deg)",
188
+ opacity: 1
189
+ },
190
+ "100%": {
191
+ transform: "perspective(400px) rotate3d(1, 0, 0, 0deg)",
192
+ opacity: 1
193
+ }
194
+ },
195
+ /**
196
+ * 翻转离开
197
+ */
198
+ flipOut: {
199
+ from: {
200
+ transform: "perspective(400px) rotate3d(1, 0, 0, 0deg)",
201
+ opacity: 1
202
+ },
203
+ "30%": {
204
+ transform: "perspective(400px) rotate3d(1, 0, 0, 20deg)",
205
+ opacity: 1
206
+ },
207
+ "100%": {
208
+ transform: "perspective(400px) rotate3d(1, 0, 0, -90deg)",
209
+ opacity: 0
210
+ }
211
+ }
212
+ };
213
+ var PerformanceOptimizer = class {
214
+ constructor(options = DEFAULT_GPU_OPTIONS) {
215
+ this.activeAnimations = /* @__PURE__ */ new Set();
216
+ this.rafId = null;
217
+ this.batchedUpdates = /* @__PURE__ */ new Map();
218
+ this.options = { ...DEFAULT_GPU_OPTIONS, ...options };
219
+ this.gpuEnabled = this.checkGPUAvailability();
220
+ }
221
+ checkGPUAvailability() {
222
+ if (typeof window === "undefined") return false;
223
+ try {
224
+ const canvas = document.createElement("canvas");
225
+ const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
226
+ return !!gl;
227
+ } catch {
228
+ return false;
229
+ }
230
+ }
231
+ isGPUAvailable() {
232
+ return this.gpuEnabled;
233
+ }
234
+ shouldUseGPU(properties) {
235
+ if (!this.gpuEnabled) return false;
236
+ const gpuFriendly = ["transform", "opacity", "filter"];
237
+ return properties.every(
238
+ (prop) => gpuFriendly.some((gpuProp) => prop.toLowerCase().includes(gpuProp))
239
+ );
240
+ }
241
+ optimizeElement(element) {
242
+ if (this.shouldUseGPU(["transform", "opacity"])) {
243
+ enableGPUAcceleration(element, this.options);
244
+ }
245
+ }
246
+ batchAnimation(id, update) {
247
+ this.batchedUpdates.set(id, update);
248
+ if (this.rafId === null) {
249
+ this.rafId = requestAnimationFrame(() => {
250
+ this.flushBatchedUpdates();
251
+ });
252
+ }
253
+ }
254
+ flushBatchedUpdates() {
255
+ this.batchedUpdates.forEach((update) => update());
256
+ this.batchedUpdates.clear();
257
+ this.rafId = null;
258
+ }
259
+ trackAnimation(id) {
260
+ this.activeAnimations.add(id);
261
+ }
262
+ untrackAnimation(id) {
263
+ this.activeAnimations.delete(id);
264
+ }
265
+ getActiveAnimationCount() {
266
+ return this.activeAnimations.size;
267
+ }
268
+ cleanup() {
269
+ if (this.rafId !== null) {
270
+ cancelAnimationFrame(this.rafId);
271
+ this.rafId = null;
272
+ }
273
+ this.batchedUpdates.clear();
274
+ this.activeAnimations.clear();
275
+ }
276
+ };
277
+ var globalOptimizer = null;
278
+ function getGlobalOptimizer() {
279
+ if (!globalOptimizer) {
280
+ globalOptimizer = new PerformanceOptimizer();
281
+ }
282
+ return globalOptimizer;
283
+ }
284
+ function resetGlobalOptimizer(options) {
285
+ if (globalOptimizer) {
286
+ globalOptimizer.cleanup();
287
+ }
288
+ globalOptimizer = new PerformanceOptimizer(options);
289
+ }
290
+
291
+ // src/index.ts
292
+ var EASING_FUNCTIONS = {
293
+ linear: (t) => t,
294
+ ease: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
295
+ "ease-in": (t) => t * t * t,
296
+ "ease-out": (t) => --t * t * t + 1,
297
+ "ease-in-out": (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
298
+ "ease-in-quad": (t) => t * t,
299
+ "ease-out-quad": (t) => t * (2 - t),
300
+ "ease-in-out-quad": (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
301
+ "ease-in-cubic": (t) => t * t * t,
302
+ "ease-out-cubic": (t) => --t * t * t + 1,
303
+ "ease-in-out-cubic": (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
304
+ "ease-in-quart": (t) => t * t * t * t,
305
+ "ease-out-quart": (t) => 1 - --t * t * t * t,
306
+ "ease-in-out-quart": (t) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t,
307
+ "ease-in-quint": (t) => t * t * t * t * t,
308
+ "ease-out-quint": (t) => 1 + --t * t * t * t * t,
309
+ "ease-in-out-quint": (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t,
310
+ "ease-in-sine": (t) => 1 - Math.cos(t * Math.PI / 2),
311
+ "ease-out-sine": (t) => Math.sin(t * Math.PI / 2),
312
+ "ease-in-out-sine": (t) => -(Math.cos(Math.PI * t) - 1) / 2,
313
+ "ease-in-expo": (t) => t === 0 ? 0 : Math.pow(2, 10 * (t - 1)),
314
+ "ease-out-expo": (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t),
315
+ "ease-in-out-expo": (t) => t === 0 ? 0 : t === 1 ? 1 : t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2,
316
+ "ease-in-circ": (t) => 1 - Math.sqrt(1 - t * t),
317
+ "ease-out-circ": (t) => Math.sqrt(1 - --t * t),
318
+ "ease-in-out-circ": (t) => t < 0.5 ? (1 - Math.sqrt(1 - 4 * t * t)) / 2 : (Math.sqrt(1 - (2 * t - 2) * (2 * t - 2)) + 1) / 2,
319
+ "ease-in-back": (t) => {
320
+ const c1 = 1.70158;
321
+ const c3 = c1 + 1;
322
+ return c3 * t * t * t - c1 * t * t;
323
+ },
324
+ "ease-out-back": (t) => {
325
+ const c1 = 1.70158;
326
+ const c3 = c1 + 1;
327
+ return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
328
+ },
329
+ "ease-in-out-back": (t) => {
330
+ const c1 = 1.70158;
331
+ const c2 = c1 * 1.525;
332
+ return t < 0.5 ? Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2) / 2 : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
333
+ },
334
+ spring: (t) => {
335
+ const c4 = 2 * Math.PI / 3;
336
+ return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
337
+ }
338
+ };
339
+ var idCounter = 0;
340
+ function generateId() {
341
+ return `lyt-animation-${++idCounter}`;
342
+ }
343
+ function getEasingFunction(easing) {
344
+ if (typeof easing === "function") {
345
+ return easing;
346
+ }
347
+ return EASING_FUNCTIONS[easing] || EASING_FUNCTIONS.ease;
348
+ }
349
+ function createAnimation(animateFn, options = {}) {
350
+ const {
351
+ duration = 300,
352
+ easing = "ease",
353
+ delay = 0,
354
+ iterations = 1,
355
+ direction = "normal",
356
+ fill = "none",
357
+ onStart,
358
+ onUpdate,
359
+ onComplete,
360
+ onPause,
361
+ onCancel
362
+ } = options;
363
+ const id = generateId();
364
+ const easingFn = getEasingFunction(easing);
365
+ let state = "idle";
366
+ let progress = 0;
367
+ let startTime = 0;
368
+ let pausedTime = 0;
369
+ let animationFrameId = null;
370
+ let currentIteration = 0;
371
+ let isReversed = direction === "reverse" || direction === "alternate-reverse";
372
+ const progressSignal = (0, import_reactivity.signal)(0);
373
+ function animate(timestamp) {
374
+ if (state !== "playing") return;
375
+ if (!startTime) {
376
+ startTime = timestamp;
377
+ }
378
+ const elapsed = timestamp - startTime - delay;
379
+ if (elapsed >= 0) {
380
+ const rawProgress = Math.min(elapsed / duration, 1);
381
+ let adjustedProgress = rawProgress;
382
+ if (isReversed) {
383
+ adjustedProgress = 1 - rawProgress;
384
+ }
385
+ if (direction === "alternate" || direction === "alternate-reverse") {
386
+ const cycleProgress = rawProgress * iterations;
387
+ const currentCycle = Math.floor(cycleProgress);
388
+ const cycleProgressRemainder = cycleProgress - currentCycle;
389
+ adjustedProgress = currentCycle % 2 === 0 ? cycleProgressRemainder : 1 - cycleProgressRemainder;
390
+ }
391
+ progress = adjustedProgress;
392
+ progressSignal.set(adjustedProgress);
393
+ const easedProgress = easingFn(adjustedProgress);
394
+ animateFn(easedProgress);
395
+ if (onUpdate) {
396
+ onUpdate(easedProgress);
397
+ }
398
+ if (rawProgress >= 1) {
399
+ currentIteration++;
400
+ if (iterations === -1 || currentIteration < iterations) {
401
+ startTime = timestamp - (elapsed - duration);
402
+ animationFrameId = requestAnimationFrame(animate);
403
+ return;
404
+ } else {
405
+ state = "completed";
406
+ if (onComplete) {
407
+ onComplete();
408
+ }
409
+ }
410
+ } else {
411
+ animationFrameId = requestAnimationFrame(animate);
412
+ }
413
+ } else {
414
+ animationFrameId = requestAnimationFrame(animate);
415
+ }
416
+ }
417
+ function play() {
418
+ if (state === "completed" || state === "cancelled") {
419
+ reset();
420
+ }
421
+ state = "playing";
422
+ if (onStart) {
423
+ onStart();
424
+ }
425
+ animationFrameId = requestAnimationFrame(animate);
426
+ }
427
+ function pause() {
428
+ if (state !== "playing") return;
429
+ state = "paused";
430
+ pausedTime = performance.now();
431
+ if (animationFrameId) {
432
+ cancelAnimationFrame(animationFrameId);
433
+ animationFrameId = null;
434
+ }
435
+ if (onPause) {
436
+ onPause();
437
+ }
438
+ }
439
+ function cancel() {
440
+ if (animationFrameId) {
441
+ cancelAnimationFrame(animationFrameId);
442
+ animationFrameId = null;
443
+ }
444
+ state = "cancelled";
445
+ if (onCancel) {
446
+ onCancel();
447
+ }
448
+ }
449
+ function reset() {
450
+ if (animationFrameId) {
451
+ cancelAnimationFrame(animationFrameId);
452
+ animationFrameId = null;
453
+ }
454
+ state = "idle";
455
+ progress = 0;
456
+ currentIteration = 0;
457
+ progressSignal.set(0);
458
+ startTime = 0;
459
+ pausedTime = 0;
460
+ isReversed = direction === "reverse" || direction === "alternate-reverse";
461
+ }
462
+ function seek(newProgress) {
463
+ progress = Math.max(0, Math.min(1, newProgress));
464
+ progressSignal.set(progress);
465
+ const easedProgress = easingFn(progress);
466
+ animateFn(easedProgress);
467
+ if (onUpdate) {
468
+ onUpdate(easedProgress);
469
+ }
470
+ }
471
+ function reverse() {
472
+ isReversed = !isReversed;
473
+ }
474
+ return {
475
+ id,
476
+ get state() {
477
+ return state;
478
+ },
479
+ get progress() {
480
+ return progressSignal();
481
+ },
482
+ play,
483
+ pause,
484
+ cancel,
485
+ reset,
486
+ seek,
487
+ reverse
488
+ };
489
+ }
490
+ function transitionElement(element, toggle, options = {}) {
491
+ const {
492
+ property = "all",
493
+ duration = 300,
494
+ easing = "ease",
495
+ delay = 0,
496
+ onBeforeEnter,
497
+ onEnter,
498
+ onAfterEnter,
499
+ onBeforeLeave,
500
+ onLeave,
501
+ onAfterLeave
502
+ } = options;
503
+ const propertyStr = Array.isArray(property) ? property.join(", ") : property;
504
+ const easingFn = getEasingFunction(easing);
505
+ if (toggle) {
506
+ if (onBeforeEnter) {
507
+ onBeforeEnter();
508
+ }
509
+ element.style.transition = `${propertyStr} ${duration}ms ${typeof easing === "string" ? easing : "ease"} ${delay}ms`;
510
+ requestAnimationFrame(() => {
511
+ if (onEnter) {
512
+ onEnter();
513
+ }
514
+ setTimeout(() => {
515
+ if (onAfterEnter) {
516
+ onAfterEnter();
517
+ }
518
+ }, duration + delay);
519
+ });
520
+ } else {
521
+ if (onBeforeLeave) {
522
+ onBeforeLeave();
523
+ }
524
+ element.style.transition = `${propertyStr} ${duration}ms ${typeof easing === "string" ? easing : "ease"} ${delay}ms`;
525
+ requestAnimationFrame(() => {
526
+ if (onLeave) {
527
+ onLeave();
528
+ }
529
+ setTimeout(() => {
530
+ if (onAfterLeave) {
531
+ onAfterLeave();
532
+ }
533
+ }, duration + delay);
534
+ });
535
+ }
536
+ }
537
+ function createKeyframeAnimation(element, keyframes, options = {}) {
538
+ const {
539
+ duration = 300,
540
+ easing = "ease",
541
+ delay = 0,
542
+ iterations = 1,
543
+ direction = "normal",
544
+ fill = "forwards",
545
+ onStart,
546
+ onUpdate,
547
+ onComplete,
548
+ onPause,
549
+ onCancel
550
+ } = options;
551
+ if (typeof element.animate === "function") {
552
+ let webAnimation = null;
553
+ let updateInterval = null;
554
+ const id = generateId();
555
+ let isPlaying = false;
556
+ const progressSignal = (0, import_reactivity.signal)(0);
557
+ const play = () => {
558
+ if (!webAnimation) {
559
+ webAnimation = element.animate(keyframes, {
560
+ duration,
561
+ easing: typeof easing === "string" ? easing : "ease",
562
+ delay,
563
+ iterations: iterations === -1 ? Infinity : iterations,
564
+ direction,
565
+ fill
566
+ });
567
+ webAnimation.onfinish = () => {
568
+ if (onComplete) {
569
+ onComplete();
570
+ }
571
+ };
572
+ webAnimation.oncancel = () => {
573
+ if (onCancel) {
574
+ onCancel();
575
+ }
576
+ };
577
+ if (onUpdate) {
578
+ updateInterval = window.setInterval(() => {
579
+ if (webAnimation && webAnimation.currentTime !== null && webAnimation.currentTime !== void 0) {
580
+ const progress = webAnimation.currentTime / duration;
581
+ progressSignal.set(progress);
582
+ onUpdate(progress);
583
+ }
584
+ }, 16);
585
+ }
586
+ } else {
587
+ webAnimation.play();
588
+ }
589
+ isPlaying = true;
590
+ if (onStart) {
591
+ onStart();
592
+ }
593
+ };
594
+ const pause = () => {
595
+ if (webAnimation) {
596
+ webAnimation.pause();
597
+ isPlaying = false;
598
+ if (onPause) {
599
+ onPause();
600
+ }
601
+ if (updateInterval) {
602
+ clearInterval(updateInterval);
603
+ updateInterval = null;
604
+ }
605
+ }
606
+ };
607
+ const cancel = () => {
608
+ if (webAnimation) {
609
+ webAnimation.cancel();
610
+ webAnimation = null;
611
+ if (updateInterval) {
612
+ clearInterval(updateInterval);
613
+ updateInterval = null;
614
+ }
615
+ }
616
+ };
617
+ const reset = () => {
618
+ if (webAnimation) {
619
+ webAnimation.cancel();
620
+ webAnimation = null;
621
+ progressSignal.set(0);
622
+ if (updateInterval) {
623
+ clearInterval(updateInterval);
624
+ updateInterval = null;
625
+ }
626
+ }
627
+ };
628
+ const seek = (progress) => {
629
+ if (webAnimation) {
630
+ webAnimation.currentTime = progress * duration;
631
+ progressSignal.set(progress);
632
+ }
633
+ };
634
+ const reverse = () => {
635
+ if (webAnimation) {
636
+ webAnimation.reverse();
637
+ }
638
+ };
639
+ return {
640
+ id,
641
+ get state() {
642
+ return isPlaying ? "playing" : webAnimation ? "paused" : "idle";
643
+ },
644
+ get progress() {
645
+ return progressSignal();
646
+ },
647
+ play,
648
+ pause,
649
+ cancel,
650
+ reset,
651
+ seek,
652
+ reverse
653
+ };
654
+ }
655
+ return createAnimation(() => {
656
+ }, options);
657
+ }
658
+ var PRESETS = {
659
+ /** 淡入 */
660
+ fadeIn: {
661
+ from: { opacity: 0 },
662
+ to: { opacity: 1 }
663
+ },
664
+ /** 淡出 */
665
+ fadeOut: {
666
+ from: { opacity: 1 },
667
+ to: { opacity: 0 }
668
+ },
669
+ /** 滑入(上方) */
670
+ slideInUp: {
671
+ from: { transform: "translateY(100%)", opacity: 0 },
672
+ to: { transform: "translateY(0)", opacity: 1 }
673
+ },
674
+ /** 滑入(下方) */
675
+ slideInDown: {
676
+ from: { transform: "translateY(-100%)", opacity: 0 },
677
+ to: { transform: "translateY(0)", opacity: 1 }
678
+ },
679
+ /** 滑入(左侧) */
680
+ slideInLeft: {
681
+ from: { transform: "translateX(-100%)", opacity: 0 },
682
+ to: { transform: "translateX(0)", opacity: 1 }
683
+ },
684
+ /** 滑入(右侧) */
685
+ slideInRight: {
686
+ from: { transform: "translateX(100%)", opacity: 0 },
687
+ to: { transform: "translateX(0)", opacity: 1 }
688
+ },
689
+ /** 缩放进入 */
690
+ zoomIn: {
691
+ from: { transform: "scale(0)", opacity: 0 },
692
+ to: { transform: "scale(1)", opacity: 1 }
693
+ },
694
+ /** 缩放离开 */
695
+ zoomOut: {
696
+ from: { transform: "scale(1)", opacity: 1 },
697
+ to: { transform: "scale(0)", opacity: 0 }
698
+ },
699
+ /** 弹跳进入 */
700
+ bounceIn: {
701
+ from: { transform: "scale(0.3)", opacity: 0 },
702
+ "40%": { transform: "scale(1.1)" },
703
+ "70%": { transform: "scale(0.9)" },
704
+ to: { transform: "scale(1)", opacity: 1 }
705
+ },
706
+ /** 摇摆进入 */
707
+ shake: {
708
+ "10%, 90%": { transform: "translate3d(-1px, 0, 0)" },
709
+ "20%, 80%": { transform: "translate3d(2px, 0, 0)" },
710
+ "30%, 50%, 70%": { transform: "translate3d(-4px, 0, 0)" },
711
+ "40%, 60%": { transform: "translate3d(4px, 0, 0)" }
712
+ }
713
+ };
714
+ function createAnimationManager(options = {}) {
715
+ const {
716
+ defaultDuration = 300,
717
+ defaultEasing = "ease",
718
+ autoCleanup = true
719
+ } = options;
720
+ const animations = /* @__PURE__ */ new Map();
721
+ function animate(animateFn, opts) {
722
+ const animation = createAnimation(animateFn, {
723
+ duration: defaultDuration,
724
+ easing: defaultEasing,
725
+ ...opts
726
+ });
727
+ animations.set(animation.id, animation);
728
+ return animation;
729
+ }
730
+ function applyPreset(element, presetName, opts) {
731
+ const preset = PRESETS[presetName];
732
+ if (!preset) {
733
+ throw new Error(`Preset "${presetName}" not found`);
734
+ }
735
+ const keyframes = [];
736
+ for (const key in preset) {
737
+ const keyframe = preset[key];
738
+ let offset;
739
+ if (key === "from") offset = 0;
740
+ else if (key === "to") offset = 1;
741
+ else {
742
+ const match = key.match(/^(\d+)%$/);
743
+ if (match) offset = parseInt(match[1], 10) / 100;
744
+ else continue;
745
+ }
746
+ keyframes.push({
747
+ offset,
748
+ ...keyframe
749
+ });
750
+ }
751
+ const animation = createKeyframeAnimation(element, keyframes, {
752
+ duration: defaultDuration,
753
+ easing: defaultEasing,
754
+ ...opts
755
+ });
756
+ animations.set(animation.id, animation);
757
+ return animation;
758
+ }
759
+ function remove(id) {
760
+ const animation = animations.get(id);
761
+ if (animation) {
762
+ animation.cancel();
763
+ animations.delete(id);
764
+ }
765
+ }
766
+ function clear() {
767
+ for (const [id, animation] of animations) {
768
+ animation.cancel();
769
+ }
770
+ animations.clear();
771
+ }
772
+ return {
773
+ animate,
774
+ applyPreset,
775
+ transitionElement,
776
+ remove,
777
+ clear
778
+ };
779
+ }
780
+ var pluginAnimation = (0, import_core.definePlugin)({
781
+ name: "animation",
782
+ version: "6.0.0",
783
+ description: "LytJS official animation plugin with CSS transitions and animations",
784
+ author: "LytJS Team",
785
+ keywords: ["lytjs", "animation", "transition", "css-animation"],
786
+ schema: {
787
+ type: "object",
788
+ object: {
789
+ properties: {
790
+ defaultDuration: { type: "number", default: 300 },
791
+ defaultEasing: { type: "string", default: "ease" },
792
+ autoCleanup: { type: "boolean", default: true }
793
+ }
794
+ }
795
+ },
796
+ install(app, options) {
797
+ const animationManager = createAnimationManager(options);
798
+ app.config.globalProperties.$animation = animationManager;
799
+ app.provide("lyt-animation", animationManager);
800
+ }
801
+ });
802
+ var index_default = pluginAnimation;
803
+ // Annotate the CommonJS export names for ESM import in node:
804
+ 0 && (module.exports = {
805
+ GPU_PRESETS,
806
+ PRESETS,
807
+ PerformanceOptimizer,
808
+ canUseGPU,
809
+ createAnimation,
810
+ createKeyframeAnimation,
811
+ disableGPUAcceleration,
812
+ enableGPUAcceleration,
813
+ getGlobalOptimizer,
814
+ resetGlobalOptimizer,
815
+ to3DTransform,
816
+ transitionElement
817
+ });