let rotationY = 0; let isDragging = false; let lastX = 0;
// Track last few movements to compute real velocity let positions = [];
const friction = 0.93; // higher = longer spin, lower = quicker stop
function updateMomentum() { // Continue momentum only when not dragging if (!isDragging) { // Apply velocity if (positions.velocity) { rotationY += positions.velocity; logo.style.transform = `rotateY(${rotationY}deg)`;
// Apply friction positions.velocity *= friction;
// Loop while there is velocity if (Math.abs(positions.velocity) > 0.01) { requestAnimationFrame(updateMomentum); } } } }
function startDrag(x) { isDragging = true; lastX = x; positions = { lastVelocities: [], velocity: 0 }; // reset }
function dragMove(x) { if (!isDragging) return;
const delta = x - lastX; lastX = x;
rotationY += delta; logo.style.transform = `rotateY(${rotationY}deg)`;
// keep a circular buffer of last few deltas positions.lastVelocities.push(delta); if (positions.lastVelocities.length > 10) { positions.lastVelocities.shift(); }
// store a smoothed velocity const sum = positions.lastVelocities.reduce((a, b) => a + b, 0); positions.velocity = sum / positions.lastVelocities.length; }
function endDrag() { if (!isDragging) return; isDragging = false;
// start momentum animation requestAnimationFrame(updateMomentum); }
// Mouse events logo.addEventListener("mousedown", (e) => { startDrag(e.clientX); e.preventDefault(); }); document.addEventListener("mousemove", (e) => dragMove(e.clientX)); document.addEventListener("mouseup", endDrag);
// Touch events logo.addEventListener("touchstart", (e) => { startDrag(e.touches[0].clientX); e.preventDefault(); }); document.addEventListener("touchmove", (e) => dragMove(e.touches[0].clientX)); document.addEventListener("touchend", endDrag); });