UI Motion Prompts Pack $19

Bottom Sheet Part 1

6 bottom sheet animations. Copy any short prompt for free, and open full prompt 1 to see how detailed they are. Full prompts 2–6 are in the pack.

1  Snap Points
Drag the handle: the sheet snaps to peek, half and full heights.
Full prompt (free sample)
Basics: stage 470×222px, background #13131C, all coordinates in px from the stage's top-left, everything clipped to the stage (its two top corners are rounded with radius 40px; anything past an edge is simply cut off). The animation is a 4s loop that plays by itself and is seamless (the state at 4.0s equals the state at 0s; u = loop time 0–4 in seconds). The video is 12s = three loops; T = seconds since the video start (0–12), and u = T mod 4. T is used only for: the waves in the background sea picture (period 4s), the caret blink in 05 (period 1s), and in 01 the 12s cycle index k12 = floor((T mod 12)/4) (0, 1 or 2 = which of the three loops is playing); those periods divide 4 and 01 ends its third loop in the state it starts with, so 12s → 0s is seamless too. The first finger touch is at u = 0.5 in every animation (a drag in 01–03, a tap in 04–06); later touches and the way back to the start state are given in each prompt. Colors: violet #6E5BFF, cyan #38C6FF, pink #FF5CA8, gold #FFD166, mint #3DDBB0. "violet→cyan" is a horizontal linear gradient from the shape's own left edge (violet) to its right edge (cyan), unless other ends are given. Text: font stack "Segoe UI Variable Display","Segoe UI",sans-serif, weight and size as given (weights used: 500, 600, 700, 800); x is the left edge unless "centered"; y is the alphabetic baseline unless "baseline middle" is stated. Opacities always multiply with the surrounding opacity. mix(A, B, k) = per-channel linear RGB blend, rounded. rr(x, y, w, h, r) = rounded rect with top-left (x, y), corner radius r (at most half the smaller side). "Glow" = a canvas shadow (that shadowColor and shadowBlur, no offset). clamp(x) = clamp to 0–1. Easing (k is clamped to 0–1 first): ease = 1−(1−k)³, easeIn = k³, easeIO = 4k³ for k < 0.5, else 1 − (−2k+2)³/2, easeBack = 1 + 2.9(k−1)³ + 1.9(k−1)² (0→1, overshooting to about 1.12). lerp(a, b, k) = a + (b−a)·k. seg(x, a, b) = clamp((x−a)/(b−a)); seg(a, b) with two arguments applies it to u. Spring springF(ω₀, ζ)(t) = 0 for t ≤ 0, else 1 − e^(−ζω₀t)·(cos ω_d t + (ζω₀/ω_d)·sin ω_d t), ω_d = ω₀√(1−ζ²) (rises 0 → 1 with an overshoot). settle(T0, from, to, ω₀, ζ) = from for u < T0, else lerp(from, to, springF(ω₀, ζ)(u − T0)) (let go at T0, then spring from → to). For an event at time E: rel = u − E wrapped into −2…+2 (negative before it), since = u − E wrapped into 0…4. Press pressK(a, d) (a = rel to the tap): 1 for a < −0.1 or a > 0.6; for −0.1 ≤ a < 0, 1 − d·(a+0.1)/0.1; for 0 ≤ a ≤ 0.6, 1 − d·(1 − springF(22, 0.45)(a)); the pressed element scales by it around its own center (or the point given). Tap indicator tapMark(x, y, a) (a = rel to the tap; drawn on top of everything): visible only for −0.42 ≤ a < 0.4. A circle of radius 22.575px, fill rgba(215,215,230,0.38) with a soft shadow (black 35%, shadowBlur 10, fill only), then a 3.5px border white 92% (no shadow); fill and border are drawn in the circle's scaled frame, so the border width scales with the circle. Scale: for a < −0.1, lerp(1.25, 1, ease((a+0.42)/0.32)); for −0.1 ≤ a < 0, lerp(1, 0.8, (a+0.1)/0.1); for a ≥ 0, lerp(0.8, 1, ease(a/0.2)). Opacity: clamp((a+0.42)/0.18) before the tap, clamp(1 − (a−0.12)/0.25) after. Ripple (drawn under the circle, not scaled, only for 0 ≤ a < 0.4): a 3px white ring of radius 22.575·(1 + 3.2a) (22.6 → 51.5px), opacity 0.7·(1 − a/0.4) (its own opacity, not multiplied by the circle's opacity); it keeps growing for its full 0.4s. Hold indicator holdMark(x, y, T0, T1) (a finger that presses at T0 and lifts at T1; (x, y) is its current position, so it moves during a drag; a = rel to T0, b = since T1): while T0 ≤ u < T1 it has opacity 1 and scale lerp(0.8, 0.86, ease(a/0.2)) (0.86 after 0.2s); else if b < 0.4 (after the lift): opacity clamp(1 − (b−0.12)/0.25), scale lerp(0.86, 1, ease(b/0.2)); else if −0.42 ≤ a < 0 it approaches exactly like the tap indicator before its tap; otherwise it is hidden. Same circle as the tap indicator. Its ripple is the same as the tap's and depends only on a: it is drawn whenever u ≥ T0 and 0 ≤ a < 0.4, at the current (x, y). Background app screen appBg(title, default "Explore"): fill the whole stage #13131C; the title (800 24px #F4F4F8) at (24, 44); two pictures 188×92 with corner radius 16: scenery kind 0 centered (118, 108) and scenery kind 1 centered (352, 108) (x 24–212 and 258–446, y 62–154); below them, for k = 0, 1: a card rr(24 + 234k, 166, 188, 40, 12) #1C1B2B with two lines rr(38 + 234k, 180, 96, 6, 3) #3A3852 and rr(38 + 234k, 192, 60, 5, 2.5) #2A2840. Picture scenery(x, y, w, h, r, kind) (center (x, y)): clipped to rr(x − w/2, y − h/2, w, h, r); local coordinates (X, Y) from the picture's top-left. Kind 0 (sunset mountains, it does not move): a vertical linear gradient from Y = 0 to Y = h with stops #3B2E86 (0), #7E5BD6 (0.5), #F3A5C8 (1) over the whole picture; a sun circle #FFD8A8 at (0.7w, 0.42h), radius 0.13h; mountains = the filled polygon (0, h), (0.32w, 0.48h), (0.55w, 0.78h), (0.75w, 0.58h), (w, 0.85h), (w, h) in #2A2266. Kind 1 (sea): a vertical gradient #1B3F7A (top) → #38C6FF (bottom); a moon circle rgba(255,255,255,0.85) at (0.3w, 0.3h), radius 0.08h; three wave layers q = 0, 1, 2 drawn in that order, filled #2C6FC0, #1F55A0, #173F80: the polygon from (0, h) through (j·w/20, h·(0.62 + 0.12q) + 0.03h·sin(0.9j + π·T/2 + q)) for j = 0–20, then (w, h) (the waves move with period 4s). Dim dimAll(a): if a > 0, fill the whole stage #05050A at opacity a. Sheet sheetBody(y, options) (y = the sheet's top edge): defaults left x0 = 20, right x1 = 450, top corner radius r = 22, bottom corner radius rb = 0, bottom edge 282 (60px below the stage, so the sheet always runs past the bottom), fill #1F1D33, handle width hw = 40, handle color #5E5B7E. Shape = the rounded rect from (x0, y) to (x1, bottom) with radius r at top-left and top-right and rb at bottom-right and bottom-left; fill it with a shadow rgba(0,0,0,0.55), shadowBlur 24, offset (0, −4) (the shadow falls upward onto the app; fill only); then stroke the same shape 1.5px rgba(255,255,255,0.07) with no shadow; then, if hw > 0, the handle rr((x0+x1)/2 − hw/2, y + 9, hw, 5, 2.5) in the handle color. Row sheetRow(x, y, w, label, sub, color): a circle of radius 16 at (x + 16, y + 18) filled color; label (600 15px #F4F4F8) at (x + 44, y + 15); sub (500 12.5px #9D9BBB) at (x + 44, y + 33); a divider rect (x + 44, y + 43, w − 44, 1) rgba(255,255,255,0.06). Place list placeList(y, title) (made-up places): the title (700 18px #F4F4F8) at (42, y + 42); then for k = 0–3 sheetRow(42, y + 58 + 48k, 386, …): "Lantern Café" / "4 min walk" / violet, "Riverside Park" / "9 min walk" / cyan, "City Library" / "12 min walk" / pink, "Night Market" / "15 min walk" / gold. Pill button pillBtn(x, y, w, h, label, pk): scaled by pk around its center (x + w/2, y + h/2): rr(x, y, w, h, h/2) violet→cyan, label (700 15px #FFFFFF) centered at x + w/2, baseline y + h/2 + 5.5. Rolling word rollDigits(x, y, from, to, k, font, color, h): text centered with baseline middle, clipped to the rect (x − 2h, y − 0.62h, 4h, 1.24h); e = ease(k); if k < 1 the old word at opacity (1 − e) at y − 1.05h·e (moves up and out); if k > 0 the new word at opacity e at y + 1.05h·(1 − e) (comes up from below). Field box fieldBox(x, y, w, h, r, f, fill): rr(x, y, w, h, r) filled fill; stroked 2px rgba(255,255,255,0.14); if f > 0, at opacity f, stroked again 2.5px with a violet→cyan gradient from x to x + w and glow rgba(110,91,255,0.45) blur 12. Typing typed(text, n, x, y, font, color): n may be fractional; draw the first floor(n) characters at (x, y), then (if n is not whole) the next character at opacity frac(n), right after them and 4·(1 − frac(n))px lower (it rises into place); its width w = width(first floor(n) characters) + frac(n)·width(next character). Caret caret(x, yc, h) at opacity a: ph = T mod 1; on = seg(ph, 0, 0.08) for ph < 0.5, else 1 − seg(ph, 0.5, 0.58); a cyan rect (x + 1, yc − h/2, 2.5, h) at opacity a·on. Send arrow icoSend(x, y, s, color, line width) (stroked, round caps and joins; coordinates in units of s from (x, y)): shaft (0, 0.38) → (0, −0.38), head (−0.30, −0.08) → (0, −0.38) → (0.30, −0.08).

A bottom sheet is dragged by its handle and let go part-way; it springs into the next of three snap heights: Peek → Half in the first loop, Half → Full in the second, Full → Peek in the third (one 12s cycle). 
- Snap heights (the sheet's top y) with their names: 0 = 158 "Peek", 1 = 92 "Half", 2 = 30 "Full". c = k12; from = height c, to = height (c + 1) mod 3; mid = from + 0.72·(to − from) (110.48, 47.36 and 122.16 in the three loops).
- Finger y: fy = lerp(from, mid, easeIO(seg(0.6, 1.3))) before 1.4; mid from 1.4. Sheet top y = fy before 1.4 (the sheet follows the finger exactly); from 1.4, y = settle(1.4, mid, to, 15, 0.6) (the finger lets go at 72% of the way and the sheet springs on into the next height, overshooting it by about 9.5% of the remaining distance). Each loop starts where the previous one ended, and the third loop ends at Peek where the first starts, so 4.0s → 0s and 12s → 0s are seamless.
- appBg("Explore"); dimAll(0.55·clamp((158 − y)/128)) (0 at Peek, ≈ 0.28 at Half, 0.55 at Full); sheetBody(y) with all defaults; then, clipped to the rect (20, y, 430, 222 − y), placeList(y, "Nearby places").
- Height tag at the sheet's top right: rr(372, y + 22, 60, 26, 13) filled rgba(110,91,255,0.22); rollDigits(402, y + 35, name(c), name(c + 1), k, 700 13px, #D6D1FF, h = 16) with k = 0 before 1.4 and seg(1.4, 1.65) from 1.4 (the tag shows the old name while dragging and rolls to the new name as the sheet springs; it moves with the sheet).
- Finger: holdMark at (235, fy + 12), pressing at 0.5 and lifting at 1.4 (it sits on the handle and moves with fy; after the lift it fades at (235, mid + 12)).
- Draw order: app background, dim, sheet (with handle), place list, tag, tag word, hold indicator.
2  Drag to Close
Pull the sheet down and let go: it slides away; tap to reopen.
Full prompt · 9,246 characters
An open sheet is pulled down by its handle and let go: it slides away off the bottom; tapping a button in the app behind opens it again with a …
🔒 Unlock all 6 in the pack — $19
3  Rubber Band
Pull past the top: it resists like rubber and springs back.
Full prompt · 9,830 characters
Pulling an open sheet up past its top makes it resist like rubber (the finger moves far, the sheet only a little, and the handle stretches and turns …
🔒 Unlock all 6 in the pack — $19
4  Mini Player
Tap the mini player: it grows into a full player sheet.
Full prompt · 10,768 characters
Tapping a floating mini player bar grows it with a spring into a full player sheet (the cover art grows and moves to the top left, the small texts …
🔒 Unlock all 6 in the pack — $19
5  Keyboard Lift
Tap the comment box: the keyboard rises and lifts the sheet.
Full prompt · 11,476 characters
Tapping the comment box of a comments sheet brings up a keyboard that pushes the input bar and the sheet up; a comment is typed and sent, the …
🔒 Unlock all 6 in the pack — $19
6  Floating Card
A floating card springs up; its content arrives in a cascade.
Full prompt · 10,402 characters
Tapping Save springs up a floating card (inset from the edges, all four corners rounded) from below; its icon, title and two buttons arrive one after …
🔒 Unlock all 6 in the pack — $19

Get every full prompt — $19

One-time payment. Price goes up as new patterns are added. Buy once, get every update.
Team license (up to 5 people, client work): $49.
Lower price in many countries, applied automatically at checkout.
Get the pack on Gumroad
← Text Field Part 2Bottom Sheet Part 2 →
Full pack · $19438 prompts · 73 demos
Get the pack