KQ-1541 · TAFFY/PULL
Taffy Pull
A display headline whose every letter can be grabbed and pulled like taffy: the part you hold follows the finger 1:1 while the letter's far side stays in its slot, so it stretches along the pull and thins into a neck (redrawn as a textured canvas mesh), rubber-banding past its reach while its neighbours are dragged a little after it on springs.snap. Let go and it snaps home on a spring of the given stiffness that takes the release velocity, while a wobble runs down the word letter by letter on the cascade; fling it hard, or pull far past the reach, and it tears free, arcs out under gravity, and is reeled back into its slot on springs.glide, landing with a recoil. Keyboard: Left and Right choose a letter, Up and Down tug it (Shift with Left or Right tugs sideways), holding the key pulls further and letting go lets it snap.
Fernworks Sweets
Saltwater taffy
Left and right arrows choose a letter. Up and down tug it; Shift with left or right tugs it sideways. Hold a key to pull further, let go to let it snap back.Pulled by hand in Coldbrook since 1931.
grab a letter · and pull
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/taffy-pull
Props
- text
- string
- default "Pull me"
- The headline. Every letter (grapheme) can be pulled; words never break mid-word.
- as
- "h1" | "h2" | "h3" | "p" | "div" | "span"
- default "h2"
- The element the headline renders as.
- stretch
- number
- default 0.5
- How far a letter reaches before it resists (and, at 1.6× that, tears): 0 is 0.4 of a letter's height, 1 is 1.6.
- stiffness
- number
- default 420
- How hard a letter snaps home, as a spring stiffness (120 to 900).
- thinning
- number
- default 0.6
- How thin the neck gets as it stretches, 0 to 1.
- wobble
- number
- default 0.5
- How long a letter rings after the snap, 0 (dead) to 1 (ringing): the snap spring's damping ratio runs 0.9 to 0.18.
- cling
- number
- default 0.35
- How much the neighbours are dragged after a pulled letter, and how far the wobble carries down the word, 0 to 1.
- tear
- boolean
- default true
- A hard fling, or a pull far past the reach, tears the letter free; it arcs out and is reeled back.
- tearSpeed
- number
- default 1600
- Release speed that tears a letter free, px a second (with at least 40% of the reach pulled).
- color
- string
- default —
- Ink for the letters; inherits the text colour unless set.
- onPull
- (index: number, amount: number) => void
- default —
- Fires while a letter is pulled, with its index and how far toward the reach it is, 0 to 1 in steps of 0.01.
- onSnap
- (index: number) => void
- default —
- Fires when a pulled letter is let go and snaps home, or lands after a tear.
- onTear
- (index: number) => void
- default —
- Fires when a letter tears free.
- sound
- boolean
- default false
- A twang at the snap pitched by the stretch, a higher one at a tear, a low one at the landing.
- disabled
- boolean
- default false
- Letters cannot be pulled; the headline is plain text.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- className
- string
- default —
- Sizes the type (set the font size here, the letters inherit it) and places the headline; the box keeps 0.75em above and below for pulls.
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | "Pull me" | The headline. Every letter (grapheme) can be pulled; words never break mid-word. |
| as | "h1" | "h2" | "h3" | "p" | "div" | "span" | "h2" | The element the headline renders as. |
| stretch | number | 0.5 | How far a letter reaches before it resists (and, at 1.6× that, tears): 0 is 0.4 of a letter's height, 1 is 1.6. |
| stiffness | number | 420 | How hard a letter snaps home, as a spring stiffness (120 to 900). |
| thinning | number | 0.6 | How thin the neck gets as it stretches, 0 to 1. |
| wobble | number | 0.5 | How long a letter rings after the snap, 0 (dead) to 1 (ringing): the snap spring's damping ratio runs 0.9 to 0.18. |
| cling | number | 0.35 | How much the neighbours are dragged after a pulled letter, and how far the wobble carries down the word, 0 to 1. |
| tear | boolean | true | A hard fling, or a pull far past the reach, tears the letter free; it arcs out and is reeled back. |
| tearSpeed | number | 1600 | Release speed that tears a letter free, px a second (with at least 40% of the reach pulled). |
| color | string | — | Ink for the letters; inherits the text colour unless set. |
| onPull | (index: number, amount: number) => void | — | Fires while a letter is pulled, with its index and how far toward the reach it is, 0 to 1 in steps of 0.01. |
| onSnap | (index: number) => void | — | Fires when a pulled letter is let go and snaps home, or lands after a tear. |
| onTear | (index: number) => void | — | Fires when a letter tears free. |
| sound | boolean | false | A twang at the snap pitched by the stretch, a higher one at a tear, a low one at the landing. |
| disabled | boolean | false | Letters cannot be pulled; the headline is plain text. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| className | string | — | Sizes the type (set the font size here, the letters inherit it) and places the headline; the box keeps 0.75em above and below for pulls. |