UNPKG

movinblocks

Version:

Movinblocks is a lightweight plugin for animating HTML elements sequentially.

563 lines (425 loc) 18.6 kB
![Movinwblocks Logo](https://a.storyblok.com/f/99692/600x315/0e60a87860/movinblocks-ogimage.jpg) # Movinblocks Movinblocks is a lightweight plugin for animating HTML elements sequentially. ## Playgrounds Explore Movinblocks's capabilities in the [Playground](https://movinblocks.vercel.app/). Movinblocks is also available for your favorite Frameworks! [![Vue](https://a.storyblok.com/f/99692/80x80/38a9ffe002/vue.png)](https://stackblitz.com/edit/movinblocks-vue) [![React](https://a.storyblok.com/f/99692/80x80/2162faf2ae/react.png)](https://stackblitz.com/edit/movinblocks-react) [![Nuxt](https://a.storyblok.com/f/99692/80x80/1ee8d02e68/nuxt.png)](https://stackblitz.com/edit/movinblocks-nuxt) [![Next](https://a.storyblok.com/f/99692/80x80/3d5e4cb32d/next.png)](https://stackblitz.com/edit/movinblocks-next) [![Svelte](https://a.storyblok.com/f/99692/80x80/316e3ea903/svelte.png)](https://stackblitz.com/edit/movinblocks-svelte) [![Angular](https://a.storyblok.com/f/99692/80x80/2a2726dabb/angular.png)](https://stackblitz.com/edit/movinblocks-angular) --- ## Installation ```sh npm install movinblocks # npx movinblocks # pnpm add movinblocks # yarn add movinblocks ``` ## Basic Usage ### HTML ```html <header id="header">I am a header</header> <main id="main"> <section id="section">I am a section</section> </main> <footer id="footer">I am a footer</footer> ``` ### Javascript & CSS #### Using a Framework or Bundler (Recommended) ```typescript import Movinblocks from "movinblocks"; import "movinblocks/styles"; const mbInstance = new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .prepare() .start(); ``` ##### CSS Imports You can include all css styles at once: ```typescript import Movinblocks from "movinblocks"; // Imports ALL styles import "movinblocks/styles"; ``` Or import the styles you need only: ```typescript import Movinblocks from "movinblocks"; // Import the base styles (required) import "movinblocks/styles/base"; // Only import the animations you need import "movinblocks/styles/fadeIn"; import "movinblocks/styles/revealInTop"; ``` #### Using a CDN ```html <script src="https://unpkg.com/movinblocks/dist/movinblocks.min.js"></script> <link rel="stylesheet" href="https://unpkg.com/movinblocks@1.0.1/dist/styles/movinblocks.css" /> <!-- Or you can import animations individually: <link rel="stylesheet" href="https://unpkg.com/movinblocks@1.0.1/dist/styles/base.css"> <link rel="stylesheet" href="https://unpkg.com/movinblocks@1.0.1/dist/styles/animations/fadein.css"> <link rel="stylesheet" href="https://unpkg.com/movinblocks@1.0.1/dist/styles/animations/revealintop.css"> --> <script> (function () { const mbInstance = new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .prepare() .start(); })(); </script> ``` ## API Movinblocks comes with a minimal API: | Method | Description | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `setTimeline()` | Sets the sequence of HTML element IDs that will be animated in order of appearence (See [setTimeline()](#settimeline)). | | `setAnimation()` | Specifies the animation style to be applied to the elements (e.g., `fadeIn`) (See [setAnimation()](#setAnimation)). | | `setDuration()` | Defines the duration (in milliseconds) for each animation in the sequence (See [setDuration()](#setDuration)). | | `setTimingFunction()` | Defines the css timing function for each animation in the sequence (See [setTimingFunction()](#setTimingFunction)). | | `setIterationCount()` | Defines the css iteration count for each animation in the sequence (See [setIterationCount()](#setIterationCount)). | | `setOverlap()` | Sets the overlap time (in milliseconds) between consecutive animations (See [setOverlap()](#setOverlap)). | | `setViewportTrigger()` | Starts the animations when the elements intersects the viewport (See [setViewportTrigger()](#setViewportTrigger)). | | `on()` | Registers a callback for a specific event (e.g., `start`) during the animation (See [on()](#on)). | | `prepare()` | Sets up the timeline, elements, and settings required for the animation sequence, ensuring everything is ready to run (See [prepare()](#prepare)). | | `start()` | Triggers the animation sequence using the timeline and settings that were previously prepared (See [start()](#start)). | | `destroy()` | Destroy the Movinblocks instance (See [destroy()](#destroy)). | ### setTimeline ```typescript setTimeline(elementIds: string | string[]) ``` Use `setTimeline()` to set the sequence and order of appearence of the HTML **element IDs** that will be animated. ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) // header appears first, main second, section third, etc. .prepare() .start(); ``` ### setAnimation ```typescript setAnimation(animationName: MbAnimation | MbAnimation[]) ``` Use `setAnimation()` to choose the animation (or animations) for your elements. If you want each element to have its own animation, declare it as an _array of MbAnimation strings, with the same length and order as the timeline_: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation(["fadeIn", "slideInTop", "slideInBottom", "slideInLeft"]) // different animations for each element. .prepare() .start(); ``` If you want all elements to have the same animation, declare it as a _MbAnimation string_: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation("fadeIn") // all elements use the same animation. .start(); ``` #### Animations Configuration Movinblocks comes with these CSS Animations: | Name | Effect | | ---------------- | ------------------------------------------------------------------- | | `fadeIn` | Elements fade in | | `fadeOut` | Elements fade out | | `slideInTop` | Elements slide+fade in from top to bottom | | `slideInBottom` | Elements slide+fade in from bottom to top | | `slideInLeft` | Elements slide+fade in from left to right | | `slideInRight` | Elements slide+fade in from right to left | | `revealInTop` | Elements slide+fade in from top to bottom inside a hidden container | | `revealInBottom` | Elements slide+fade in from bottom to top inside a hidden container | Alternatively, you can _add custom animations of your own creation, or import them from other vendors_ (e.g: [animate.css](https://animate.style/)). ##### Custom Animation Here is an example of how to add a **custom animation**: ```css @keyframes myCustomAnimation { from { opacity: 1; background-color: #000; } to { opacity: 0; background-color: #4bafff; } } .myCustomAnimation { animation-name: myCustomAnimation; } ``` ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation("myCustomAnimation" as MbCustomAnimation) .start(); ``` ##### Vendor Animation Here is an example of how to add various animations of [animate.css](https://animate.style/): **Important: Make sure to import animate.css styles.** `import 'animate.css'` 1. **Using the Same Animation for All Elements** Apply a shared animate.css animation to all elements in the timeline: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation({ name: "bounceInUp", vendor: "animate.css" }) .start(); ``` 2. **Using Different Animations for Each Element** Assign a unique animate.css animation to each element: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation([ { name: "fadeIn", vendor: "animate.css" }, { name: "fadeInDown", vendor: "animate.css" }, { name: "bounceInUp", vendor: "animate.css" }, { name: "bounceIn", vendor: "animate.css" }, ]) .start(); ``` 3. **Mixing animate.css and Built-in Movinblocks Animations** Combine Movinblocks animations and animate.css animations for different elements: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation([ // Movinblocks' built-in "fadeIn" animation. "fadeIn", // Custom animate.css animations. { name: "fadeInDown", vendor: "animate.css" }, { name: "bounceInUp", vendor: "animate.css" }, { name: "bounceIn", vendor: "animate.css" }, ]) .start(); ``` ### setTimingFunction ```typescript setTimingFunction(timingFunctionName: MbTimingFunction | MbTimingFunction[]) ``` Use `setTimingFunction()` to choose the timing function (or functions) for your elements. ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setTimingFunction(["ease-in", "linear", "ease-in-out", "ease-out"]) // different timing functions for each element. .prepare() .start(); ``` If you want all elements to have the same timing function, declare it as a _MbTimingFunction string_: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setTimingFunction("linear") // all elements use the same timing function. .start(); ``` ### setIterationCount ```typescript setIterationCount(iterationCount: MbIterationCount | MbIterationCount[]) ``` Use `setIterationCount()` to choose the iteration count value (_number | 'infinite'_) for your elements. ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setIterationCount(["infinite", 1, 1, 3]) // different iteration count values for each element. .prepare() .start(); ``` If you want all elements to have the same iteration count value, declare it as a single _MbIterationCount value_: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setIterationCount("infinite") // all elements use 'infinite' as their iteration count value. .start(); ``` ### setDuration ```typescript setDuration(duration: number | number[]) ``` Use `setDuration()` to set the duration (in milliseconds) of your element's animations. If you want each element to have its own duration, declare it as an _array of numbers with the same length and order as the timeline_: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setDuration([1000, 500, 1200, 600]) // different durations for each element. .prepare() .start(); ``` If you want all elements to have the same animation, declare it as a _number_: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setDuration(420) // all elements use the same duration. .prepare() .start(); ``` ### setOverlap ```typescript setOverlap(overlap: number | number[]) ``` Use `setOverlap()` to set the overlap time (in milliseconds) between the animations of your elements. Important: Overlap is not supported when `setViewportTrigger()` is enabled (See [setViewportTrigger()](#setOverlap-and-setViewportTrigger) for details). If you want each element to have its own overlap time, declare it as an array of numbers: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setDuration(1000) .setOverlap([400, 300, 500]) // different overlap times for each element. .prepare() .start(); ``` Note: `setOverlap` takes one value less than the timeline. So, the `setOverlap([400, 300, 500])` array defines the overlap times for the elements **except for the first one (header)**: ```markdown 1. 0ms for the `header` element id (first element in the timeline): it will start without any overlap. 2. 400ms for the `main` element id: it will start 400ms before `header` finishes. 3. 300ms for the `section` element id: it will start 300ms before `main` finishes. 4. 500ms for the `footer` element id: it will start 500ms before `section` finishes. ``` If you want all elements to have the same overlap time, declare it as a number: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setDuration(1000) .setOverlap(350) // all elements have the same overlap time. .prepare() .start(); ``` ### setViewportTrigger ```typescript setViewportTrigger(intersectionOptions: MbIntersectionOptions | null = null) ``` You can choose to trigger Movinblocks **only when the element enters the viewport**. ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setDuration(1000) .setViewportTrigger() // each elements will start animating once inside the viewport. .prepare() .start(); ``` If you wish to modify the intersection properties, you can provide an `intersectionOptions` object as parameter of the method. ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setDuration(1000) .setViewportTrigger({ root: document.querySelector("#myElement"), rootMargin: "100px", threshold: 1.0, }) .prepare() .start(); ``` #### setOverlap and setViewportTrigger The **Overlap** functionality is not supported when `setViewportTrigger()` is enabled, as each element animates based on its own appearance in the viewport and no longer adheres to the shared timeline. ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setDuration(1000) .setOverlap(400) // ❌ It won't take effect because setViewportTrigger() is defined. .setViewportTrigger() .prepare() .start(); ``` ### on Use `on()` to register event listeners for specific events during the animation process. The `on()` method allows you to define callbacks that will be triggered when these events occurs: | Method | Description | |--|--| | `prepare` | Triggered when Movinblocks prepares. | | `start` | Triggered when Movinblocks starts. | | `end` | Triggered when Movinblocks ends. | | `destroy` | Triggered when the Movinblocks instance is destroyed.| | `animationStart` | Triggered when an animation starts. | | `animationIteration` | Triggered when an animation loop completes. | | `animationEnd` | Triggered when an animation ends. | ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation("fadeIn") .setDuration(1000) .on("start", (data) => console.log("Movinblocks started!", data)) .on("end", (data) => console.log("Movinblocks ended!", data)) .prepare() .start(); ``` #### Event Callback Data When using the `on()` method, the callback function receives an event data object containing the following properties: | Property | Type | Description | | ---------------- | ---------------- | -------------------------------------------------------------------------- | | `elements` | `Set<MbPayload>` | A set containing all elements managed by the current Movinblocks instance. | | `currentElement` | `MbPayload` | The specific element affected by the current event. | ```js { elements: Set<MbPayload>, // All elements in the Movinblocks instance. currentElement: MbPayload // The element affected by this event. } ``` This data lets you dynamically access and manipulate elements during the animation process. ### prepare The `prepare()` method sets up all necessary configurations for the animation sequence, such as the timeline, elements, and duration. This step ensures that everything is ready before calling `start()`. It's useful when you want to separate the initialization phase from execution. ```typescript const mbInstance = new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation("fadeIn") .setDuration(500) .prepare(); ``` You can use `prepare()` to perform setup tasks early and then call start() at the desired moment: ```typescript const mbInstance = new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .setAnimation("fadeIn") .setDuration(500) .prepare(); // Start the animation later document .getElementById("myButton") ?.addEventListener("click", () => mbInstance.start()); ``` This separation makes your code more modular and easier to manage in interactive scenarios. ### start The `start()` method initiates the animation sequence configured for Movinblocks. You can call `start()` as the last method in the instance chain for a straightforward setup: ```typescript new Movinblocks() .setTimeline(["header", "main", "section", "footer"]) .prepare() .start(); ``` Alternatively, you can detach it from the instance declaration and invoke it later in your code: ```typescript const mbInstance = new Movinblocks() .setTimeline(['header', 'main', 'section', 'footer']); .setDuration(420); .prepare() setTimeout(() => console.log('Just killing time'), 2000); mbInstance.start(); ``` Note: Make sure to have called `prepare()` before calling `start()`. ### destroy The `destroy()` method destroys a Movinblocks instance (including events, classes, and other resources). ```typescript const mbInstance = new Movinblocks() .setTimeline(['header', 'main', 'section', 'footer']); .prepare() .start(); setTimeout(() => mbInstance.destroy(), 2000) // Triggers the destroy after 2 seconds. ``` --- #### Like Movinblocks, but you want to animate texts instead? ## [Try Movinwords!](https://github.com/revueltai/movinwords) It's another lightweight plugin I created, designed for animating sentences, words, and letters in various creative ways. [Give it a go!](https://github.com/revueltai/movinwords)