@brandocms/jupiter 4.0.0-beta.1 → 5.0.0-beta.1
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/README.md +191 -2
- package/package.json +20 -18
- package/src/index.js +10 -10
- package/src/modules/Application/index.js +203 -157
- package/src/modules/Cookies/index.js +34 -55
- package/src/modules/CoverOverlay/index.js +20 -13
- package/src/modules/Dataloader/index.js +71 -24
- package/src/modules/Dataloader/url-sync.js +238 -0
- package/src/modules/Dom/index.js +18 -0
- package/src/modules/DoubleHeader/index.js +571 -0
- package/src/modules/Dropdown/index.js +101 -75
- package/src/modules/EqualHeightElements/index.js +5 -7
- package/src/modules/EqualHeightImages/index.js +7 -2
- package/src/modules/FixedHeader/index.js +60 -30
- package/src/modules/FooterReveal/index.js +3 -3
- package/src/modules/HeroSlider/index.js +207 -91
- package/src/modules/HeroVideo/index.js +15 -27
- package/src/modules/Lazyload/index.js +101 -80
- package/src/modules/Lightbox/index.js +17 -55
- package/src/modules/Links/index.js +54 -49
- package/src/modules/Looper/index.js +1737 -0
- package/src/modules/Marquee/index.js +106 -37
- package/src/modules/MobileMenu/index.js +70 -124
- package/src/modules/Moonwalk/index.js +349 -150
- package/src/modules/Popover/index.js +186 -28
- package/src/modules/Popup/index.js +27 -34
- package/src/modules/StackedBoxes/index.js +3 -3
- package/src/modules/StickyHeader/index.js +364 -155
- package/src/modules/Toggler/index.js +184 -27
- package/src/utils/motion-helpers.js +330 -0
- package/types/index.d.ts +1 -30
- package/types/modules/Application/index.d.ts +6 -6
- package/types/modules/Breakpoints/index.d.ts +2 -0
- package/types/modules/Dataloader/index.d.ts +5 -2
- package/types/modules/Dataloader/url-sync.d.ts +36 -0
- package/types/modules/Dom/index.d.ts +7 -0
- package/types/modules/DoubleHeader/index.d.ts +63 -0
- package/types/modules/Dropdown/index.d.ts +7 -30
- package/types/modules/EqualHeightImages/index.d.ts +1 -1
- package/types/modules/FixedHeader/index.d.ts +1 -1
- package/types/modules/Lazyload/index.d.ts +9 -9
- package/types/modules/Lightbox/index.d.ts +0 -5
- package/types/modules/Looper/index.d.ts +127 -0
- package/types/modules/Moonwalk/index.d.ts +6 -15
- package/types/modules/Parallax/index.d.ts +10 -32
- package/types/modules/Popover/index.d.ts +12 -0
- package/types/modules/Popup/index.d.ts +6 -19
- package/types/modules/ScrollSpy/index.d.ts +1 -1
- package/types/modules/StickyHeader/index.d.ts +171 -14
- package/types/modules/Toggler/index.d.ts +24 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Vendor imports
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { animate, stagger } from 'motion'
|
|
5
5
|
import _defaultsDeep from 'lodash.defaultsdeep'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -11,9 +11,28 @@ import * as Events from '../../events'
|
|
|
11
11
|
import prefersReducedMotion from '../../utils/prefersReducedMotion'
|
|
12
12
|
import imageIsLoaded from '../../utils/imageIsLoaded'
|
|
13
13
|
import imagesAreLoaded from '../../utils/imagesAreLoaded'
|
|
14
|
+
import { set, animateAutoAlpha, delayedCall, convertEasing } from '../../utils/motion-helpers'
|
|
14
15
|
import Dom from '../Dom'
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Debug logging
|
|
19
|
+
*/
|
|
20
|
+
const DEBUG = false
|
|
21
|
+
|
|
22
|
+
function logMoonwalk(category, message, data = {}) {
|
|
23
|
+
if (DEBUG) {
|
|
24
|
+
console.log(`[Moonwalk:${category}]`, message, data)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function logComputedStyle(element, props = ['opacity', 'transform']) {
|
|
29
|
+
if (DEBUG && element) {
|
|
30
|
+
const computed = window.getComputedStyle(element)
|
|
31
|
+
const values = {}
|
|
32
|
+
props.forEach((prop) => (values[prop] = computed[prop]))
|
|
33
|
+
console.log('[Moonwalk:ComputedStyle]', element, values)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
17
36
|
|
|
18
37
|
/**
|
|
19
38
|
* @typedef {Object} MoonwalkTransition
|
|
@@ -39,6 +58,7 @@ gsap.registerPlugin(CSSPlugin)
|
|
|
39
58
|
* @property {boolean} [repeated=false] - Whether the run should repeat
|
|
40
59
|
* @property {string} [rootMargin] - IntersectionObserver rootMargin
|
|
41
60
|
* @property {Function} [initialize] - Function called during initialization
|
|
61
|
+
* @property {Function} [onReady] - Function called when APPLICATION_REVEALED fires, before viewport observers start
|
|
42
62
|
*/
|
|
43
63
|
|
|
44
64
|
/**
|
|
@@ -344,6 +364,7 @@ export default class Moonwalk {
|
|
|
344
364
|
el: run,
|
|
345
365
|
threshold: foundRun.threshold || 0,
|
|
346
366
|
initialize: foundRun.initialize,
|
|
367
|
+
onReady: foundRun.onReady,
|
|
347
368
|
callback: foundRun.callback,
|
|
348
369
|
onExit: foundRun.onExit,
|
|
349
370
|
repeated: foundRun.repeated,
|
|
@@ -386,16 +407,15 @@ export default class Moonwalk {
|
|
|
386
407
|
this.addIndexes(section)
|
|
387
408
|
}
|
|
388
409
|
|
|
389
|
-
const timeline = gsap.timeline({
|
|
390
|
-
autoRemoveChildren: false,
|
|
391
|
-
smoothChildTiming: false,
|
|
392
|
-
})
|
|
393
|
-
|
|
394
410
|
return {
|
|
395
411
|
id: Math.random().toString(36).substring(7),
|
|
396
412
|
el: section,
|
|
397
413
|
name: section.getAttribute('data-moonwalk-section') || null,
|
|
398
|
-
|
|
414
|
+
animation: {
|
|
415
|
+
lastDelay: 0,
|
|
416
|
+
lastDuration: 0,
|
|
417
|
+
lastStartTime: null,
|
|
418
|
+
},
|
|
399
419
|
observer: null,
|
|
400
420
|
stage: {
|
|
401
421
|
name: section.getAttribute('data-moonwalk-stage') || null,
|
|
@@ -481,14 +501,32 @@ export default class Moonwalk {
|
|
|
481
501
|
section.children = this.orderChildren(section.el.children)
|
|
482
502
|
}
|
|
483
503
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
504
|
+
// Only set initial states for JS animations (transition !== null)
|
|
505
|
+
if (sectionWalk.transition) {
|
|
506
|
+
const fromTransition = sectionWalk.alphaTween
|
|
507
|
+
? {
|
|
508
|
+
...sectionWalk.transition.from,
|
|
509
|
+
opacity: 0,
|
|
510
|
+
}
|
|
511
|
+
: sectionWalk.transition.from
|
|
512
|
+
|
|
513
|
+
logMoonwalk('InitialState', 'Setting initial state for named section', {
|
|
514
|
+
section: section.name,
|
|
515
|
+
childCount: section.children.length,
|
|
516
|
+
fromTransition,
|
|
517
|
+
})
|
|
518
|
+
set(section.children, fromTransition)
|
|
519
|
+
|
|
520
|
+
// Check if styles were actually applied
|
|
521
|
+
if (section.children.length > 0) {
|
|
522
|
+
logComputedStyle(section.children[0])
|
|
523
|
+
}
|
|
524
|
+
} else {
|
|
525
|
+
logMoonwalk('InitialState', 'Skipping initial state for CSS-only section', {
|
|
526
|
+
section: section.name,
|
|
527
|
+
childCount: section.children.length,
|
|
528
|
+
})
|
|
529
|
+
}
|
|
492
530
|
}
|
|
493
531
|
|
|
494
532
|
if (section.stage.name) {
|
|
@@ -500,7 +538,12 @@ export default class Moonwalk {
|
|
|
500
538
|
section.stage.name
|
|
501
539
|
)
|
|
502
540
|
} else {
|
|
503
|
-
|
|
541
|
+
logMoonwalk('InitialState', 'Setting stage initial state', {
|
|
542
|
+
stage: section.stage.name,
|
|
543
|
+
from: stageTween.transition.from,
|
|
544
|
+
})
|
|
545
|
+
set(section.el, stageTween.transition.from)
|
|
546
|
+
logComputedStyle(section.el)
|
|
504
547
|
}
|
|
505
548
|
}
|
|
506
549
|
|
|
@@ -530,12 +573,9 @@ export default class Moonwalk {
|
|
|
530
573
|
// run stage tween
|
|
531
574
|
const stageTween = walks[section.stage.name]
|
|
532
575
|
|
|
533
|
-
|
|
534
|
-
...stageTween.transition.to,
|
|
576
|
+
animate(entry.target, stageTween.transition.to, {
|
|
535
577
|
duration: stageTween.duration,
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
section.timeline.to(entry.target, to, 0)
|
|
578
|
+
})
|
|
539
579
|
section.stage.firstTween = true
|
|
540
580
|
}
|
|
541
581
|
}
|
|
@@ -550,44 +590,75 @@ export default class Moonwalk {
|
|
|
550
590
|
)
|
|
551
591
|
}
|
|
552
592
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
tween.alphaTween
|
|
559
|
-
|
|
560
|
-
|
|
593
|
+
logMoonwalk('SectionObserver', 'Named section triggered', {
|
|
594
|
+
sectionName: section.name,
|
|
595
|
+
childCount: section.children.length,
|
|
596
|
+
interval: tween.interval,
|
|
597
|
+
duration: tween.duration,
|
|
598
|
+
hasAlphaTween: !!tween.alphaTween,
|
|
599
|
+
isCssOnly: !tween.transition,
|
|
600
|
+
})
|
|
601
|
+
|
|
602
|
+
// Check if this is CSS-only animation (transition: null)
|
|
603
|
+
if (!tween.transition) {
|
|
604
|
+
// CSS-only mode - stagger adding the data-moonwalked attribute
|
|
605
|
+
logMoonwalk('SectionObserver', 'Using CSS-only mode', {
|
|
606
|
+
sectionName: section.name,
|
|
607
|
+
})
|
|
608
|
+
|
|
609
|
+
section.children.forEach((child, index) => {
|
|
610
|
+
const delay = (tween.startDelay || 0) + index * tween.interval
|
|
611
|
+
delayedCall(delay, () => {
|
|
612
|
+
child.setAttribute('data-moonwalked', '')
|
|
613
|
+
})
|
|
614
|
+
})
|
|
615
|
+
} else {
|
|
616
|
+
// JS animation mode
|
|
617
|
+
if (typeof tween.alphaTween === 'object') {
|
|
618
|
+
tween.alphaTween.duration = tween.alphaTween.duration
|
|
619
|
+
? tween.alphaTween.duration
|
|
620
|
+
: tween.duration
|
|
621
|
+
} else if (tween.alphaTween === true) {
|
|
622
|
+
tween.alphaTween = {
|
|
623
|
+
duration: tween.duration,
|
|
624
|
+
ease: 'easeIn',
|
|
625
|
+
}
|
|
561
626
|
}
|
|
562
|
-
}
|
|
563
627
|
|
|
564
|
-
|
|
565
|
-
tween.transition.to
|
|
566
|
-
|
|
567
|
-
delay: tween.startDelay,
|
|
568
|
-
}
|
|
569
|
-
}
|
|
628
|
+
// Extract ease from to values and convert for Motion.js
|
|
629
|
+
const { ease: tweenEase, ...toValues } = tween.transition.to
|
|
630
|
+
const convertedEase = convertEasing(tweenEase || 'easeOut')
|
|
570
631
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
632
|
+
const animationOptions = {
|
|
633
|
+
duration: tween.duration,
|
|
634
|
+
ease: convertedEase,
|
|
635
|
+
delay: stagger(tween.interval, {
|
|
636
|
+
startDelay: tween.startDelay || 0,
|
|
637
|
+
}),
|
|
638
|
+
}
|
|
578
639
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
640
|
+
logMoonwalk('SectionObserver', 'Starting stagger animation', {
|
|
641
|
+
sectionName: section.name,
|
|
642
|
+
to: toValues,
|
|
643
|
+
ease: convertedEase,
|
|
644
|
+
options: animationOptions,
|
|
645
|
+
})
|
|
646
|
+
|
|
647
|
+
animate(section.children, toValues, animationOptions)
|
|
648
|
+
|
|
649
|
+
if (tween.alphaTween) {
|
|
650
|
+
animate(
|
|
651
|
+
section.children,
|
|
652
|
+
{ opacity: 1 },
|
|
653
|
+
{
|
|
654
|
+
duration: tween.alphaTween.duration,
|
|
655
|
+
ease: convertEasing(tween.alphaTween.ease || 'easeIn'),
|
|
656
|
+
delay: stagger(tween.interval, {
|
|
657
|
+
startDelay: tween.startDelay || 0,
|
|
658
|
+
}),
|
|
659
|
+
}
|
|
660
|
+
)
|
|
661
|
+
}
|
|
591
662
|
}
|
|
592
663
|
}
|
|
593
664
|
|
|
@@ -629,6 +700,64 @@ export default class Moonwalk {
|
|
|
629
700
|
})
|
|
630
701
|
}
|
|
631
702
|
|
|
703
|
+
/**
|
|
704
|
+
* Calculate the delay for the next animation in the section.
|
|
705
|
+
* This replaces GSAP's timeline.recent() logic.
|
|
706
|
+
*
|
|
707
|
+
* @param {*} section - The section object
|
|
708
|
+
* @param {*} duration - Duration of the animation to add
|
|
709
|
+
* @param {*} overlap - How much the animations should overlap
|
|
710
|
+
* @returns {number} The delay in seconds
|
|
711
|
+
*/
|
|
712
|
+
calculateDelay(section, duration, overlap) {
|
|
713
|
+
if (!section.animation.lastStartTime) {
|
|
714
|
+
// First animation in section
|
|
715
|
+
logMoonwalk('DelayCalc', 'First animation in section', { delay: 0 })
|
|
716
|
+
return 0
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
const now = performance.now()
|
|
720
|
+
const elapsed = (now - section.animation.lastStartTime) / 1000
|
|
721
|
+
// overlap is negative when animations should stagger (start before previous ends)
|
|
722
|
+
// So we ADD overlap (which is negative) to get the correct next start time
|
|
723
|
+
const idealNextStart =
|
|
724
|
+
section.animation.lastDelay + section.animation.lastDuration + overlap
|
|
725
|
+
const actualDelay = Math.max(0, idealNextStart - elapsed)
|
|
726
|
+
|
|
727
|
+
logMoonwalk('DelayCalc', 'Calculating delay', {
|
|
728
|
+
elapsed: elapsed.toFixed(3),
|
|
729
|
+
lastDelay: section.animation.lastDelay,
|
|
730
|
+
lastDuration: section.animation.lastDuration,
|
|
731
|
+
overlap,
|
|
732
|
+
idealNextStart,
|
|
733
|
+
actualDelay: actualDelay.toFixed(3),
|
|
734
|
+
})
|
|
735
|
+
|
|
736
|
+
return actualDelay
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Update the animation state after adding an animation.
|
|
741
|
+
*
|
|
742
|
+
* @param {*} section - The section object
|
|
743
|
+
* @param {*} delay - The delay that was used
|
|
744
|
+
* @param {*} duration - The duration of the animation
|
|
745
|
+
*/
|
|
746
|
+
updateAnimationState(section, delay, duration) {
|
|
747
|
+
const previousState = { ...section.animation }
|
|
748
|
+
|
|
749
|
+
section.animation.lastDelay = delay
|
|
750
|
+
section.animation.lastDuration = duration
|
|
751
|
+
section.animation.lastStartTime = performance.now()
|
|
752
|
+
|
|
753
|
+
logMoonwalk('StateUpdate', 'Updating animation state', {
|
|
754
|
+
delay,
|
|
755
|
+
duration,
|
|
756
|
+
previousState,
|
|
757
|
+
newState: { ...section.animation },
|
|
758
|
+
})
|
|
759
|
+
}
|
|
760
|
+
|
|
632
761
|
onReady() {
|
|
633
762
|
if (this.opts.initialDelay) {
|
|
634
763
|
setTimeout(() => {
|
|
@@ -646,6 +775,14 @@ export default class Moonwalk {
|
|
|
646
775
|
ready() {
|
|
647
776
|
const { opts } = this
|
|
648
777
|
|
|
778
|
+
// Execute onReady callbacks for all runs
|
|
779
|
+
for (let idx = 0; idx < this.runs.length; idx += 1) {
|
|
780
|
+
const run = this.runs[idx]
|
|
781
|
+
if (run && run.onReady) {
|
|
782
|
+
run.onReady(run.el)
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
649
786
|
for (let idx = 0; idx < this.runs.length; idx += 1) {
|
|
650
787
|
const run = this.runs[idx]
|
|
651
788
|
|
|
@@ -688,7 +825,29 @@ export default class Moonwalk {
|
|
|
688
825
|
}
|
|
689
826
|
|
|
690
827
|
section.elements = section.el.querySelectorAll('[data-moonwalk]')
|
|
691
|
-
|
|
828
|
+
|
|
829
|
+
// Only set initial states and observe individual elements for unnamed sections
|
|
830
|
+
// Named sections are observed at the section level via sectionObserver
|
|
831
|
+
if (!section.name) {
|
|
832
|
+
// Set initial states for tweenJS elements BEFORE observing
|
|
833
|
+
section.elements.forEach((element) => {
|
|
834
|
+
const walkName = element.getAttribute('data-moonwalk')
|
|
835
|
+
const cfg = !walkName.length
|
|
836
|
+
? opts.walks.default
|
|
837
|
+
: opts.walks[walkName]
|
|
838
|
+
|
|
839
|
+
// Only set initial state if this uses tweenJS (has transition property)
|
|
840
|
+
if (cfg && cfg.transition) {
|
|
841
|
+
logMoonwalk('InitialState', 'Setting initial state for individual element', {
|
|
842
|
+
walkName: walkName || 'default',
|
|
843
|
+
from: cfg.transition.from,
|
|
844
|
+
})
|
|
845
|
+
set(element, cfg.transition.from)
|
|
846
|
+
}
|
|
847
|
+
})
|
|
848
|
+
|
|
849
|
+
section.elements.forEach((box) => section.observer.observe(box))
|
|
850
|
+
}
|
|
692
851
|
}
|
|
693
852
|
}
|
|
694
853
|
|
|
@@ -830,16 +989,25 @@ export default class Moonwalk {
|
|
|
830
989
|
if (entry.isIntersecting || entry.intersectionRatio > 0) {
|
|
831
990
|
section.running = true
|
|
832
991
|
|
|
833
|
-
if (entry.target.dataset.moonwalkId) {
|
|
834
|
-
console.debug('-- intersecting', entry.target.dataset.moonwalkId)
|
|
835
|
-
}
|
|
836
|
-
|
|
837
992
|
const walkName = entry.target.getAttribute('data-moonwalk')
|
|
993
|
+
const targetId =
|
|
994
|
+
entry.target.getAttribute('data-testid') ||
|
|
995
|
+
walkName ||
|
|
996
|
+
entry.target.className
|
|
997
|
+
|
|
998
|
+
logMoonwalk('Observer', 'Element entered viewport', {
|
|
999
|
+
target: targetId,
|
|
1000
|
+
walkName,
|
|
1001
|
+
isIntersecting: entry.isIntersecting,
|
|
1002
|
+
intersectionRatio: entry.intersectionRatio,
|
|
1003
|
+
})
|
|
838
1004
|
const cfg = !walkName.length
|
|
839
1005
|
? opts.walks.default
|
|
840
1006
|
: opts.walks[walkName]
|
|
841
1007
|
|
|
842
|
-
const { duration, transition,
|
|
1008
|
+
const { duration, transition, startDelay } = cfg
|
|
1009
|
+
// Default interval to 0.15 if not specified (same as default walk)
|
|
1010
|
+
const interval = cfg.interval !== undefined ? cfg.interval : 0.15
|
|
843
1011
|
|
|
844
1012
|
let { alphaTween } = cfg
|
|
845
1013
|
let overlap = (duration - interval) * -1 // flip it
|
|
@@ -856,27 +1024,36 @@ export default class Moonwalk {
|
|
|
856
1024
|
} else if (alphaTween === true) {
|
|
857
1025
|
alphaTween = {
|
|
858
1026
|
duration,
|
|
859
|
-
ease: '
|
|
1027
|
+
ease: 'easeIn',
|
|
860
1028
|
}
|
|
861
1029
|
}
|
|
862
1030
|
|
|
863
|
-
const tween = transition ? this.tweenJS : this.tweenCSS
|
|
864
|
-
|
|
865
1031
|
const tweenFn = () => {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
1032
|
+
if (transition) {
|
|
1033
|
+
this.tweenJS(
|
|
1034
|
+
section,
|
|
1035
|
+
entry.target,
|
|
1036
|
+
duration,
|
|
1037
|
+
interval,
|
|
1038
|
+
transition,
|
|
1039
|
+
overlap,
|
|
1040
|
+
alphaTween
|
|
1041
|
+
)
|
|
1042
|
+
} else {
|
|
1043
|
+
this.tweenCSS(
|
|
1044
|
+
section,
|
|
1045
|
+
entry.target,
|
|
1046
|
+
duration,
|
|
1047
|
+
interval,
|
|
1048
|
+
transition,
|
|
1049
|
+
overlap
|
|
1050
|
+
)
|
|
1051
|
+
}
|
|
875
1052
|
}
|
|
876
1053
|
|
|
877
1054
|
const wrappedTweenFn = () => {
|
|
878
1055
|
if (startDelay) {
|
|
879
|
-
|
|
1056
|
+
delayedCall(startDelay, tweenFn)
|
|
880
1057
|
} else {
|
|
881
1058
|
tweenFn()
|
|
882
1059
|
}
|
|
@@ -940,56 +1117,90 @@ export default class Moonwalk {
|
|
|
940
1117
|
tweenOverlap,
|
|
941
1118
|
alphaTween
|
|
942
1119
|
) {
|
|
943
|
-
|
|
944
|
-
|
|
1120
|
+
const targetId =
|
|
1121
|
+
target.getAttribute('data-testid') ||
|
|
1122
|
+
target.getAttribute('data-moonwalk') ||
|
|
1123
|
+
target.className
|
|
1124
|
+
|
|
1125
|
+
logMoonwalk('TweenJS', 'Starting tweenJS', {
|
|
1126
|
+
target: targetId,
|
|
1127
|
+
duration: tweenDuration,
|
|
1128
|
+
overlap: tweenOverlap,
|
|
1129
|
+
hasAlphaTween: !!alphaTween,
|
|
1130
|
+
})
|
|
945
1131
|
|
|
946
1132
|
if (Dom.hasAttribute(target, 'data-moonwalked')) {
|
|
1133
|
+
logMoonwalk('TweenJS', 'Already moonwalked, skipping', { target: targetId })
|
|
947
1134
|
return
|
|
948
1135
|
}
|
|
949
1136
|
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
/* Still time, add as normal overlap at the end */
|
|
961
|
-
tweenPosition = () => `>${tweenOverlap}`
|
|
962
|
-
} else {
|
|
963
|
-
/* Won't make it */
|
|
964
|
-
tweenPosition = () => section.timeline.time()
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
} else {
|
|
968
|
-
tweenPosition = () => '>'
|
|
969
|
-
}
|
|
1137
|
+
// Calculate delay using our new helper method
|
|
1138
|
+
const delay = this.calculateDelay(section, tweenDuration, tweenOverlap)
|
|
1139
|
+
|
|
1140
|
+
// Initial state should already be set during ready()
|
|
1141
|
+
// Only log for debugging
|
|
1142
|
+
logMoonwalk('TweenJS', 'Element should already have initial state', {
|
|
1143
|
+
target: targetId,
|
|
1144
|
+
expectedFrom: tweenTransition.from,
|
|
1145
|
+
})
|
|
1146
|
+
logComputedStyle(target, ['opacity', 'transform', 'x', 'y'])
|
|
970
1147
|
|
|
971
|
-
|
|
1148
|
+
// Extract ease from to values (GSAP format) and convert to Motion easing option
|
|
1149
|
+
const { ease, ...toValues } = tweenTransition.to
|
|
1150
|
+
const easingOption = convertEasing(ease || 'easeOut')
|
|
972
1151
|
|
|
973
|
-
|
|
974
|
-
|
|
1152
|
+
logMoonwalk('TweenJS', 'Starting animation', {
|
|
1153
|
+
target: targetId,
|
|
1154
|
+
toValues,
|
|
975
1155
|
duration: tweenDuration,
|
|
976
|
-
|
|
977
|
-
|
|
1156
|
+
delay: delay.toFixed(3),
|
|
1157
|
+
ease: easingOption,
|
|
1158
|
+
})
|
|
1159
|
+
|
|
1160
|
+
// Animate to final state
|
|
1161
|
+
const animation = animate(target, toValues, {
|
|
1162
|
+
duration: tweenDuration,
|
|
1163
|
+
delay,
|
|
1164
|
+
ease: easingOption,
|
|
1165
|
+
})
|
|
978
1166
|
|
|
979
|
-
|
|
1167
|
+
// Use .finished promise for completion callback
|
|
1168
|
+
if (animation && animation.finished) {
|
|
1169
|
+
animation.finished
|
|
1170
|
+
.then(() => {
|
|
1171
|
+
logMoonwalk('TweenJS', 'Animation completed', { target: targetId })
|
|
1172
|
+
target.setAttribute('data-moonwalked', '')
|
|
1173
|
+
})
|
|
1174
|
+
.catch((err) => {
|
|
1175
|
+
// Animation cancelled or failed, still mark as walked
|
|
1176
|
+
logMoonwalk('TweenJS', 'Animation failed/cancelled', {
|
|
1177
|
+
target: targetId,
|
|
1178
|
+
error: err,
|
|
1179
|
+
})
|
|
1180
|
+
target.setAttribute('data-moonwalked', '')
|
|
1181
|
+
})
|
|
1182
|
+
} else {
|
|
1183
|
+
// No animation object returned, mark immediately
|
|
1184
|
+
logMoonwalk('TweenJS', 'No animation object returned', { target: targetId })
|
|
1185
|
+
target.setAttribute('data-moonwalked', '')
|
|
1186
|
+
}
|
|
980
1187
|
|
|
1188
|
+
// Optional separate alpha animation
|
|
981
1189
|
if (alphaTween) {
|
|
982
|
-
|
|
983
|
-
target,
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
)
|
|
1190
|
+
logMoonwalk('TweenJS', 'Adding alpha tween', {
|
|
1191
|
+
target: targetId,
|
|
1192
|
+
duration: alphaTween.duration,
|
|
1193
|
+
delay: (delay + (alphaTween.delay || 0)).toFixed(3),
|
|
1194
|
+
})
|
|
1195
|
+
animate(target, { opacity: 1 }, {
|
|
1196
|
+
duration: alphaTween.duration,
|
|
1197
|
+
ease: convertEasing(alphaTween.ease || 'easeIn'),
|
|
1198
|
+
delay: delay + (alphaTween.delay || 0),
|
|
1199
|
+
})
|
|
992
1200
|
}
|
|
1201
|
+
|
|
1202
|
+
// Update animation state for next element
|
|
1203
|
+
this.updateAnimationState(section, delay, tweenDuration)
|
|
993
1204
|
}
|
|
994
1205
|
|
|
995
1206
|
/**
|
|
@@ -1009,47 +1220,35 @@ export default class Moonwalk {
|
|
|
1009
1220
|
tweenTransition,
|
|
1010
1221
|
tweenOverlap
|
|
1011
1222
|
) {
|
|
1012
|
-
let tweenPosition
|
|
1013
|
-
const startingPoint = tweenDuration - tweenOverlap * -1
|
|
1014
|
-
|
|
1015
1223
|
if (Dom.hasAttribute(target, 'data-moonwalked')) {
|
|
1016
1224
|
return
|
|
1017
1225
|
}
|
|
1018
1226
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
so insert at current time in timeline instead */
|
|
1026
|
-
tweenPosition = () => section.timeline.time()
|
|
1027
|
-
} else {
|
|
1028
|
-
if (currentTime + tweenOverlap * -1 < lastTweenEndTime) {
|
|
1029
|
-
/* Still time, add as normal overlap at the end */
|
|
1030
|
-
tweenPosition = () => `>${tweenOverlap}`
|
|
1031
|
-
} else {
|
|
1032
|
-
/* Won't make it */
|
|
1033
|
-
tweenPosition = () => section.timeline.time()
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
} else {
|
|
1037
|
-
tweenPosition = () => '>'
|
|
1038
|
-
}
|
|
1227
|
+
// Calculate delay using our helper method for stagger effect
|
|
1228
|
+
const calculatedDelay = this.calculateDelay(
|
|
1229
|
+
section,
|
|
1230
|
+
tweenDuration,
|
|
1231
|
+
tweenOverlap
|
|
1232
|
+
)
|
|
1039
1233
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
)
|
|
1053
|
-
|
|
1234
|
+
const targetId = target.getAttribute('data-testid') || target.className
|
|
1235
|
+
|
|
1236
|
+
logMoonwalk('TweenCSS', 'Scheduling CSS animation', {
|
|
1237
|
+
target: targetId,
|
|
1238
|
+
delay: calculatedDelay.toFixed(3),
|
|
1239
|
+
duration: tweenDuration,
|
|
1240
|
+
})
|
|
1241
|
+
|
|
1242
|
+
// Add class after delay to trigger CSS transition
|
|
1243
|
+
delayedCall(calculatedDelay, () => {
|
|
1244
|
+
logMoonwalk('TweenCSS', 'Adding moonwalked attribute', {
|
|
1245
|
+
target: targetId,
|
|
1246
|
+
})
|
|
1247
|
+
target.classList.add('moonwalked')
|
|
1248
|
+
target.setAttribute('data-moonwalked', '')
|
|
1249
|
+
})
|
|
1250
|
+
|
|
1251
|
+
// Update animation state for next element in section
|
|
1252
|
+
this.updateAnimationState(section, calculatedDelay, tweenDuration)
|
|
1054
1253
|
}
|
|
1055
1254
|
}
|