Skip to content

Commit d2a10fb

Browse files
committed
Update: Refactored script and fixed Marquee on top to bottom when multiple sizes were found in the contained elements
1 parent 8db91ed commit d2a10fb

1 file changed

Lines changed: 49 additions & 45 deletions

File tree

Dist/Functional/Marquee.js

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -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

112118
const 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

Comments
 (0)