Liquid Dial Control
Home
Snippets
Liquid Dial Control
HTML
CSS
JS
<svg style="position: absolute; width: 0; height: 0;"> <defs> <filter id="liquid-goo"> <feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur" /> <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -8" result="goo" /> <feComposite in="SourceGraphic" in2="goo" operator="atop" /> </filter> </defs> </svg> <div class="slider-wrap" id="slider"> <div class="track"></div> <div class="knob" id="knob"></div> </div>
body { margin: 0; background-color: #050608; height: 100vh; display: flex; justify-content: center; align-items: center; user-select: none; -webkit-user-select: none; } .slider-wrap { position: relative; width: 280px; height: 60px; display: flex; align-items: center; cursor: pointer; filter: url("#liquid-goo"); } .track { position: absolute; width: 100%; height: 8px; background: #1e293b; border-radius: 4px; } .knob { position: absolute; width: 24px; height: 24px; background: #3b82f6; border-radius: 50%; left: 0; transform: translateX(-50%); pointer-events: none; }
const slider = document.getElementById('slider'); const knob = document.getElementById('knob'); let isDragging = false; let currentX = 40; let targetX = 40; let vx = 0; function updatePhysics() { let ax = (targetX - currentX) * 0.25; vx += ax; vx *= 0.75; currentX += vx; knob.style.left = `${currentX}px`; let stretch = 1 + Math.abs(vx) * 0.04; let squash = 1 - Math.abs(vx) * 0.02; knob.style.transform = `translateX(-50%) scale(${stretch}, ${squash})`; requestAnimationFrame(updatePhysics); } function handleMove(clientX) { const rect = slider.getBoundingClientRect(); let relativeX = clientX - rect.left; targetX = Math.max(0, Math.min(relativeX, rect.width)); } slider.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e.clientX); }); window.addEventListener('mousemove', (e) => { if (isDragging) handleMove(e.clientX); }); window.addEventListener('mouseup', () => isDragging = false); slider.addEventListener('touchstart', (e) => { isDragging = true; handleMove(e.touches[0].clientX); }, { passive: true }); window.addEventListener('touchmove', (e) => { if (isDragging) handleMove(e.touches[0].clientX); }, { passive: true }); window.addEventListener('touchend', () => isDragging = false); updatePhysics();
Ad #1
Ad #2
Scroll to Top