Menu

Checkpoint

Animate elements on scroll.


Demos

Built-In Animations

Use the built-in animations.

<div class="box js-checkpoint" data-checkpoint-animation="fade-in">
  fade-in
</div>

<div class="box js-checkpoint" data-checkpoint-animation="fade-up">
  fade-up
</div>

<div class="box js-checkpoint" data-checkpoint-animation="fade-down">
  fade-down
</div>

<div class="box js-checkpoint" data-checkpoint-animation="fade-left">
  fade-left
</div>

<div class="box js-checkpoint" data-checkpoint-animation="fade-right">
  fade-right
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-in">
  zoom-in
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-in-up">
  zoom-in-up
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-in-down">
  zoom-in-down
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-in-left">
  zoom-in-left
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-in-right">
  zoom-in-right
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-out">
  zoom-out
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-out-up">
  zoom-out-up
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-out-down">
  zoom-out-down
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-out-left">
  zoom-out-left
</div>

<div class="box js-checkpoint" data-checkpoint-animation="zoom-out-right">
  zoom-in-right
</div>

<div class="box js-checkpoint" data-checkpoint-animation="flip-up">
  flip-up
</div>

<div class="box js-checkpoint" data-checkpoint-animation="flip-down">
  flip-down
</div>

<div class="box js-checkpoint" data-checkpoint-animation="flip-left">
  flip-left
</div>

<div class="box js-checkpoint" data-checkpoint-animation="flip-right">
  flip-right
</div>

<div class="marker"></div>
import { CheckPoint, Utils } from 'formstone';

Utils.ready(() =&gt; {
  CheckPoint.construct('.js-checkpoint', {
    offset: '25%',
    reverse: true,
  });
});

body {
  padding-bottom: 30vh;
}

body::before {
  align-items: center;
  content: 'Scroll Down\A\21E3';
  display: flex;
  height: 105vh;
  justify-content: center;
  text-align: center;
  white-space: pre-wrap;
}

.box {
  background: var(--color-yellow);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
  margin: 0 auto 30vh;
  width: 200px;
  padding: 20px 10px;
  text-align: center;
}

.marker {
  width: 100%;
  height: 0;
  position: fixed;
  bottom: 25vh;
  border: 1px dashed var(--color-blue);
}

.marker::before {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 10px;
  color: var(--color-blue);
  content: 'offset: 25%';
  text-transform: uppercase;
  font-size: 14px;
  line-height: 1;
}

Custom Animation

Define a custom animation.

<div class="box js-checkpoint" data-checkpoint-animation="spinner">
  spinner
</div>

<div class="marker"></div>
import { CheckPoint, Utils } from 'formstone';

Utils.ready(() =&gt; {
  CheckPoint.construct('.js-checkpoint', {
    offset: '25%',
    reverse: true,
  });
});
[data-checkpoint-animation="spinner"] {
  --opacity: 0;
  --transform: translate(0, 100%) scale(0.5) rotate(300deg);
  --duration: 0.5s;
  --ease: cubic-bezier(0.47, 1.64, 0.41, 0.8);

  opacity: var(--opacity);
  transform: var(--transform);
  transition:
    opacity var(--duration) linear,
    transform var(--duration) var(--ease);
}

[data-checkpoint-animation="spinner"].fs-checkpoint-active {
  --opacity: 1;
  --transform: translate(0, 0) scale(1) rotate(0deg);
}

body {
  padding-bottom: 30vh;
}

body::before {
  align-items: center;
  content: 'Scroll Down\A\21E3';
  display: flex;
  height: 105vh;
  justify-content: center;
  text-align: center;
  white-space: pre-wrap;
}

.box {
  background: var(--color-yellow);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
  margin: 0 auto 30vh;
  width: 200px;
  padding: 20px 10px;
  text-align: center;
}

.marker {
  width: 100%;
  height: 0;
  position: fixed;
  bottom: 25vh;
  border: 1px dashed var(--color-blue);
}

.marker::before {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 10px;
  color: var(--color-blue);
  content: 'offset: 25%';
  text-transform: uppercase;
  font-size: 14px;
  line-height: 1;
}

Trigger

Set an element to act as the animation trigger.

<div class="container">
  <div class="box js-checkpoint" data-checkpoint-trigger=".trigger" data-checkpoint-animation="trigger">
    trigger
  </div>
  <div class="trigger">
    Scroll Trigger
  </div>
</div>

<div class="marker"></div>
import { CheckPoint, Utils } from 'formstone';

Utils.ready(() =&gt; {
  CheckPoint.construct('.js-checkpoint', {
    offset: '25%',
    reverse: true,
  });
});
body {
  background: var(--color-gray-5);
}

body::before {
  align-items: center;
  content: 'Scroll Down\A\21E3';
  display: flex;
  height: 85vh;
  justify-content: center;
  text-align: center;
  white-space: pre-wrap;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-radius: var(--border-size);
  padding: 10vh;
}

.trigger {
  align-self: flex-end;
  background: var(--color-blue);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
  margin: 80vh auto;
  padding: 5px 10px;
  text-align: center;
  width: 200px;
}

.box {
  position: sticky;
  top: 50vh;
  align-self: flex-start;
  background: var(--color-white);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
  margin: 0 auto;
  width: 200px;
  padding: 20px 10px;
  text-align: center;
  transform: translate(0, -50%);
}

.box.fs-checkpoint-active {
  background: var(--color-yellow);
}

.marker {
  width: 100%;
  height: 0;
  position: fixed;
  bottom: 25vh;
  border: 1px dashed var(--color-blue);
}

.marker::before {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 10px;
  color: var(--color-blue);
  content: 'offset: 25%';
  text-transform: uppercase;
  font-size: 14px;
  line-height: 1;
}

Container

Set a container to animate elements inside a parent.

<div class="container">
  <div class="box js-checkpoint" data-checkpoint-container=".container" data-checkpoint-animation="fade-in">
    fade-up
  </div>
</div>

<div class="marker"></div>
import { CheckPoint, Utils } from 'formstone';

Utils.ready(() =&gt; {
  CheckPoint.construct('.js-checkpoint', {
    offset: '75%',
    reverse: true,
  });
});
body {
  background: var(--color-gray-5);
  padding-bottom: 60vh;
}

body::before {
  align-items: center;
  content: 'Scroll Down\A\21E3';
  display: flex;
  height: 85vh;
  justify-content: center;
  text-align: center;
  white-space: pre-wrap;
}

.container {
  display: flex;
  align-items: flex-end;
  height: 50vh;
  margin: 0 10vh 10vh;
  background: var(--color-white);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
}

.box {
  background: var(--color-yellow);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
  margin: 0 auto 20px;
  width: 200px;
  padding: 20px 10px;
  text-align: center;
}

.marker {
  width: 100%;
  height: 0;
  position: fixed;
  bottom: 75vh;
  border: 1px dashed var(--color-blue);
}

.marker::before {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 10px;
  color: var(--color-blue);
  content: 'offset: 75%';
  text-transform: uppercase;
  font-size: 14px;
  line-height: 1;
}

Parent

Set a container to animate elements inside a scrollable parent.

<div class="parent_wrapper">
  <div class="parent">

    <div class="box js-checkpoint" data-checkpoint-parent=".parent" data-checkpoint-animation="fade-in">
      fade-up
    </div>

    <div class="marker"></div>

  </div>
</div>
import { CheckPoint, Utils } from 'formstone';

Utils.ready(() =&gt; {
  CheckPoint.construct('.js-checkpoint', {
    offset: '25%',
    reverse: true,
  });
});
body {
  background: var(--color-gray-5);
  padding-bottom: 30vh;
}

body::before,
.parent::before {
  align-items: center;
  content: 'Scroll Down\A\21E3';
  display: flex;
  height: 85vh;
  justify-content: center;
  text-align: center;
  white-space: pre-wrap;
}

body::before {
  height: 75vh;
}

.parent {
  overflow-y: scroll;
  height: 80vh;
  margin: 10vh;
  background: var(--color-white);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
  padding-bottom: 30vh;
}

.parent_wrapper {
  position: relative;
}

.box {
  background: var(--color-yellow);
  border: var(--border-size) solid var(--color-black);
  border-radius: var(--border-size);
  margin: 0 auto 30vh;
  width: 200px;
  padding: 20px 10px;
  text-align: center;
}

.marker {
  width: calc(100% - 20vh - 4px);
  height: 0;
  position: absolute;
  bottom: 25%;
  border: 1px dashed var(--color-blue);
}

.marker::before {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 10px;
  color: var(--color-blue);
  content: 'offset: 25%';
  text-transform: uppercase;
  font-size: 14px;
  line-height: 1;
}

Options

Set instance options by passing a valid object at initialization, or to the public .defaults() method. Custom options for a specific instance can also be set by attaching a data-checkpoint-options attribute containing a properly formatted JSON object to the target element.

Name Type Default Description
offset string '0px' Element offset for activating animation (pixels or percentage)
reverse boolean false Deactivate animation when scrolling back

Data attributes provide additional configuration options and can be set directly on the target element.

Name Type Description
data-checkpoint-options string (JSON) JSON encoded object containing instance options
data-checkpoint-animation string Animation type (e.g., fade-in, zoom-in-up, flip-left)
data-checkpoint-offset string Custom offset value, overrides the option (pixels or percentage)
data-checkpoint-parent string Selector for a scrollable parent container
data-checkpoint-trigger string Selector for a custom trigger element
data-checkpoint-container string Selector for parent trigger element

Methods

Methods are publicly available to all active instances, unless otherwise stated.

Name Description
.construct() Initializes CheckPoint plugin on target elements
.defaults() Sets default options for future CheckPoint instances
.destroy() Removes plugin and all related data
.enable() Enables the CheckPoint instance
.disable() Disables the CheckPoint instance
.activate() Activates the checkpoint animation
.deactivate() Deactivates the checkpoint animation

.construct()

Initializes CheckPoint plugin on target elements.

Parameters

Name Type Default Description
selector string (required) '' Selector string to target
options object (optional) {} Object containing instance options

Returns

Type Description
NodeList NodeList of target elements

Examples

let targets = CheckPoint.construct('.js-checkpoint');
let targets = CheckPoint.construct('.js-checkpoint', {
  reverse: true
});

.defaults()

Sets default options for future CheckPoint instances.

Parameters

Name Type Default Description
options object (required) {} Object containing default options

Examples

CheckPoint.defaults({
  reverse: true
});

.destroy()

Removes plugin and all related data.

Examples

el.CheckPoint.destroy();

.enable()

Enables the CheckPoint instance.

Examples

el.CheckPoint.enable();

.disable()

Disables the CheckPoint instance.

Examples

el.CheckPoint.disable();

.activate()

Activates the checkpoint animation.

Examples

el.CheckPoint.activate();

.deactivate()

Deactivates the checkpoint animation.

Examples

el.CheckPoint.deactivate();

Events

Events are triggered on the target instance's element, unless otherwise stated.

Name Description
checkpoint:activate Checkpoint animation activated
checkpoint:deactivate Checkpoint animation deactivated

Styles

CSS custom properties are used to modify default styles.

Property Default Description
--fs-checkpoint-duration 0.5s Transition duration (all animations)
--fs-checkpoint-distance 50px Translate distance (fade, zoom)
--fs-checkpoint-perspective 3000px Perspective value (flip)
--fs-checkpoint-rotate 90deg Rotation amount (flip)
--fs-checkpoint-scale-in 0.5 Scale amount (zoom-in)
--fs-checkpoint-scale-out 1.25 Scale amount (zoom-out)

Classes allow deeper customization and indicate the current state of a specific instance.

Classname Type Description
.fs-checkpoint element Target element
.fs-checkpoint-active modifier Indicates active state