<div class="container-rullo">
<div class="rullo-3d" id="rullo">
<div class="item" style="--i:0;"><a href=""><img src=""></a></div>
<div class="item" style="--i:1;"><a href=""><img src=""></a></div>
<div class="item" style="--i:2;"><a href=""><img src=""></a></div>
<div class="item" style="--i:3;"><a href=""><img src=""></a></div>
<div class="item" style="--i:4;"><a href=""><img src=""></a></div>
<div class="item" style="--i:5;"><a href=""><img src=""></a></div>
<div class="item" style="--i:6;"><a href=""><img src=""></a></div>
<div class="item" style="--i:7;"><a href=""><img src=""></a></div>
</div>
</div>
<style>
.container-rullo {
height: 350px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
perspective: 1500px;
background: transparent;
touch-action: pan-y;
width: 100%;
}
.rullo-3d {
position: relative;
width: 120px;
height: 180px;
transform-style: preserve-3d;
transform: rotateY(0deg);
}
.item {
position: absolute;
inset: 0;
transform: rotateY(calc(var(--i) * 45deg)) translateZ(180px);
}
.item img {
width: 100%;
height: 100%;
border-radius: 12px;
object-fit: cover;
border: 2px solid rgba(255, 255, 255, 0.8);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);
/* Rimosso backface-visibility hidden per evitare "buchi" durante la rotazione veloce */
}
(max-width: 480px) {
.container-rullo {
height: 280px;
}
.item {
transform: rotateY(calc(var(--i) * 45deg)) translateZ(150px);
}
.rullo-3d {
width: 90px;
height: 130px;
}
}
</style>
<script>
const tuttiIRulli = document.querySelectorAll('.rullo-3d');
tuttiIRulli.forEach((rullo) => {
let isDragging = false;
let isHovered = false;
let startX;
let currentRotation = 0;
// --- TURBO AUTOMATICO (Gira piano da solo) ---
// Usiamo di nuovo il setInterval che avevi, è più facile da gestire
setInterval(() => {
if (!isDragging && !isHovered) {
currentRotation += 0.5; // Questa è la velocità (0.5 è piano)
rullo.style.transform = `rotateY(${currentRotation}deg)`;
}
}, 30);
// --- BLOCCA QUANDO PASSI SOPRA CON IL MOUSE ---
rullo.addEventListener('mouseenter', () => isHovered = true);
rullo.addEventListener('mouseleave', () => isHovered = false);
// --- TRASCINAMENTO (Gira quando vuoi tu) ---
rullo.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.pageX;
});
window.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const deltaX = e.pageX - startX;
currentRotation += deltaX * 0.4; // Sensibilità del tocco
rullo.style.transform = `rotateY(${currentRotation}deg)`;
startX = e.pageX;
});
window.addEventListener('mouseup', () => {
isDragging = false;
});
// --- TOCCO PER TELEFONI ---
rullo.addEventListener('touchstart', (e) => {
isDragging = true;
isHovered = true;
startX = e.touches[0].pageX;
});
window.addEventListener('touchend', () => {
isDragging = false;
isHovered = false;
});
window.addEventListener('touchmove', (e) => {
if (!isDragging) return;
const deltaX = e.touches[0].pageX - startX;
currentRotation += deltaX * 0.4;
rullo.style.transform = `rotateY(${currentRotation}deg)`;
startX = e.touches[0].pageX;
});
});
</script>Ciao a tutti! Creo per passione, parto dalle mie idee e mi faccio dare una mano dall'AI per la sintassi o quando mi incastro. Mettendo un po' di ordine nel caos dei miei vecchi progetti, ho ritrovato questo codice che avevo scritto un po' di tempo fa per creare un rullo 3D interattivo. È roba molto semplice: So bene che per i dev più esperti sarà una cosa banale, ma per me che ho fatto tutto da autodidatta ha ancora un fascino speciale ogni volta che lo vedo girare. Vi lascio il codice qui sotto, che ne pensate? CSS3D per la prospettiva e la rotazione delle card (transform-style: preserve-3d). Vanilla JS puro per la rotazione automatica e la gestione del trascinamento (mouse e touch per il telefono).
P.S. Lo so che i programmatori esperti lo sanno già, ma ci tengo a dirlo per chiarezza: se volete mettere più rulli di fila uno sopra l'altro, vi basta duplicare il blocco HTML del container. Il JS usa *, quindi si prende tutti i rulli in automatico senza dover aggiungere altri script o motori sotto!* querySelectorAll