@@ -6,31 +6,27 @@ class Marquee {
66 this . container = _container ;
77 this . elements = Array . from ( this . container . children ) ;
88 if ( this . elements . length === 0 ) throw new Error ( "No elements found inside the marquee container." ) ;
9-
9+
1010 this . speed = _container . getAttribute ( 'wt-marquee-speed' ) || 50 ;
11- this . direction = _container . getAttribute ( 'wt-marquee-direction' ) || 'left' ; // Possible values: 'left', 'right', 'top', 'bottom'
12- this . isVertical = this . direction === 'top' || this . direction === 'bottom' ; // Detect if vertical
11+ this . direction = _container . getAttribute ( 'wt-marquee-direction' ) || 'left' ; // 'left', 'right', 'top', 'bottom'
12+ this . isVertical = this . direction === 'top' || this . direction === 'bottom' ;
1313 this . parentSize = this . isVertical ? this . container . parentElement . offsetHeight : this . container . parentElement . offsetWidth ;
14- this . totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
15- this . scrollPosition = 0 ;
1614 this . gapSize = this . getGapSize ( ) ;
1715
16+ this . scrollPosition = 0 ;
17+ this . totalSize = this . calculateTotalSize ( ) ;
1818 this . fillContainer ( ) ;
19+ this . setMarqueeStyles ( ) ;
1920 this . startMarquee ( ) ;
2021 this . handleResize ( ) ;
2122 } catch ( err ) {
2223 console . error ( `Error initializing Marquee: ${ err . message } ` ) ;
2324 }
2425 }
2526
26- calculateTotalWidth ( ) {
27- const gapTotal = ( this . elements . length - 1 ) * this . gapSize ;
28- return this . elements . reduce ( ( total , el ) => total + el . offsetWidth , 0 ) + gapTotal ;
29- }
30-
31- calculateTotalHeight ( ) {
27+ calculateTotalSize ( ) {
3228 const gapTotal = ( this . elements . length - 1 ) * this . gapSize ;
33- return this . elements . reduce ( ( total , el ) => total + el . offsetHeight , 0 ) + gapTotal ;
29+ return this . elements . reduce ( ( total , el ) => total + ( this . isVertical ? el . offsetHeight : el . offsetWidth ) , 0 ) + gapTotal ;
3430 }
3531
3632 getGapSize ( ) {
@@ -39,66 +35,76 @@ class Marquee {
3935 }
4036
4137 fillContainer ( ) {
42- let totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
43- const targetSize = this . parentSize * 1.5 ;
44-
38+ let totalSize = this . calculateTotalSize ( ) ;
39+ const targetSize = this . parentSize * 1.5 ;
40+
4541 while ( totalSize < targetSize ) {
4642 this . elements . forEach ( el => {
4743 const clone = el . cloneNode ( true ) ;
4844 this . container . appendChild ( clone ) ;
4945 } ) ;
5046 this . elements = Array . from ( this . container . children ) ;
51- totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
47+ totalSize = this . calculateTotalSize ( ) ;
5248 }
5349 }
5450
51+ setMarqueeStyles ( ) {
52+ this . container . style . display = 'flex' ;
53+ this . container . style . flexDirection = this . isVertical ? 'column' : 'row' ;
54+ this . container . style . whiteSpace = 'nowrap' ;
55+ this . container . style . position = 'relative' ;
56+ }
57+
5558 startMarquee ( ) {
5659 this . marqueeInterval = setInterval ( ( ) => {
57- // Adjust scroll position based on the direction
58- if ( this . direction === 'left' || this . direction === 'top' ) {
59- this . scrollPosition -= 1 ;
60- } else {
61- this . scrollPosition += 1 ;
62- }
63-
60+ this . scrollPosition += ( this . direction === 'left' || this . direction === 'top' ) ? - 1 : 1 ;
6461 this . moveOffscreenElement ( ) ;
6562
6663 if ( this . isVertical ) {
67- this . container . style . transform = `translateY( ${ this . scrollPosition } px)` ;
64+ this . container . style . transform = `translate3d(0, ${ this . scrollPosition } px, 0 )` ;
6865 } else {
69- this . container . style . transform = `translateX (${ this . scrollPosition } px)` ;
66+ this . container . style . transform = `translate3d (${ this . scrollPosition } px, 0, 0 )` ;
7067 }
7168 } , this . speed ) ;
7269 }
7370
7471 moveOffscreenElement ( ) {
7572 const firstElement = this . container . firstElementChild ;
73+ const lastElement = this . container . lastElementChild ;
74+
7675 const firstElementSize = this . isVertical ? firstElement . offsetHeight : firstElement . offsetWidth ;
7776 const firstElementTotalSize = firstElementSize + this . gapSize ;
7877
79- if ( ( this . direction === 'left' || this . direction === 'top' ) && this . scrollPosition <= - firstElementTotalSize ) {
80- this . container . style . transition = 'none' ;
81- this . container . appendChild ( firstElement ) ;
82- this . scrollPosition += firstElementTotalSize ;
83- requestAnimationFrame ( ( ) => {
84- this . container . style . transition = '' ;
85- } ) ;
86- } else if ( ( this . direction === 'right' || this . direction === 'bottom' ) && this . scrollPosition >= - firstElementTotalSize / 2 ) {
87- const lastElement = this . container . lastElementChild ;
88- this . container . style . transition = 'none' ;
89- this . container . insertBefore ( lastElement , firstElement ) ;
90- this . scrollPosition -= firstElementTotalSize ;
91- requestAnimationFrame ( ( ) => {
92- this . container . style . transition = '' ;
93- } ) ;
78+ const lastElementSize = this . isVertical ? lastElement . offsetHeight : lastElement . offsetWidth ;
79+ const lastElementTotalSize = lastElementSize + this . gapSize ;
80+
81+ if ( this . direction === 'left' || this . direction === 'top' ) {
82+ if ( this . scrollPosition <= - firstElementTotalSize ) {
83+ this . container . style . transition = 'none' ;
84+ this . container . appendChild ( firstElement ) ;
85+ this . scrollPosition += firstElementTotalSize ;
86+ requestAnimationFrame ( ( ) => {
87+ this . container . style . transition = '' ;
88+ } ) ;
89+ }
90+ } else if ( this . direction === 'right' || this . direction === 'bottom' ) {
91+ if ( this . scrollPosition >= - firstElementTotalSize / 2 ) {
92+ this . container . style . transition = 'none' ;
93+ this . container . insertBefore ( lastElement , firstElement ) ;
94+ this . scrollPosition -= lastElementTotalSize ;
95+ requestAnimationFrame ( ( ) => {
96+ this . container . style . transition = '' ;
97+ } ) ;
98+ }
9499 }
95100 }
96101
102+
97103 handleResize ( ) {
98104 window . addEventListener ( 'resize' , ( ) => {
99105 clearInterval ( this . marqueeInterval ) ;
100106 this . parentSize = this . isVertical ? this . container . parentElement . offsetHeight : this . container . parentElement . offsetWidth ;
101- this . totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
107+ this . totalSize = this . calculateTotalSize ( ) ;
102108 this . fillContainer ( ) ;
103109 this . startMarquee ( ) ;
104110 } ) ;
@@ -111,13 +117,11 @@ class Marquee {
111117
112118const InitializeMarquee = ( ) => {
113119 try {
114- window . trickeries = window . trickeries || [ ] ;
115120 const marqueeContainers = document . querySelectorAll ( '[wt-marquee-element="container"]' ) ;
116121 if ( ! marqueeContainers || marqueeContainers . length === 0 ) throw new Error ( "No marquee containers found." ) ;
117122
118123 marqueeContainers . forEach ( container => {
119- let instance = new Marquee ( container ) ;
120- window . trickeries . push ( { 'Marquee' : instance } ) ;
124+ new Marquee ( container ) ;
121125 } ) ;
122126 } catch ( err ) {
123127 console . error ( `Error in InitializeMarquee: ${ err . message } ` ) ;
@@ -128,4 +132,4 @@ if (/complete|interactive|loaded/.test(document.readyState)) {
128132 InitializeMarquee ( ) ;
129133} else {
130134 window . addEventListener ( 'DOMContentLoaded' , InitializeMarquee ) ;
131- }
135+ } ;
0 commit comments