SigmoidLive demo. Scroll, tune, compare.
Everything on this page that moves while you scroll is driven by @sweberdev/sigmoid. In browsers with CSS scroll-driven animations the browser does the work, without a script per frame. The thin bar at the top of the window is a data-sigmoid attribute, nothing else.
Curves
Easing you can use in CSS.Springs, the S-curve and Bézier curves as one object.
Pick a curve and move the sliders. Sigmoid solves the spring, samples it and keeps only the points that matter, so the curve fits into a short CSS linear() value. Press play to run it as a plain CSS transition.
JavaScript
import { spring } from "@sweberdev/sigmoid/easing"
const pop = spring({ duration: 0.6, bounce: 0.3 })CSS
transition: transform 983ms linear(0, 0.0009 0.42%, 0.0078 1.25%, 0.0293 2.5%, 0.062 3.75%, 0.0888 4.58%, 0.1189 5.42%, 0.1689 6.67%, 0.2232 7.92%, 0.4754 13.33%, 0.5859 15.83%, 0.6539 17.5%, 0.7013 18.75%, 0.7455 20%, 0.7862 21.25%, 0.8234 22.5%, 0.8571 23.75%, 0.8875 25%, 0.9229 26.67%, 0.9656 29.17%, 0.9828 30.42%, 1.0017 32.08%, 1.0226 34.58%, 1.0359 37.08%, 1.0439 40%, 1.046 42.92%, 1.0409 47.92%, 1.0121 62.5%, 1.0027 70.42%, 0.998 82.08%, 1);Reveal
Eight presets, one function.Scroll down slowly and watch them arrive.
Each card is revealed with reveal() over the range entry 0% to cover 40%: the animation starts when the card enters the window and ends when it has covered 40% of its way through. Change the curve or force the JavaScript fallback to compare: both paths compute the same progress.
- 01
fade-in - 02
fade-up - 03
fade-down - 04
slide-left - 05
slide-right - 06
scale-in - 07
blur-in - 08
clip-up
The code for one card
reveal(".card", {
keyframes: "scale-in",
range: "entry 0% cover 40%",
easing: ease.bouncy,
})Parallax and scrub
Depth without layout work.Three layers, three distances, one transform each.
The squares move against the scroll by 20, 60 and 120 pixels while they cross the window. The ring is linked to the scroll position of the whole page with scrub(): it turns once from top to bottom.
parallax() and scrub()
import { parallax, scrub } from "@sweberdev/sigmoid"
parallax(".layer-far", { distance: 20 })
parallax(".layer-near", { distance: 120 })
scrub(".ring", [
{ transform: "rotate(0deg)" },
{ transform: "rotate(360deg)" },
])Zero JavaScript
Only an attribute.Works in Server Components and plain HTML.
These lines are animated by sigmoid.css alone. Custom properties tune the range, the curve and the distance. In browsers without scroll timelines, one call to init() starts the fallback; elsewhere it does nothing.
fade-up with the default curve
slide-left with the bouncy spring
blur-in over a longer range
clip-up with the S-curve
The markup of these lines
<p data-sigmoid="fade-up">
fade-up with the default curve
</p>
<p data-sigmoid="slide-left" style="--sigmoid-easing: var(--sigmoid-ease-bouncy); --sigmoid-distance: 64px">
slide-left with the bouncy spring
</p>
<p data-sigmoid="blur-in" style="--sigmoid-range: entry 0% cover 60%">
blur-in over a longer range
</p>
<p data-sigmoid="clip-up" style="--sigmoid-easing: var(--sigmoid-ease-sigmoid)">
clip-up with the S-curve
</p>Get started
MIT licensed.Free for every project.
Install the package, add the stylesheet, and mark your first element. The docs cover the API, the curves, React and reduced motion.
pnpm add @sweberdev/sigmoid