Signature
An animated SVG signature effect that draws out text as if hand-written.
Live preview recorded from Bakai Lab; experiment and demo by Bakai Tolondu uulu. Preview: platform recorded · rights authorized.
A tethered voice-recording button that stretches independently along each screen axis while preserving its apparent volume through circular drags.
LSource LandLab - Bakai Tolondu uuluWhy it stands out
A tethered voice-recording button that stretches independently along each screen axis while preserving its apparent volume through circular drags.
Build a round glass button that you can drag, and that behaves like a weight on a rubber tether rather than a soap bubble. Geometry: a 54px circle. Keep every internal length as a RATIO of the button's own width, not absolute pixels, so the gesture feels identical at any size. The drag. Track the pointer from the button's own CENTRE, not from where the finger landed — with a grab-point origin the neutral position becomes wherever you happened to press, so grabbing the edge and sliding to the middle still counts as a pull and the disc sits there stretched over its own centre. Inside a dead zone of 0.24 of the width the button does not move at all, so a press that is only a press cannot shiver and the break-free gives the pull a beginning. Past it, the offset is cap * tanh((d - dead) / cap) along the same vector, where cap is only 0.30 of the width. Asymptotic, never a hard clamp: it tracks nearly 1:1 while the pull is small, gives less and less, and never quite reaches the cap, so there is no wall to feel. Keep the leash SHORT — the button is on a tether, not being relocated, and travel and stretch trade against each other: the less it is allowed to move, the more the same pull has to show up as shape. Release and two springs (damping 17, stiffness 338) carry x and y home. That is a damping ratio of 0.46, a 19% overshoot over a 385ms period: it passes home, swings about a fifth of the pull past it and comes back. Raise the damping alone and the timing goes with the amplitude, because what you see as timing is the damped frequency wn*sqrt(1 - zeta^2) — move both numbers together to change one without the other. The deformation. Lock it to the SCREEN axes and do NOT rotate an ellipse into the drag direction. Each axis stretches on its own displacement and neither one squashes: scaleX = 1 + 0.28 * ex^2 and scaleY = 1 + 0.28 * ey^2, where (ex, ey) is the offset over the tether cap. Squared so the response eases in and a small pull barely deforms. A sideways pull widens only, an upward pull heightens only, and a diagonal pull grows both by half, which is a circle about 14% larger. Clamp that offset as a VECTOR before you split it, not one axis at a time. Per-axis clamping squares off the tether's circle: once either component saturates, turning the pull changes only the other one, so the sum of the two stops being constant around a sweep and the disc's area starts breathing again. It is not a corner case, because these read off the follow SPRING rather than the pointer, and a spring chasing a rotating target overshoots its own cap. Measured at 1.58x on a fast circle, so the clamp is live for most of one. The trap worth naming, because the tidy-looking version is the wrong one. It is tempting to drive the two axes off their DIFFERENCE, max(0, u - v)^2, to strip out the part they have in common so that a diagonal pull returns the disc to exactly its resting circle. Do not. Subtracting the common part means the disc is 1.28 of its area on an axis and 1.00 on a diagonal, so a steady circular drag inflates and deflates it 28% FOUR TIMES A TURN while the finger is doing one smooth continuous thing. It reads as jumpy and buggy, it is not a discontinuity, and no amount of smoothing the handover fixes it because the size change IS the model. Measured on a scripted 1400ms sweep: area swing 28.0% against 1.5%, worst single frame 0.059 against 0.003, with the aspect range identical at 0.781..1.280. Same expressiveness, 19x smoother, and the whole price is that a diagonal pull settles on a slightly larger circle rather than the resting one. Never compress the perpendicular axis: the disc moves as a whole and stretches a little, it does not get squashed into a lens. Add a 3 degree lean, placed INSIDE the scale in the transform string so the stretch still acts on the screen axes (CSS applies the rightmost function to the element first). With no rotation into the pull there is no counter-rotation to undo, so the icon rides the same transform and stays upright for free. The press. Glass under a finger COMPRESSES: sink to 0.97, never pop outward. Use a spring at damping 52 / stiffness 1400 (ratio 0.70, settling in about 150ms) — underdamp it and the release overshoots back out past resting size, which is the single most bubble-like thing you can do. A press that travelled less than 4px FROM THE PRESS POINT is a tap and fires the click; measure that from the finger, not from the disc's centre, or the button only clicks when you hit the exact middle. The surface. Fill with a radial-gradient at 61% 54%, rgba(208,208,208,0.80) to rgba(212,212,212,0.44) at 68% — equal channels throughout, so the glass has no colour of its own and takes it from whatever is behind. Add a backdrop-filter blur of 3% of the width. The edge is three inset shadows and nothing else: two rim lights at about 1.7% offset with a -1.6% spread at rgba(255,255,255,0.62), top-left and bottom-right, plus a broad bloom from the bottom at rgba(255,255,255,0.3). NO drop shadow and no ground cast: a cast belongs on a separate, differently-transformed layer, because a box-shadow on the element carrying the jelly inherits the squash and swings around with it. Inside, two blurred white bars at -45 degrees stand in for the specular. They must NOT rotate as you drag — a fixed light source does not move when the object deforms; the bars sit inside the jellied element so the highlight stretches because the surface under it stretched. Fusing with its neighbour. Put a pill of the same glass to its left, the SAME HEIGHT as the disc so the merged silhouette has no step in it, with a gap of about a quarter of the disc between them. Drag the disc left and the two must merge into one body with a proper neck, never overlap as two shapes. Do it with a metaball: put a solid silhouette of each into one group, Gaussian blur the group, then throw a hard step at the ALPHA channel with a colour matrix (alpha row 24, offset -12). Where the two blurred halos overlap enough, the threshold closes over the gap and a neck appears and pinches. Everything inside that group must be OPAQUE and hard-edged — a shadow, a fade, or a second blur in there is eaten by the same threshold — so paint the glass in its resolved-over-white form there, and drop the translucent fill from the element above it or the tint applies twice. Pin color-interpolation-filters to sRGB; unset it defaults to linearRGB and browsers disagree, so the neck renders at a different weight per engine. Do NOT add feComposite atop: letting colour blur through the neck is what makes glass read as merging into glass. The edge lights have to GO where they merge. This is the part that decides whether it looks fused or just overlapped: once the two have joined there is no edge at the join any more, so a rim light still drawn across it is a white seam sitting exactly where the join should be invisible. Keep the rim on its own layer, separate from the fill and the icon, and mask it with a radial hole anchored at the junction — transparent at the centre, fading to opaque at the rim of the hole — whose radius grows with how fused the two are. Make it a TALL ellipse rather than a circle: a circular hole only reaches sqrt(2)/2 of the way up the disc and leaves the upper and lower arcs lit, which reads as an edge drawn through the middle of the blob. Drive the amount off how much of the resting gap has been closed, counting BOTH the disc's travel and the half-width it gains as it stretches, and start it a little before they actually touch, since the metaball closes over a gap of roughly twice the blur radius. Size that hole by the JOIN, and put nothing else on the layer wearing it. Both halves of that matter and both are easy to get wrong. Size it off the blur, which is what sets how big the neck is, at roughly 4x it: sizing it off a BODY instead is meaningless (it has nothing to do with how big the join is) and it means one number does two different jobs, because the pill and the disc are not the same size. Sized off the disc's width it cleared over half the pill's length, and the lit edge crawled further in the harder you pulled. And keep the mask on a layer that carries ONLY the edge light. Share an element with the body shading and the wipe takes the shading with it, which leaves half the pill flat at the raw fill colour and visibly lighter, a far worse artefact than the seam it was hiding. Every fill has to die before it reaches an edge, or it draws one. This is the rule that catches the last artefact: a 180deg gradient down a pill is transparent at the top and bottom and fully OPAQUE at both ends, so its right end is a hard step that lands inside the merged body the moment the two join. Give it a static horizontal fade over the last couple of blur radii. Static, not driven by the fusion: a fade that grows as you pull is the same travelling edge you just removed. The same goes for anything clipped by the shape's own radius, and the specular bars are the ones that catch people out, since they are wider than the disc and end in a hard bright arc lying exactly on its circle. On the free edge that arc IS the glass catching light; on the merged side it is the outline redrawn through the middle of the blob, so it needs the same wipe the rim gets. Ignore every pointer after the one that started the drag, or a second finger resets the origin and the disc jumps mid-gesture. Under prefers-reduced-motion, drop the drag entirely and let it behave as a plain button that fires on release.
Discovery vocabulary
Related by governed terms
An animated SVG signature effect that draws out text as if hand-written.
More from Lab - Bakai Tolondu uulu