npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

css-driven

v0.2.1

Published

CSS Driven Transitions and Animations Library

Downloads

51

Readme

CSS Driven Animations

without the callback hell

CSS Driven is a small library for helping you drive CSS animations using Javascript and requestAnimationFrame. Getting your head around the timing can be tricky, especially if you want to set your timing in CSS rather than JavaScript. CSS Driven helps with that.

Install

npm install css-driven

CSS Driven uses standard DOM methods, and does not rely on jQuery et al.

Usage Guide

Use the method CSSDriven.doTransition to set a CSS based animation or transition in motion. Consider this:

var modal = document.querySelector(".modal");

CSSDriven.doTransition(modal, {
  "setup": "+is-animating",   // add the class is-animating
  "trigger": "~is-hidden",    // toggle the class is-hidden
  "end": "-is-animating"      // remove the class is-animating
});
.modal {
  position: fixed;
  top: 20%;
  right: 20%;
  bottom: 20%;
  left: 20%;
  border-radius: 20px;
  background: linear-gradient(90deg, #d53369 33%, #cbad6d 67%);
}

.modal.is-animating {
  transition: opacity 0.5s ease-out 0.2s, transform 1s ease-out;
  display: block !important;
}

.modal.is-hidden {
  display: none;
  opacity: 0;
  transform: scale(1.5) rotate(180deg);
}

In this example, we have a funky modal we want to animate in with some excessive effects. We want to make sure the animation is timed based on the transition that will take the longest, in this case it's the transformation.

On calling doTransition, CSSDriven will:

  • Run the "setup" instruction - add the class is-animating
  • Measure all transition and animation durations + delays to find the longest running transition, and use that time as our endpoint.
  • Run the "trigger" instruction on the next frame - toggling the class is-hidden
  • Wait until 1000ms has passed, and then run the "end" instruction - removing the class is-animating.

Under the hood, this sensitive timing is handled by a dispatcher using requestAnimationFrame to get your timing down to the millisecond. In fact, "setup", "end" and "trigger" are just aliases for timing. You'd get the same result with:

CSSDriven.doTransition(modal, {
  "0": "+is-animating",    // execute immediately (frame 0)
  "1": "~is-hidden",       // execute at frame 1
  "100%": "-is-animating"  // execute once 100% of the animation has passed
});

This interface gives you plenty of flexibility to base your Javascript execution upon the timing of CSS transitions and animations. You could use different percentages to tweak the CSS in flight, possibly a z-index if you're transitioning into a page.

In a more complex example, lets imagine an accordion with a body:

var accordion = document.getElementById("accordion");
var accordionToggle = document.getElementById("accordion-header");

accordionToggle.addEventListener("click", function() {
  if (accordion.classList.contains("is-animating")) return false;
  CSSDriven.doTransition(accordion, {
    "setup": [function($el, state) {

      // measuring desired accordion height and setting start point
      var startHeight = $el.querySelector(".accordion__body").offsetHeight;
      $el.classList.toggle("is-open");
      var targetHeight = $el.querySelector(".accordion__body").offsetHeight;
      $el.classList.toggle("is-open");
      $el.querySelector(".accordion__body").style.height = startHeight + "px";
      $el.querySelector(".accordion__body").offsetHeight;
      return targetHeight; // returning the target height as state

    }, "+is-animating"],
    "trigger": function($el, state) {
      $el.querySelector(".accordion__body").style.height = state + "px";
    },
    "end": [function($el, state) {
      $el.querySelector(".accordion__body").style.height = null;
      $el.classList.toggle("is-open");
    }, "-is-animating"]
  }, {
    "timingElement": accordion.querySelector(".accordion__body"),
  });

});

Here we're using the same timing, but instead of just flipping classes, we're transitioning from auto to 0px. Those who've tried know that CSS alone can't do it, but here we're breaking it down into clear frame steps that let CSS step in when it needs to. The function also has the ability to pass state to future steps, so you can make use of measurements you've made.

Because the transition doesn't actually occur on the accordion where we're changing the classes, we've added an option at the end, "timingElement" lets us set a different element to measure the transition/animation timing on.

Browser Support

css-driven aims to technically support IE8+ - but perform best in modern browsers. Obviously browsers that do not support CSS transitions cannot transition so this is detected we fallback to run each of the steps in sequence which more often than not is more than acceptable.

IE8/9 required polyfills

We do use some more modern Javscript features so you will need to polyfill the following for the css-driven to run in older browsers (IE8/9).

Method Reference

doTransition(domElement, instructions, options)

Perform a transition on the DOM element provided, based on the instructions. Frame 0 is triggered immediately and synchronously. All other steps are executed using requestAnimationFrame to the appropriate frame or timestamp.

options

  • name: name the animation, useful for debug mode
  • timingElement: set an alternative DOM element to use for measuring the timing of the transition.
  • fallback: set a custom fallback function that will be called if requestAnimationFrame is not found. By default CSSDriven will just run through the steps immediately, but if you want to maybe provide a Javascript Driven alternative this is a way to do it.

debugMode(boolean)

not available in minified version

Set the debug mode to be true or false. When in debug mode, transitions will log out to the console when handlers are triggered, along with their current state.

fallbackMode(boolean)

not available in minified version

Set the fallback mode to be true or false. When in fallback mode, CSS Driven will always act as if requestAnimationFrame is not available, and run either your fallback function, or all the steps in sequence synchronously. Useful so you can write your doTransition fallback functions in modern browsers.

License

Copyright (c) 2014 Offsider, used under The MIT License (MIT)