← Blurr Motion form-shader-success-minimal
Categorie forms Tier 3 Techniek #28 Deps webgl2

Motion Lab / Forms / shader success / minimal

Bedankt — we mailen binnen 24u.

1. Mechanisme — kopieer 1-op-1, geen styling-keuzes
// Mechanisme: form-shader-success-minimal (techniek #28 — fragment shader success state)
// Bij submit toont een vanilla WebGL2-canvas met monochroom ripple/wave (cream/ink).
// Auto-demo elke 5s. Reduced-motion: single render (geen animation loop).
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const canvas = document.querySelector('.shader-canvas');
const overlay = document.querySelector('.shader-overlay');
const form = document.querySelector('.shader-form');
const gl = canvas && canvas.getContext('webgl2');
const VS = '#version 300 es\nin vec2 p;void main(){gl_Position=vec4(p,0.,1.);}';
const FS = '#version 300 es\nprecision highp float;out vec4 o;uniform vec2 r;uniform float t;void main(){vec2 uv=(gl_FragCoord.xy-.5*r)/min(r.x,r.y);float d=length(uv);float w=sin(d*18.-t*3.)*.5+.5;w*=smoothstep(.9,.0,d);vec3 ink=vec3(.039);vec3 paper=vec3(.957,.945,.922);o=vec4(mix(paper,ink,w*.55),1.);}';
// Compile + link, set up fullscreen quad, animate t. Bij submit: overlay.classList.add('on').
2. Skeleton — DOM + class-namen, mag herschikken
<!-- Skeleton: form-shader-success-minimal -->
<div class="shader-wrap">
  <form class="shader-form">…</form>
  <div class="shader-overlay">
    <canvas class="shader-canvas"></canvas>
    <p class="shader-msg">Bedankt — we mailen binnen 24u.</p>
  </div>
</div>
3. Styling-template — verplicht eigen invulling per merk
/* Styling: form-shader-success-minimal */
:root {
  --block-paper: #F4F1EB;
  --block-ink: #0A0A0A;
  --block-rule: rgba(10,10,10,.18);
}
.shader-wrap { position: relative; background: var(--block-paper); color: var(--block-ink); font-family: 'Inter', sans-serif; font-weight: 300; padding: clamp(3rem,6vw,5rem) clamp(1.5rem,4vw,4rem); }
.shader-form { max-width: 480px; display: flex; flex-direction: column; gap: 1.75rem; }
.shader-form input, .shader-form textarea { width: 100%; appearance: none; border: 0; border-bottom: 1px solid var(--block-rule); background: transparent; padding: .6rem 0; font: 300 1rem 'Inter',sans-serif; color: inherit; outline: none; }
.shader-form button { align-self: flex-start; background: var(--block-ink); color: var(--block-paper); border: 0; padding: .9rem 2rem; font: 300 .95rem 'Inter',sans-serif; cursor: pointer; }
.shader-overlay { position: absolute; inset: 0; opacity: 0; visibility: hidden; transition: opacity .5s ease; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.shader-overlay.on { opacity: 1; visibility: visible; }
.shader-overlay canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.shader-msg { position: relative; font-family: 'Inter', sans-serif; font-weight: 300; font-size: clamp(1.25rem,2.5vw,1.75rem); letter-spacing: -.01em; color: var(--block-ink); background: rgba(244,241,235,.85); padding: 1rem 2rem; }