Define once, apply anywhere

Reusable Animation Sets

Create site-wide motion tokens, load them before HF Motion, override individual values, and register sets at runtime.

Open playground
TOKENS
Markupdata-hf-set
Config APIHFMotionConfig.sets
Runtime APIdefineSet()

The set model

A set is a named object scoped to one effect type. This means fade.default and parallax.default can coexist without ambiguity.

Keep data-hf on the element so CSS can identify the effect immediately, then use data-hf-set to load the reusable settings.

<div data-hf="fade" data-hf-set="default">Content</div>
<script>
(function (document, window) {
  document.documentElement.classList.add('hf-motion-pending');
  window.HFMotionFirstPaintTimer = window.setTimeout(function () {
    document.documentElement.classList.remove('hf-motion-pending');
  }, 3000);
}(document, window));
</script>
<link rel="stylesheet" href="hf-motion.css">
<script>window.HFMotionConfig = window.HFMotionConfig || {};</script>
<script src="hf-motion-sets.js"></script>
<script src="hf-motion.min.js" defer></script>

hf-motion-sets.js is optional. Include it when markup uses data-hf-set; public class presets and exact data attributes only require the core stylesheet and runtime.

Complete extended set file

This is the exact preset file used by the offline documentation website.

/*!
 * HF Motion v1.0.0 - advanced reusable set pack for the offline documentation.
 * Free with attribution to https://humanfriend.digital/.
 * Attribution is waived for Human Friend Digital clients and development partners.
 * Load this file before hf-motion.min.js.
 */
(function (window) {
  'use strict';

  var config = window.HFMotionConfig = window.HFMotionConfig || {};
  var sets = config.sets = config.sets || {};

  sets.parallax = sets.parallax || {};
  sets.fade = sets.fade || {};
  sets.blur = sets.blur || {};
  sets.scale = sets.scale || {};
  sets.rotate = sets.rotate || {};

  sets.parallax.subtle = {
    direction: 'top',
    distance: 80,
    speed: 0.55
  };

  sets.parallax.default = {
    direction: 'top',
    distance: 160,
    speed: 0.85
  };

  sets.parallax.dramatic = {
    direction: 'top',
    distance: 300,
    speed: 1.1
  };

  sets.parallax.reverse = {
    direction: 'top',
    distance: 180,
    speed: -0.75
  };

  sets.fade.soft = {
    direction: 'none',
    duration: 600,
    distance: 0,
    easing: 'ease-out'
  };

  sets.fade.quick = {
    direction: 'bottom',
    duration: 500,
    distance: 28,
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
  };

  sets.fade.default = {
    direction: 'bottom',
    duration: 800,
    distance: 40,
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
  };

  sets.fade.dramatic = {
    direction: 'bottom',
    duration: 1100,
    distance: 90,
    easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
  };

  sets.blur.soft = {
    direction: 'none',
    blur: 8,
    duration: 650,
    easing: 'ease-out'
  };

  sets.blur.default = {
    direction: 'bottom',
    distance: 24,
    blur: 12,
    duration: 800,
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
  };

  sets.blur.dramatic = {
    direction: 'bottom',
    distance: 36,
    blur: 24,
    duration: 1050,
    easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
  };

  sets.scale.subtle = {
    scale: 0.96,
    duration: 550,
    origin: 'center center',
    easing: 'ease-out'
  };

  sets.scale.default = {
    scale: 0.92,
    duration: 700,
    origin: 'center center',
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
  };

  sets.scale.pop = {
    scale: 0.78,
    duration: 800,
    origin: 'center center',
    easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
  };

  sets.scale.settle = {
    scale: 1.1,
    duration: 750,
    origin: 'center center',
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
  };

  sets.rotate.subtle = {
    rotate: 4,
    duration: 650,
    origin: 'center center',
    easing: 'ease-out'
  };

  sets.rotate.default = {
    rotate: 7,
    duration: 750,
    origin: 'center center',
    easing: 'cubic-bezier(0.22, 1, 0.36, 1)'
  };

  sets.rotate.dramatic = {
    rotate: -12,
    duration: 950,
    origin: 'bottom left',
    easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
  };

  sets.rotate.hinge = {
    direction: 'bottom',
    distance: 24,
    rotate: 10,
    duration: 900,
    origin: 'bottom right',
    easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
  };
}(window));

Download this file

Register a set at runtime

HFMotion.defineSet('parallax', 'hero', {
  direction: 'top',
  distance: 360,
  speed: 1.2
});
<div data-hf="parallax" data-hf-set="hero">
  Hero artwork
</div>

HFMotion.defineSet() merges the settings and refreshes initialized elements.

Naming guidance

  • Use intent-based names such as hero, editorial, or card when a set belongs to a component system.
  • Use intensity names such as subtle, default, and dramatic for broad site-wide utilities.
  • Keep each set focused on one effect type and stack effects with wrappers.
  • Override individual attributes only where a component genuinely differs.