commit 20260703

This commit is contained in:
2026-07-03 20:34:27 +08:00
parent 296db4a164
commit c1630b8c10
63 changed files with 3497 additions and 1110 deletions
+80
View File
@@ -0,0 +1,80 @@
/**
* Testimonials marquee — same logic as myfundedfutures.com Reviews section:
* - FisherYates shuffle, 3 cards per row
* - 3 rows × 3 duplicate tracks
* - Row speeds: 125s / 75s reverse / 275s (Framer Motion durations → CSS linear)
*/
(function () {
var ROW_CONFIG = [
{ duration: 125, reverse: false },
{ duration: 75, reverse: true },
{ duration: 275, reverse: false },
];
var TRACK_COUNT = 3;
var CARDS_PER_ROW = 3;
function shuffle(list) {
var arr = list.slice();
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
return arr;
}
function pickCards(cards, count) {
return shuffle(cards).slice(0, Math.min(count, cards.length));
}
function buildTrack(cards, duration, reverse, trackIndex) {
var track = document.createElement('div');
track.className =
'au2-testimonials__track' + (reverse ? ' au2-testimonials__track--reverse' : '');
track.style.setProperty('--duration', duration + 's');
if (trackIndex > 0) {
track.setAttribute('aria-hidden', 'true');
}
cards.forEach(function (card) {
track.appendChild(card.cloneNode(true));
});
return track;
}
function buildRow(cards, config) {
var row = document.createElement('div');
row.className = 'au2-testimonials__row';
var picked = pickCards(cards, CARDS_PER_ROW);
for (var i = 0; i < TRACK_COUNT; i++) {
row.appendChild(buildTrack(picked, config.duration, config.reverse, i));
}
return row;
}
function initAu2TestimonialsMarquee() {
var root = document.querySelector('[data-au2-testimonials-marquee]');
if (!root) return;
var source = root.querySelector('.au2-testimonials__source');
var rowsEl = root.querySelector('.au2-testimonials__rows');
if (!source || !rowsEl) return;
var cards = Array.prototype.slice.call(source.querySelectorAll('.au2-testimonial'));
if (!cards.length) return;
ROW_CONFIG.forEach(function (config) {
rowsEl.appendChild(buildRow(cards, config));
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initAu2TestimonialsMarquee);
} else {
initAu2TestimonialsMarquee();
}
})();