html, body {
max-width: 100%;
overflow-x: hidden;
}
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
body {
background: #111;
color: white;
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
overflow-x: hidden;
}
.controls {
margin-bottom: 0px;
}
.slider-container {
width: 100%;
overflow: hidden;
position: relative;
}
.slider-track {
display: flex;
/*animation: scroll 10s linear infinite;*/
width: max-content;
}
.slider {
display: flex;
gap: 30px; /* plus simple que margin-right */
}
.image-container {
position: relative;
/*margin-right: 30px; /* <- ajoute de l'espace */
border-radius: 0px;
overflow: hidden;
}
.image-container img {
display: block;
width: 100%; /* 90% de la largeur de l’écran */
max-width: 500px; /* sur grand écran, garde 500px max */
height: clamp(220px, 60vh, 520px);
object-fit: cover;
transition: transform 0.3s ease;
border-radius: 0px;
user-select: none;
pointer-events: auto; /* autorise hover et click, mais empêche sélection */
}
.image-container:hover img {
transform: scale(1.2);
z-index: 10;
}
.caption {
position: absolute;
bottom: 10px;
left: 0;
width: 100%;
background: rgba(0, 0, 0, 0.6);
color: white;
text-align: center;
font-size: 14px;
padding: 8px 0;
opacity: 0;
transform: translateY(20px);
transition: opacity 0.4s ease, transform 0.4s ease;
pointer-events: none;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.image-container:hover .caption {
opacity: 1;
transform: translateY(0);
pointer-events: auto; /* activé si actif */
}
.slider-track:hover {
animation-play-state: paused;
}
@keyframes scroll {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
/* N’applique le zoom au survol que si l’appareil a un vrai “hover” (desktop) */
@media (hover: hover) and (pointer: fine) {
.image-container:hover img {
transform: scale(1.08);
z-index: 10;
}
}
/* Optionnel : désactiver la transition lourde sur mobile pour lisser le scroll */
@media (hover: none) {
.image-container img {
transition: none;
}
.controls input[type=range] {
width: 0%;
}
}
<!–
–>
(function () {
var isMobile = matchMedia(‘(max-width: 768px)’).matches;
if (!isMobile) return;
// 1) Couper le smooth natif du navigateur (au cas où il a été forcé)
try { document.documentElement.style.scrollBehavior = ‘auto’; } catch(e){}
// 2) Neutraliser les écouteurs scroll/touch “lourds”
// (les libs ignorent généralement cet override mais on tente)
try {
window.addEventListener(‘scroll’, function(){}, {passive:true});
window.addEventListener(‘touchmove’, function(){}, {passive:true});
} catch(e){}
// 3) Si certaines libs globales existent, on les ralentit/arrête
// GSAP ScrollSmoother / ScrollTrigger
if (window.ScrollTrigger && ScrollTrigger.config) {
try { ScrollTrigger.config({ ignoreMobileResize: true }); } catch(e){}
try { ScrollTrigger.getAll().forEach(t => t.disable && t.disable()); } catch(e){}
}
if (window.ScrollSmoother && ScrollSmoother.get) {
try { ScrollSmoother.get().paused(true); } catch(e){}
}
// Lenis
if (window.lenis) {
try { window.lenis.stop && window.lenis.stop(); } catch(e){}
}
// Locomotive Scroll
if (window.locoScroll) {
try { window.locoScroll.stop && window.locoScroll.stop(); } catch(e){}
}
// Swiper: désactiver “momentum” si carrousel
if (window.Swiper) {
try {
document.querySelectorAll(‘.swiper’).forEach(function(el){
if (el.swiper && el.swiper.params && el.swiper.params.freeMode) {
el.swiper.params.freeMode.momentum = false;
}
});
} catch(e){}
}
})();
const track = document.getElementById(‘sliderTrack’);
const speedInput = document.getElementById(‘speed’);
const sliderContainer = document.querySelector(‘.slider-container’);
let speed = parseFloat(speedInput.value); // en px/s
let paused = false;
// Duplique une seule fois pour la boucle infinie
track.innerHTML += track.innerHTML;
// Pré-calcul des largeurs pour éviter les reflows répétés
let halfWidth = track.scrollWidth / 2;
let translateX = 0;
// Active le GPU
track.style.transform = ‘translate3d(0,0,0)’;
sliderContainer.addEventListener(‘mouseenter’, () => { paused = true; });
sliderContainer.addEventListener(‘mouseleave’, () => { paused = false; });
// rAF avec delta temps (indépendant du framerate)
let lastTime = performance.now();
function animate(now = performance.now()) {
const dt = (now – lastTime) / 1000; // secondes
lastTime = now;
if (!paused) {
translateX -= speed * dt; // défile vers la gauche
// Réinitialise sans reflow lourd
if (-translateX >= halfWidth) {
translateX += halfWidth; // garde l’offset dans [ -halfWidth ; 0 ]
}
track.style.transform = `translate3d(${translateX}px,0,0)`;
}
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
// Vitesse dynamique (px/s)
speedInput.addEventListener(‘input’, () => {
speed = parseFloat(speedInput.value) * 50; // ajuste le facteur si tu veux
});
// Recalcule si les images chargent et changent la largeur
window.addEventListener(‘load’, () => {
halfWidth = track.scrollWidth / 2;
});
window.addEventListener(‘resize’, () => {
halfWidth = track.scrollWidth / 2;
});
// Tap pour afficher les légendes sur mobile (inchangé)
document.querySelectorAll(‘.image-container’).forEach(img => {
img.addEventListener(‘click’, () => {
const caption = img.querySelector(‘.caption’);
document.querySelectorAll(‘.caption’).forEach(c => c.classList.remove(‘active’));
caption.classList.toggle(‘active’);
});
});
// Désactiver clic droit & drag
document.querySelectorAll(‘.image-container img’).forEach(img => {
img.addEventListener(‘contextmenu’, (e) => e.preventDefault(), { passive: true });
img.setAttribute(‘draggable’, ‘false’);
});
// Pause quand l’onglet est masqué (batterie + perf)
document.addEventListener(‘visibilitychange’, () => {
paused = document.hidden ? true : false;
if (!document.hidden) lastTime = performance.now();
});
const track = document.getElementById(‘sliderTrack’);
const speedInput = document.getElementById(‘speed’);
const sliderContainer = document.querySelector(‘.slider-container’);
let speed = parseFloat(speedInput.value);
let scrollAmount = 0;
let paused = false;
// Dupliquer le contenu pour faire une boucle infinie
track.innerHTML += track.innerHTML;
// — PAUSE AU SURVOL —
// Quand on passe la souris (hover)
sliderContainer.addEventListener(‘mouseenter’, () => {
paused = true;
});
// Quand on quitte le hover
sliderContainer.addEventListener(‘mouseleave’, () => {
paused = false;
});
// — FONCTION ANIMATE —
function animate() {
if (!paused) {
scrollAmount += speed;
if (scrollAmount >= track.scrollWidth / 2) {
scrollAmount = 0;
}
track.style.transform = `translateX(${-scrollAmount}px)`;
}
requestAnimationFrame(animate);
}
animate();
// — VITESSE DYNAMIQUE —
speedInput.addEventListener(« input », () => {
speed = parseFloat(speedInput.value);
});
// — CAPTION CLICK POUR MOBILE —
const images = document.querySelectorAll(‘.image-container’);
images.forEach(img => {
img.addEventListener(‘click’, () => {
const caption = img.querySelector(‘.caption’);
if (caption.classList.contains(‘active’)) {
caption.classList.remove(‘active’);
} else {
document.querySelectorAll(‘.caption’).forEach(c => c.classList.remove(‘active’));
caption.classList.add(‘active’);
}
});
// Désactiver le clic droit sur les images
document.querySelectorAll(‘.image-container img’).forEach(img => {
img.addEventListener(‘contextmenu’, (e) => {
e.preventDefault();
});
// Désactiver le glisser-déposer
img.setAttribute(‘draggable’, ‘false’);
});
});
DECHU
IDOLE
TRANSE
ARGENT MONSTRE
HELL’Z AMERE
AVANTASIA
COQ EN SPACE
PAS SAGE ROBOT
PAS SAGE ROBOT