JS
Animate with JavaScript instead of CSS: GSAP, Motion, the Web Animations API or any library.
Import it from pagefold/js (about 1.2 KB minified and compressed, shared code included).
Each animation is an object:
{
name: 'slide', // optional: only runs when the visit asks for this name
from: '/', // optional: pattern or list of patterns, default any page
to: '/blog/:slug', // optional: same
out: (done, data) => {}, // animate the old content out
in: (done, data) => {}, // animate the new content in
}
You can pass the array directly: new PagefoldJs([ ... ]).
Read Animating with JavaScript for the contract, and the guides for GSAP, Motion and the Web Animations API.
Matching
:namematches one path segment,*or(.*)matches anything.- The query string is ignored and a trailing slash is optional.
matchOptionschanges that:{ ignoreCase: true },{ strict: true }(the trailing slash has to match) and{ end: false }(/blogalso matches/blog/post). - Matching entries are checked in order. If the visit has an animation name, an entry with that name wins; otherwise the first entry without a name runs.
- When nothing matches, the visit simply does not wait.
How it fits in
It replaces the default behavior of the animation:out:await and animation:in:await hooks. Handlers registered with .before or normally still run around it.
Which animation runs: examples
With these entries:
new PagefoldJs([
{ name: 'slide', out: slideOut, in: slideIn },
{ from: '/', to: '/blog/:slug', out: zoomOut, in: zoomIn },
{ out: fadeOut, in: fadeIn },
])
| Visit | Runs | Why |
|---|---|---|
/ to /blog/hello | zoom | The second entry matches both patterns and has no name |
/about to /contact | fade | No pattern matches, so the first entry without a name runs |
/about to /contact, link has data-pagefold-animation="slide" | slide | An entry with the visit’s name wins, as long as its own patterns match |
/ to /blog/hello, link has data-pagefold-animation="slide" | slide | The name wins. The slide entry has no patterns, so it matches every visit |
Put the most specific entries first and a plain fallback last. Without a fallback, pages that match nothing change instantly.
Common problems
- The animation is skipped. No entry matched and there is no fallback, or the visit has
animation.animate = false(for example a back-button visit). See Caching and history. - The page waits forever. An
outorinthat takesdonenever calls it, for example because of an exception before it. Pagefold has no timeout of its own here, so wrap risky code intry / finally. - Both CSS and JS animate. Set
animationSelector: falseso Pagefold does not also wait for CSS transitions.
Options
| Option | Type | Default | What it does |
|---|---|---|---|
animations | JsAnimation[] | [] | The animations. The first one whose from and to patterns match the visit runs. |
matchOptions | { ignoreCase?, strict?, end? } | {} | How path patterns are matched: ignoreCase (default false), strict (the trailing slash has to match, default false) and end (default true; false also matches the paths below). |