Wereldbol met vestigingen Nieuw
Een draaiende stippenwereldbol op canvas 2D (orthografische projectie, landmasker van 144 x 72 uit Natural Earth, publiek domein) met pins voor vestigingen. Klik een vestiging in de lijst en de bol draait ernaartoe en tekent de lijn vanaf het hoofdkantoor. Slepen of pijltjestoetsen draaien zelf; stilstaand bij minder beweging en buiten beeld. Werkt zonder WebGL, dus overal: voor logistiek, groothandel en bedrijven met kantoren in het buitenland.
Vrachtlijn op 6 plekken
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.
<!-- Wereldbol met vestigingen · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="wbv"><div class="wbv__in">
<canvas class="wbv__cv" tabindex="0" role="img" aria-label="Wereldbol met zes vestigingen van Vrachtlijn. Sleep of gebruik de pijltjestoetsen om te draaien."></canvas>
<div class="wbv__side">
<b class="wbv__h">Vrachtlijn op 6 plekken</b>
<ul class="wbv__list">
<li><button class="wbv__it" type="button" data-i="0" aria-pressed="false">Rotterdam<span>hoofdkantoor</span></button></li>
<li><button class="wbv__it" type="button" data-i="1" aria-pressed="false">Hamburg<span>havenkantoor</span></button></li>
<li><button class="wbv__it" type="button" data-i="2" aria-pressed="false">Gdańsk<span>overslag</span></button></li>
<li><button class="wbv__it" type="button" data-i="3" aria-pressed="false">Valencia<span>douane</span></button></li>
<li><button class="wbv__it" type="button" data-i="4" aria-pressed="false">New York<span>verkoop</span></button></li>
<li><button class="wbv__it" type="button" data-i="5" aria-pressed="false">Singapore<span>Azië</span></button></li>
</ul>
</div>
</div></div>
</div>/* Wereldbol met vestigingen · NedDev · eigen werk. */
.wbv{position:absolute;inset:0;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',sans-serif;text-align:left;container-type:inline-size}
.wbv__in{position:absolute;inset:0;display:grid;grid-template-columns:1fr 176px}
.wbv__cv{display:block;width:100%;height:100%;cursor:grab;touch-action:pan-y;outline:none}
.wbv__cv:active{cursor:grabbing}
.wbv__cv:focus-visible{box-shadow:inset 0 0 0 2px #F5480F}
.wbv__side{display:flex;flex-direction:column;justify-content:center;padding:10px 12px 10px 0;min-width:0}
.wbv__h{font:600 14px/1.2 'Switzer',sans-serif;margin:0 0 6px 8px}
.wbv__list{list-style:none;margin:0;padding:0}
.wbv__it{display:flex;align-items:baseline;justify-content:space-between;gap:6px;width:100%;min-height:26px;padding:4px 8px;border:0;border-radius:4px;background:transparent;color:#0a0a0a;font:500 13px/1.2 'Switzer',sans-serif;text-align:left;cursor:pointer}
.wbv__it span{font-weight:400;font-size:12px;color:#5c5a57;white-space:nowrap}
.wbv__it:hover{background:#e9e6e1}
.wbv__it[aria-pressed="true"]{background:#0a0a0a;color:#fff}
.wbv__it[aria-pressed="true"] span{color:#d6d3ce}
.wbv__it:focus-visible{outline:2px solid #F5480F;outline-offset:1px}
@container (max-width:370px){.wbv__in{grid-template-columns:1fr 124px}.wbv__it span{display:none}.wbv__h{font-size:13px}}// Wereldbol met vestigingen · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.wbv');if(!w)return;
var cv=w.querySelector('.wbv__cv'),ctx=cv.getContext('2d'),items=[].slice.call(w.querySelectorAll('.wbv__it'));
var rm=matchMedia('(prefers-reduced-motion: reduce)').matches;
/* landmasker 144 x 72 (2,5 graden per cel), rij 0 = 90N, kolom 0 = 180W; 1 bit per cel, base64 */
var M='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5///gAAAAAAAAAAAAAAAAEz/P//8ABwAAAADAAAAAAAABKZAP//8AAAAA4AH4AAAAAAADwDQAP/8AAAAGAH/4AIAAgEABfG/gH/4AAAAGHf//9/gAB///1Ds4H/gAAf4F6///////8/////w+H8BAB/0/////////AP////UcHwCAD3/////////+A////8BgDgAAPn////////74AeB//+B6AAAAPn///////4CAAIAf//h+AAACFP///////gOAAAAP//7/gAANH////////wMAAAAH////wAAD/////////wAAAAAD///04AAD/////////wAAAAAD///8AAAB//X//////gAAAAAD///wAAAB6+D//////EAAAAAD///gAAAPhvb/////8IAAAAAB///AAAAPAp/////+IIAAAAAB///AAAAA8Af/////EwAAAAAAf/+AAAAH8AP/////BAAAAAAAX/4AAAAP/uv/////gAAAAAAAP8EAAAAP///v////gAAAAAAAD4EAAAA///3z////AAAAAAAAB4AAAAA///3+H//+gAAAAAAAA4gAAAB///7/D+fgAAAAAAAAA9gYAAA///7+B8PQAAAAAAAAAHgAAAB///94B4HggAAAAAAAAA4AAAB////gAwHwwAAAAAAAAAAoAAA///+QAwFgAAAAAAAAAAF/AAAf///wAAEAIAAAAAAAAAB/gAAPv//wAICAAAAAAAAAAAB/8AAAD//gAAGGAAAAAAAAAAD/8AAAD//AAADOAAAAAAAAAAD//AAAD/+AAADOjAAAAAAAAAD//4AAD/8AAABAg8AAAAAAAAD//8AAB/8AAAAgAeAAAAAAAAD//8AAB/8AAAABoIAAAAAAAAB//4AAB/8AAAAAAAAAAAAAAAB//wAAB/8QAAAADAAAAAAAAAAf/wAAB/8wAAAAfkAAAAAAAAAP/wAAB/wwAAAAf+AAAAAAAAAP/wAAB/xgAAAD//AAAAAAAAAP/AAAA/xgAAAH//AAAAAAAAAP+AAAA/gAAAAH//gAAAAAAAAf8AAAAfgAAAAD//gAAAAAAAAf8AAAAfAAAAAD//gAAAAAAAAf4AAAAcAAAAADw/gAAAAAAAAfgAAAAAAAAAAAAPAAAAAAAAAfAAAAAAAAAAAAACACAAAAAAA8AAAAAAAAAAAAACAEAAAAAAAcAAAAAAAAAAAAAAAIAAAAAAA4AAAAAAAAAAAAAAAQAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAwgAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////';
var bin=atob(M),GW=144,GH=72,pts=[];
for(var r=0;r<GH;r++){var lat=90-(r+.5)*180/GH,step=Math.max(1,Math.round(1/Math.max(.15,Math.cos(lat*Math.PI/180))));
for(var c=0;c<GW;c+=step){var i=r*GW+c;if(bin.charCodeAt(i>>3)&(128>>(i&7)))pts.push([lat*Math.PI/180,(-180+(c+.5)*360/GW)*Math.PI/180]);}}
var P=[[51.92,4.48],[53.55,9.99],[54.35,18.65],[39.47,-.38],[40.71,-74.0],[1.35,103.82]].map(function(p){return[p[0]*Math.PI/180,p[1]*Math.PI/180];});
var lon0=-0.1,lat0=0.62,sel=-1,W=0,H=0,R=0,dpr=1,t0=performance.now(),vis=true,drag=false,lx=0,ly=0,lastInt=-1e9,anim=null;
function size(){dpr=Math.min(2,window.devicePixelRatio||1);W=cv.clientWidth;H=cv.clientHeight;cv.width=Math.round(W*dpr);cv.height=Math.round(H*dpr);R=Math.min(W,H)*.43;}
function proj(la,lo){var cl=Math.cos(la),d=lo-lon0;return[cl*Math.sin(d),Math.cos(lat0)*Math.sin(la)-Math.sin(lat0)*cl*Math.cos(d),Math.sin(lat0)*Math.sin(la)+Math.cos(lat0)*cl*Math.cos(d)];}
function draw(now){ctx.setTransform(dpr,0,0,dpr,0,0);ctx.clearRect(0,0,W,H);var cx=W/2,cy=H/2;
ctx.fillStyle='#fff';ctx.beginPath();ctx.arc(cx,cy,R,0,6.2832);ctx.fill();ctx.strokeStyle='rgba(10,10,10,.18)';ctx.lineWidth=1;ctx.stroke();
var ds=Math.max(1.3,R/70);
for(var k=0;k<pts.length;k++){var q=proj(pts[k][0],pts[k][1]);if(q[2]<=0.02)continue;ctx.globalAlpha=.25+.6*q[2];ctx.fillStyle='#0a0a0a';ctx.fillRect(cx+q[0]*R-ds/2,cy-q[1]*R-ds/2,ds,ds);}
ctx.globalAlpha=1;
if(sel>0){var a=P[0],b=P[sel];/* grootcirkel van hoofdkantoor naar keuze, licht boven het oppervlak */
var va=[Math.cos(a[0])*Math.cos(a[1]),Math.cos(a[0])*Math.sin(a[1]),Math.sin(a[0])],vb=[Math.cos(b[0])*Math.cos(b[1]),Math.cos(b[0])*Math.sin(b[1]),Math.sin(b[0])];
var om=Math.acos(Math.min(1,va[0]*vb[0]+va[1]*vb[1]+va[2]*vb[2])),prog=anim?Math.min(1,(now-anim)/900):1;
ctx.strokeStyle='#F5480F';ctx.lineWidth=2;ctx.beginPath();var started=false;
for(var s=0;s<=60*prog;s++){var t=s/60,sa=Math.sin((1-t)*om)/Math.sin(om),sb=Math.sin(t*om)/Math.sin(om),x=sa*va[0]+sb*vb[0],y=sa*va[1]+sb*vb[1],z=sa*va[2]+sb*vb[2];
var la=Math.asin(z),lo=Math.atan2(y,x),q2=proj(la,lo),h=1+.12*Math.sin(Math.PI*t)*Math.min(1,om);if(q2[2]<-0.1){started=false;continue;}
var X=cx+q2[0]*R*h,Y=cy-q2[1]*R*h;if(!started){ctx.moveTo(X,Y);started=true;}else ctx.lineTo(X,Y);}ctx.stroke();}
for(var j=0;j<P.length;j++){var p=proj(P[j][0],P[j][1]);if(p[2]<=0)continue;var X2=cx+p[0]*R,Y2=cy-p[1]*R,on=j===sel;
if(!rm){var ph=((now/1600)+j*.17)%1;ctx.strokeStyle='rgba(245,72,15,'+(0.6*(1-ph)).toFixed(3)+')';ctx.lineWidth=1.5;ctx.beginPath();ctx.arc(X2,Y2,4+ph*(on?16:10),0,6.2832);ctx.stroke();}
ctx.fillStyle=on||j===0?'#F5480F':'#0a0a0a';ctx.beginPath();ctx.arc(X2,Y2,on?6:4,0,6.2832);ctx.fill();ctx.strokeStyle='#fff';ctx.lineWidth=1.5;ctx.stroke();}}
function ease(t){return 1-Math.pow(1-t,3);}
var tw=null;function turnTo(i){var tl=P[i][1],tla=Math.max(-.5,Math.min(1,P[i][0]));var d=((tl-lon0)%6.2832+9.4248)%6.2832-3.1416;
var sL=lon0,sA=lat0,st=performance.now();anim=st;if(rm){lon0=sL+d;lat0=tla;tw=null;return;}tw={f:function(now){var t=Math.min(1,(now-st)/900),e=ease(t);lon0=sL+d*e;lat0=sA+(tla-sA)*e;if(t>=1)tw=null;}};}
items.forEach(function(b,i){b.addEventListener('click',function(){sel=sel===i?-1:i;items.forEach(function(x,k){x.setAttribute('aria-pressed',k===sel?'true':'false');});lastInt=performance.now();if(sel>=0)turnTo(sel);if(rm)draw(performance.now());});});
cv.addEventListener('pointerdown',function(e){drag=true;tw=null;lx=e.clientX;ly=e.clientY;try{cv.setPointerCapture(e.pointerId);}catch(_){}});
cv.addEventListener('pointermove',function(e){if(!drag)return;lon0-=(e.clientX-lx)/R;lat0=Math.max(-1,Math.min(1.2,lat0+(e.clientY-ly)/R));lx=e.clientX;ly=e.clientY;lastInt=performance.now();if(rm)draw(lastInt);});
function up(){drag=false;lastInt=performance.now();}cv.addEventListener('pointerup',up);cv.addEventListener('pointercancel',up);
cv.addEventListener('keydown',function(e){var k=e.key;if(k==='ArrowLeft')lon0+=.15;else if(k==='ArrowRight')lon0-=.15;else if(k==='ArrowUp')lat0=Math.min(1.2,lat0+.12);else if(k==='ArrowDown')lat0=Math.max(-1,lat0-.12);else return;e.preventDefault();tw=null;lastInt=performance.now();if(rm)draw(lastInt);});
var last=performance.now();
function frame(now){requestAnimationFrame(frame);if(!vis)return;var dt=Math.min(50,now-last);last=now;if(tw)tw.f(now);else if(!drag&&sel<0&&now-lastInt>2500)lon0+=dt*0.00012;draw(now);}
size();
if('ResizeObserver' in window)new ResizeObserver(function(){size();draw(performance.now());}).observe(cv);
if(rm){draw(performance.now());}else{new IntersectionObserver(function(es){es.forEach(function(e){vis=e.isIntersecting;});}).observe(w);requestAnimationFrame(frame);}
}
init(document.querySelector('.jouw-container'));
Meer uit cijfers & grafieken
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 →