WEBLEB
Home
Editor
Login
Pro
English
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Draggable Vertical Rectangles HTML
67
alejandrokundrah
Open In Editor
Publish Your Code
Recommended
26 June 2025
E-Ticaret Sitesi HTML, Tailwind CSS, Alışveriş
5 July 2025
Glitch Effect Homepage: HTML, CSS, Tailwind
26 July 2025
Online HTML Editor | CodeCanvas - Free Web Dev Tool
HTML
Copy
CSS
Copy
*{ box-sizing: border-box; } html, body { margin: 0; padding: 0; } :root { --sz: clamp(24px, min(4vw, 6vh) , 42px); font-size: var(--sz); --bg: #09090a; } body { background: var(--bg); display: flex; flex-direction: row; gap: 1em; justify-content: center; align-items: center; min-height: 100vh; overflow: hidden; } .vert { position: relative; width: 12em; height: 12em; } .drag { --dvar: 0; --xvar: 0; --skew: 16; --line: 1px; --thick: 0.4rem; --clr: gray; position: absolute; top: 0; left: 0; right: 0; height: 4rem; cursor: grab; color: #fff; transform-style: preserve-3d; perspective: 1200px; transition: all ease-out 1s; } .vert.loaded .drag { transform: rotateX(calc( 1deg * ( var(--skew) - ( 2 * var(--skew) * var(--dvar)) ))); } .rect { position: absolute; margin: auto; transform-style: preserve-3d; left:0; right:0; width: 2rem; height: 100%; translate: 4rem; transform-origin: -3rem 50%; box-shadow: inset 0 0 0 var(--line) var(--clr); background: hsl(from var(--bg) h s calc( l + 12) ); background-size: cover; background-position: center; transition: all ease-out 2s; } .vert.loaded { .rect:nth-child(1) { transform: rotateY( calc( 360deg * var(--dvar)) ) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(2) { transform: rotateY( calc( 360deg * ( 1 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(3) { transform: rotateY( calc( 360deg * ( 2 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(4) { transform: rotateY( calc( 360deg * ( 3 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(5) { transform: rotateY( calc( 360deg * ( 4 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(6) { transform: rotateY( calc( 360deg * ( 5 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(7) { transform: rotateY( calc( 360deg * ( 6 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(8) { transform: rotateY( calc( 360deg * ( 7 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(9) { transform: rotateY( calc( 360deg * ( 8 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(10) { transform: rotateY( calc( 360deg * ( 9 /11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } .rect:nth-child(11) { transform: rotateY( calc( 360deg * ( 10/11 + var(--dvar)) )) rotateX( calc( 1deg * var(--xvar))); } } .rect:nth-child(1) { background-image: url('https://picsum.photos/id/43/300'); } .rect:nth-child(2) { background-image: url('https://picsum.photos/id/58/300'); } .rect:nth-child(3) { background-image: url('https://picsum.photos/id/61/300'); } .rect:nth-child(4) { background-image: url('https://picsum.photos/id/79/300'); } .rect:nth-child(5) { background-image: url('https://picsum.photos/id/88/300'); } .rect:nth-child(6) { background-image: url('https://picsum.photos/id/91/300'); } .rect:nth-child(7) { background-image: url('https://picsum.photos/id/115/300'); } .rect:nth-child(8) { background-image: url('https://picsum.photos/id/121/300'); } .rect:nth-child(9) { background-image: url('https://picsum.photos/id/130/300'); } .rect:nth-child(10) { background-image: url('https://picsum.photos/id/192/300'); } .rect:nth-child(11) { background-image: url('https://picsum.photos/id/209/300'); } .rect span:nth-child(1), .rect span:nth-child(2) { position: absolute; width: var(--thick); height: 100%; box-shadow: inset 0 0 0 var(--line) var(--clr); transform-origin: 0% 50%; background: var(--bg); } .rect span:nth-child(1) { transform: rotateY(-90deg); } .rect span:nth-child(2) { transform: rotateY(-90deg); left: 100%; } .rect span:nth-child(3), .rect span:nth-child(4) { position: absolute; width: 100%; height: var(--thick); box-shadow: inset 0 0 0 var(--line) var(--clr); transform-origin: 50% 0%; background: var(--bg); } .rect span:nth-child(3) { transform: rotateX(90deg); } .rect span:nth-child(4) { transform: rotateX(90deg); top: 100%; } .rect span:nth-child(5) { position: absolute; width: 100%; height: 100%; box-shadow: inset 0 0 0 var(--line) var(--clr); transform-origin: 50% 50%; transform: translateZ( var(--thick) ); background: hsl(from var(--bg) h s calc( l - 12) ); }
JS
Copy
const vert = document.querySelector('.vert'); const drag = document.querySelector('.drag'); let isDragging = false; let dragValue = 0; let clickOffsetY = 0; let lastTop = 0; let lastTime = performance.now(); let smoothedVelocity = 0; const velocityStrength = 164; const velocityEase = 0.2; const velocityDecay = 0.1; let lastUpdateTime = 0; let rafId = null; const updateInterval = 10; document.addEventListener("DOMContentLoaded", function() { vert.classList.add('loaded'); }); drag.addEventListener('mousedown', (e) => { lastInteractionTime = performance.now(); if (idleOscillating) idleOscillating = false; isDragging = true; const dragRect = drag.getBoundingClientRect(); clickOffsetY = e.clientY - dragRect.top; document.body.style.userSelect = 'none'; lastTop = drag.offsetTop; lastTime = performance.now(); }); document.addEventListener('mousemove', (e) => { lastInteractionTime = performance.now(); if (!isDragging || rafId) return; if (idleOscillating) idleOscillating = false; rafId = requestAnimationFrame(() => { const now = performance.now(); const deltaTime = now - lastTime; const vertRect = vert.getBoundingClientRect(); let newTop = e.clientY - vertRect.top - clickOffsetY; const maxTop = vert.offsetHeight - drag.offsetHeight; newTop = Math.max(0, Math.min(newTop, maxTop)); drag.style.top = `${newTop}px`; dragValue = newTop / maxTop; if (now - lastUpdateTime >= updateInterval) { const cleanValue = parseFloat(dragValue.toFixed(4)); drag.style.setProperty('--dvar', cleanValue); lastUpdateTime = now; } const deltaPos = newTop - lastTop; const rawVelocity = deltaTime > 0 ? deltaPos / deltaTime : 0; smoothedVelocity += (rawVelocity - smoothedVelocity) * velocityEase; const outputVelocity = Math.max(-velocityStrength, Math.min(velocityStrength, smoothedVelocity * velocityStrength)); drag.style.setProperty('--xvar', outputVelocity.toFixed(4)); lastTop = newTop; lastTime = now; rafId = null; }); }); function easeVelocityToZero() { if (isDragging) { requestAnimationFrame(easeVelocityToZero); return; } smoothedVelocity += (0 - smoothedVelocity) * velocityDecay; const outputVelocity = smoothedVelocity * velocityStrength; drag.style.setProperty('--xvar', outputVelocity.toFixed(4)); if (Math.abs(smoothedVelocity) > 0.001) { requestAnimationFrame(easeVelocityToZero); } } document.addEventListener('mouseup', () => { lastInteractionTime = performance.now(); if (idleOscillating) idleOscillating = false; isDragging = false; document.body.style.userSelect = ''; easeVelocityToZero(); }); let lastInteractionTime = performance.now(); let idleOscillating = false; let idleStartTime = 0; function startIdleOscillation() { if (idleOscillating || isDragging) return; idleOscillating = true; idleStartTime = performance.now(); const vertHeight = vert.offsetHeight - drag.offsetHeight; function animateIdle() { if (isDragging) { idleOscillating = false; return; } const now = performance.now(); const elapsed = (now - idleStartTime) / 1000; const frequency = 0.12; const amplitude = 0.4; const phaseOffset = Math.PI / -2; const dvar = 0.5 + Math.sin(elapsed * 2 * Math.PI * frequency + phaseOffset) * amplitude; const newTop = dvar * vertHeight; drag.style.top = `${newTop}px`; const cleanValue = parseFloat(dvar.toFixed(4)); drag.style.setProperty('--dvar', cleanValue); const deltaTime = now - lastTime; const deltaPos = newTop - lastTop; const rawVelocity = deltaTime > 0 ? deltaPos / deltaTime : 0; smoothedVelocity += (rawVelocity - smoothedVelocity) * velocityEase; const outputVelocity = Math.max(-velocityStrength, Math.min(velocityStrength, smoothedVelocity * velocityStrength)); drag.style.setProperty('--xvar', outputVelocity.toFixed(4)); lastTop = newTop; lastTime = now; requestAnimationFrame(animateIdle); } animateIdle(); } function monitorIdle() { requestAnimationFrame(() => { const now = performance.now(); if (!isDragging && !idleOscillating && now - lastInteractionTime > 3200) { startIdleOscillation(); } monitorIdle(); }); } monitorIdle();