Portret in een vorm die beweegt New
A portrait of the owner inside a soft, ever changing shape, with an orange blob behind it breathing at its own pace. On hover the shape moves a little livelier; the button pauses the motion. Plain SVG with its own shape function, no library. For the about section of a dog groomer, hairdresser, coach or any business where the owner is the face.
Anouk trimt al veertien jaar honden in Leiden
Trimsalon Vacht & Co, Haarlemmerstraat 112. Een eerste knipbeurt voor een kleine hond kost € 45.
Afspraak makenHow to use it
- Paste the HTML where the components should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Portret in een vorm die beweegt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="r7bp">
<div class="r7bp__txt">
<h3 class="r7bp__h">Anouk trimt al veertien jaar honden in Leiden</h3>
<p class="r7bp__p">Trimsalon Vacht & Co, Haarlemmerstraat 112. Een eerste knipbeurt voor een kleine hond kost € 45.</p>
<a class="r7bp__a" href="#r7s-blob-portret">Afspraak maken</a>
</div>
<div class="r7bp__fig">
<svg class="r7bp__svg" viewBox="0 0 200 200" role="img" aria-label="Anouk met een borderterriër op de arm in haar trimsalon">
<defs><clipPath id="r7bp-clip"><path class="r7bp__c" d="M100 22C143 22 178 57 178 100C178 143 143 178 100 178C57 178 22 143 22 100C22 57 57 22 100 22Z"/></clipPath></defs>
<path class="r7bp__o" d="M108 18C155 18 194 57 194 104C194 151 155 190 108 190C61 190 22 151 22 104C22 57 61 18 108 18Z"/>
<image href="https://neddev.com/lab-media/r7s-blob-portret-1.webp" x="-136" y="-8" width="420" height="229" preserveAspectRatio="xMidYMid slice" clip-path="url(#r7bp-clip)"/>
</svg>
<button class="r7bp__pz" type="button" aria-pressed="false" aria-label="Beweging stilzetten"><svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path class="r7bp__ip" d="M5.5 3.5v9M10.5 3.5v9"/><path class="r7bp__iv" d="M5 3.5l7 4.5-7 4.5z"/></svg></button>
</div>
</div>
</div>/* Portret in een vorm die beweegt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.r7bp{position:absolute;inset:0;display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);align-items:center;gap:12px;padding:14px 16px 14px 20px;background:#f4f3f1;color:#0a0a0a;font-family:'Switzer',sans-serif;container-type:size;text-align:left}
.r7bp *,.r7bp *::before,.r7bp *::after{box-sizing:border-box}
.r7bp__txt{display:flex;flex-direction:column;align-items:flex-start;gap:8px;min-width:0}
.r7bp__h{margin:0;font:650 clamp(16px,5.2cqi,22px)/1.12 'Switzer',sans-serif;letter-spacing:-.02em;text-wrap:balance}
.r7bp__p{margin:0;font:400 clamp(12px,3.3cqi,14px)/1.4 'Switzer',sans-serif;color:#45433f}
.r7bp__a{margin-top:2px;padding:10px 14px;background:#F5480F;color:#0a0a0a;border-radius:4px;font:600 14px/1 'Switzer',sans-serif;text-decoration:none;transition:background-color .16s}
.r7bp__a:hover{background:#ff6a36}
.r7bp__a:focus-visible{outline:2px solid #0a0a0a;outline-offset:3px}
.r7bp__fig{position:relative;width:100%;max-width:220px;justify-self:center;aspect-ratio:1}
.r7bp__svg{display:block;width:100%;height:100%;overflow:visible}
.r7bp__o{fill:#F5480F}
.r7bp__pz{position:absolute;right:0;bottom:2px;width:32px;height:32px;display:grid;place-items:center;margin:0;padding:0;border:1px solid rgba(10,10,10,.2);border-radius:4px;background:#fff;color:#0a0a0a;cursor:pointer}
.r7bp__pz:hover{border-color:#0a0a0a}
.r7bp__pz:focus-visible{outline:2px solid #0a0a0a;outline-offset:2px}
.r7bp__pz svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.r7bp__iv{display:none}
.r7bp__pz[aria-pressed="true"] .r7bp__ip{display:none}
.r7bp__pz[aria-pressed="true"] .r7bp__iv{display:inline}
@container (max-width:360px){.r7bp__p{display:none}}// Portret in een vorm die beweegt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.r7bp');if(!w)return;
var rm=window.matchMedia&&matchMedia('(prefers-reduced-motion: reduce)').matches;
var clip=w.querySelector('.r7bp__c'),oranje=w.querySelector('.r7bp__o'),fig=w.querySelector('.r7bp__fig'),knop=w.querySelector('.r7bp__pz');
function vorm(cx,cy,r,amp,t,zaad){
var n=7,pts=[];
for(var i=0;i<n;i++){var a=i/n*Math.PI*2;var k=1+amp*(Math.sin(t*0.9+i*1.7+zaad)*0.6+Math.sin(t*0.53+i*2.9+zaad*2)*0.4);pts.push([cx+Math.cos(a)*r*k,cy+Math.sin(a)*r*k]);}
var d='M'+pts[0][0].toFixed(2)+' '+pts[0][1].toFixed(2);
for(var j=0;j<n;j++){var p0=pts[(j-1+n)%n],p1=pts[j],p2=pts[(j+1)%n],p3=pts[(j+2)%n];
d+='C'+(p1[0]+(p2[0]-p0[0])/6).toFixed(2)+' '+(p1[1]+(p2[1]-p0[1])/6).toFixed(2)+' '+(p2[0]-(p3[0]-p1[0])/6).toFixed(2)+' '+(p2[1]-(p3[1]-p1[1])/6).toFixed(2)+' '+p2[0].toFixed(2)+' '+p2[1].toFixed(2);}
return d+'Z';
}
var t=0,amp=0.07,doel=0.07,stil=rm,raf=0,laatste=0,zicht=true;
function teken(){clip.setAttribute('d',vorm(100,100,79,amp,t,0.4));oranje.setAttribute('d',vorm(110,106,86,amp*1.25,t*0.8,2.1));}
function lus(nu){raf=0;if(stil||!zicht)return;var dt=laatste?Math.min(50,nu-laatste)/1000:0;laatste=nu;amp+=(doel-amp)*0.06;t+=dt*(1+amp*8);teken();raf=requestAnimationFrame(lus);}
function start(){if(!raf&&!stil&&zicht){laatste=0;raf=requestAnimationFrame(lus);}}
teken();
fig.addEventListener('pointerenter',function(){doel=0.13;});
fig.addEventListener('pointerleave',function(){doel=0.07;});
knop.addEventListener('click',function(){stil=!stil;knop.setAttribute('aria-pressed',stil?'true':'false');knop.setAttribute('aria-label',stil?'Beweging hervatten':'Beweging stilzetten');start();});
if(rm){knop.setAttribute('aria-pressed','true');knop.setAttribute('aria-label','Beweging hervatten');}
if('IntersectionObserver' in window){new IntersectionObserver(function(e){zicht=e[0].isIntersecting;start();}).observe(w);}
start();
}
init(document.querySelector('.jouw-container'));
More components
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →