360 graden draaien Nieuw
Een product dat je rond sleept door een reeks van 36 opnamen (om de 10 graden), zoals webshops met een draaitafel-fotoset doen. Alle frames staan in één sprite (6 x 6), dus één verzoek en direct wisselen. Slepen met muis of vinger met uitloop, pijltjestoetsen per 10 graden, Home voor de voorkant, en een knop om zelf te laten draaien (start niet vanzelf, uit bij minder beweging).
Mok Lekstroom
Steengoed, 0,3 liter
€ 18,50
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen.
- Zet de CSS in je stylesheet. Alle klassen hebben een eigen voorvoegsel, dus niets botst met je eigen opmaak.
- Voeg de JavaScript toe en roep init() aan met het element waar de HTML in staat.
<!-- 360 graden draaien · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="d36"><div class="d36__in">
<div class="d36__view" tabindex="0" role="slider" aria-label="Mok Lekstroom, sleep of gebruik de pijltjes om te draaien" aria-valuemin="0" aria-valuemax="350" aria-valuenow="0" aria-valuetext="Voorkant, 0 graden">
<div class="d36__img" role="img" aria-label="Witte mok met oranje band en handvat"></div>
<span class="d36__hint" aria-hidden="true"><svg viewBox="0 0 40 16"><path d="M6 8h28M10 4L6 8l4 4M30 4l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>Sleep om te draaien</span>
</div>
<div class="d36__info">
<b class="d36__ti">Mok Lekstroom</b>
<span class="d36__me">Steengoed, 0,3 liter</span>
<span class="d36__pr">€ 18,50</span>
<div class="d36__deg" aria-hidden="true"><i class="d36__dot"></i></div>
<button class="d36__auto" type="button" aria-pressed="false">Laat draaien</button>
</div>
</div></div>
</div>/* 360 graden draaien · NedDev · eigen werk. */
.d36{position:absolute;inset:0;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',sans-serif;text-align:left}
.d36__view{position:relative;display:grid;place-items:center;cursor:grab;touch-action:pan-y;outline:none;user-select:none;-webkit-user-select:none}
.d36__view:active{cursor:grabbing}
.d36__view:focus-visible{box-shadow:inset 0 0 0 2px #F5480F}
.d36__img{width:min(96%,calc(100cqh * 1.2));aspect-ratio:360/300;background:url("https://neddev.com/lab-media/draai-360-1.webp") 0 0/600% 600% no-repeat}
.d36{container-type:size}
.d36__in{position:absolute;inset:0;display:grid;grid-template-columns:1fr 132px}
.d36__hint{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);display:flex;align-items:center;gap:6px;font:500 12px/1 'Switzer',sans-serif;color:#55524d;white-space:nowrap;transition:opacity .4s}
.d36__hint svg{width:30px;height:12px}
.d36.is-used .d36__hint{opacity:0}
.d36__info{display:flex;flex-direction:column;justify-content:center;gap:6px;padding:14px 14px 14px 0}
.d36__ti{font:600 16px/1.2 'Switzer',sans-serif;letter-spacing:-.01em}
.d36__me{font:400 13px/1.4 'Switzer',sans-serif;color:#55524d}
.d36__pr{font:600 14px/1.2 'Switzer',sans-serif;font-variant-numeric:tabular-nums}
.d36__deg{position:relative;width:40px;height:40px;margin:6px 0 4px;border:1.5px solid #0a0a0a;border-radius:50%}
.d36__dot{position:absolute;left:50%;top:50%;width:8px;height:8px;margin:-4px 0 0 -4px;border-radius:50%;background:#F5480F;transform:rotate(var(--a,0deg)) translateY(17px)}
.d36__auto{align-self:flex-start;min-height:32px;padding:0 12px;border:1.5px solid #0a0a0a;border-radius:4px;background:#fff;color:#0a0a0a;font:500 13px/1 'Switzer',sans-serif;cursor:pointer}
.d36__auto[aria-pressed="true"]{background:#0a0a0a;color:#fff}
.d36__auto:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
@container (max-width:360px){.d36__in{grid-template-columns:1fr 118px}.d36__info{padding-right:10px}.d36__ti{font-size:15px}}
@media (prefers-reduced-motion:reduce){.d36__hint{transition:none}.d36__auto{display:none}}// 360 graden draaien · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.d36');if(!w)return;
var view=w.querySelector('.d36__view'),img=w.querySelector('.d36__img'),dot=w.querySelector('.d36__dot'),auto=w.querySelector('.d36__auto');
var N=36,ang=0,vel=0,drag=false,lastX=0,lastT=0,raf=0,spin=false,rm=matchMedia('(prefers-reduced-motion: reduce)').matches;
var names=['Voorkant','Rechterkant','Achterkant','Linkerkant'];
function draw(){var a=((ang%360)+360)%360,fr=Math.round(a/10)%N,c=fr%6,r=Math.floor(fr/6);
img.style.backgroundPosition=(c*20)+'% '+(r*20)+'%';dot.style.setProperty('--a',(fr*10)+'deg');
var deg=fr*10;view.setAttribute('aria-valuenow',deg);view.setAttribute('aria-valuetext',names[Math.round(deg/90)%4]+', '+deg+' graden');}
function loop(t){raf=0;if(spin){ang+=0.6;}else if(!drag&&Math.abs(vel)>.05){ang+=vel;vel*=.93;}else if(!drag){vel=0;return draw();}
draw();raf=requestAnimationFrame(loop);}
function go(){if(!raf)raf=requestAnimationFrame(loop);}
function stopSpin(){if(spin){spin=false;auto.setAttribute('aria-pressed','false');auto.textContent='Laat draaien';}}
view.addEventListener('pointerdown',function(e){drag=true;stopSpin();w.classList.add('is-used');lastX=e.clientX;lastT=performance.now();vel=0;try{view.setPointerCapture(e.pointerId);}catch(_){}});
view.addEventListener('pointermove',function(e){if(!drag)return;var dx=e.clientX-lastX,now=performance.now();ang-=dx*0.9;vel=rm?0:-dx*0.9*Math.min(1,16/Math.max(1,now-lastT));lastX=e.clientX;lastT=now;draw();});
function up(){if(!drag)return;drag=false;if(!rm)go();}
view.addEventListener('pointerup',up);view.addEventListener('pointercancel',up);
view.addEventListener('keydown',function(e){var k=e.key;if(k==='ArrowRight'||k==='ArrowUp')ang+=10;else if(k==='ArrowLeft'||k==='ArrowDown')ang-=10;else if(k==='Home')ang=0;else if(k==='End')ang=180;else return;e.preventDefault();stopSpin();vel=0;w.classList.add('is-used');ang=Math.round(ang/10)*10;draw();});
auto.addEventListener('click',function(){spin=!spin;auto.setAttribute('aria-pressed',spin?'true':'false');auto.textContent=spin?'Stop draaien':'Laat draaien';if(spin){w.classList.add('is-used');go();}});
new IntersectionObserver(function(es){es.forEach(function(e){if(!e.isIntersecting)stopSpin();});}).observe(w);
draw();
}
init(document.querySelector('.jouw-container'));
Meer uit componenten
Iets gezien dat je mooi vindt?
Zet het in je selectie en stuur hem op. Dan bouwen we je site eromheen, in jouw huisstijl.
Neem contact op →