@@ -6,11 +6,12 @@ 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- this . speed = _container . getAttribute ( 'wt-marquee-speed' ) || 50 ;
10- this . direction = _container . getAttribute ( 'wt-marquee-direction' ) || 'left'
11- this . viewportWidth = window . innerWidth ;
12- this . parentWidth = this . container . parentElement . offsetWidth ;
13- this . totalWidth = this . calculateTotalWidth ( ) ;
9+
10+ 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
13+ this . parentSize = this . isVertical ? this . container . parentElement . offsetHeight : this . container . parentElement . offsetWidth ;
14+ this . totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
1415 this . scrollPosition = 0 ;
1516 this . gapSize = this . getGapSize ( ) ;
1617
@@ -27,51 +28,66 @@ class Marquee {
2728 return this . elements . reduce ( ( total , el ) => total + el . offsetWidth , 0 ) + gapTotal ;
2829 }
2930
31+ calculateTotalHeight ( ) {
32+ const gapTotal = ( this . elements . length - 1 ) * this . gapSize ;
33+ return this . elements . reduce ( ( total , el ) => total + el . offsetHeight , 0 ) + gapTotal ;
34+ }
35+
3036 getGapSize ( ) {
3137 const styles = getComputedStyle ( this . container ) ;
3238 return parseFloat ( styles . gap ) || 0 ;
3339 }
3440
3541 fillContainer ( ) {
36- let totalWidth = this . calculateTotalWidth ( ) ;
37- const targetWidth = this . parentWidth * 1.5 ;
42+ let totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
43+ const targetSize = this . parentSize * 1.5 ;
3844
39- while ( totalWidth < targetWidth ) {
45+ while ( totalSize < targetSize ) {
4046 this . elements . forEach ( el => {
4147 const clone = el . cloneNode ( true ) ;
4248 this . container . appendChild ( clone ) ;
4349 } ) ;
4450 this . elements = Array . from ( this . container . children ) ;
45- totalWidth = this . calculateTotalWidth ( ) ;
51+ totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
4652 }
4753 }
4854
4955 startMarquee ( ) {
5056 this . marqueeInterval = setInterval ( ( ) => {
51- this . scrollPosition += this . direction === 'left' ? - 1 : 1 ;
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+ }
5263
5364 this . moveOffscreenElement ( ) ;
5465
55- this . container . style . transform = `translateX(${ this . scrollPosition } px)` ;
66+ if ( this . isVertical ) {
67+ this . container . style . transform = `translateY(${ this . scrollPosition } px)` ;
68+ } else {
69+ this . container . style . transform = `translateX(${ this . scrollPosition } px)` ;
70+ }
5671 } , this . speed ) ;
5772 }
5873
5974 moveOffscreenElement ( ) {
6075 const firstElement = this . container . firstElementChild ;
61- const firstElementWidth = firstElement . offsetWidth + this . gapSize ;
76+ const firstElementSize = this . isVertical ? firstElement . offsetHeight : firstElement . offsetWidth ;
77+ const firstElementTotalSize = firstElementSize + this . gapSize ;
6278
63- if ( this . direction === 'left' && this . scrollPosition <= - firstElementWidth ) {
79+ if ( ( this . direction === 'left' || this . direction === 'top' ) && this . scrollPosition <= - firstElementTotalSize ) {
6480 this . container . style . transition = 'none' ;
6581 this . container . appendChild ( firstElement ) ;
66- this . scrollPosition += firstElementWidth ;
82+ this . scrollPosition += firstElementTotalSize ;
6783 requestAnimationFrame ( ( ) => {
6884 this . container . style . transition = '' ;
6985 } ) ;
70- } else if ( this . direction === 'right' && this . scrollPosition >= - firstElementWidth / 2 ) {
86+ } else if ( ( this . direction === 'right' || this . direction === 'bottom' ) && this . scrollPosition >= - firstElementTotalSize / 2 ) {
7187 const lastElement = this . container . lastElementChild ;
7288 this . container . style . transition = 'none' ;
7389 this . container . insertBefore ( lastElement , firstElement ) ;
74- this . scrollPosition -= firstElementWidth ;
90+ this . scrollPosition -= firstElementTotalSize ;
7591 requestAnimationFrame ( ( ) => {
7692 this . container . style . transition = '' ;
7793 } ) ;
@@ -81,9 +97,8 @@ class Marquee {
8197 handleResize ( ) {
8298 window . addEventListener ( 'resize' , ( ) => {
8399 clearInterval ( this . marqueeInterval ) ;
84- this . viewportWidth = window . innerWidth ;
85- this . parentWidth = this . container . parentElement . offsetWidth ;
86- this . totalWidth = this . calculateTotalWidth ( ) ;
100+ this . parentSize = this . isVertical ? this . container . parentElement . offsetHeight : this . container . parentElement . offsetWidth ;
101+ this . totalSize = this . isVertical ? this . calculateTotalHeight ( ) : this . calculateTotalWidth ( ) ;
87102 this . fillContainer ( ) ;
88103 this . startMarquee ( ) ;
89104 } ) ;
0 commit comments