-JOS-Animation, Javascript On Scroll Animation library is a simple & easy to use animation library package to instantly add professional animation to your website. It was built to make my life easier while developing websites & comes with tons of features and is fully customizable. It is lightweight & has a very small footprint. The best part of all is that it has no (\*minimum) toll on performance.
+
+ A lightweight, performant scroll animation library for the web
+
-- Open source, no download or tiring setup, just add a script tag (Embed).
-- Includes Preset and expert custom animation options.
-- Works with all major browsers & Platforms.
-- Fast, light and small with no/min toll on performance.
-- Simple & easy to setup for both beginners & experts.
-- Customize animation settings and build your own scroll invoked functions
-- [npm](https://www.npmjs.com/package/jos-animation) & [CDNjs](https://cdnjs.com/libraries/jos-animation) approved library for the fastest deliveries
-- And lots more stuff... explore it yourself.
+---
-This project is currently being developed by me & the dev community, So you can expect more features and updates quite often..
+## About
-Was inspired by GSAP, AOS libraries. I wanted something easier to use, with great performance and wanted to make the implementation better. So I worked on this project from scratch.
+JOS (JavaScript On Scroll) is a scroll animation library that uses the Intersection Observer API for high-performance, jank-free animations. Add `class="jos"` to any element and it animates on scroll — zero configuration required.
-Feel free to report an issue or request a feature in this repository :)
-& for more information, Check out the [JOS Webpage](https://jos-animation.vercel.app).
-
+**Key features:**
-
-
-Badges
-
+- **Tiny footprint** — under 3KB gzipped
+- **60+ built-in animations** — fade, slide, zoom, flip, rotate, spin, skew, filters, and more
+- **Stagger support** — sequential child animations with configurable delay
+- **Scroll progress callbacks** — bind element properties to scroll position
+- **Direction-aware** — animate only on scroll up or down
+- **Anchor triggers** — trigger animations based on another element's visibility
+- **Custom animations** — define your own with simple CSS classes
+- **Framework-friendly** — works with React, Vue, Angular, Svelte, Next.js, Nuxt
+- **Zero dependencies** — pure JavaScript + CSS
+- **ES Modules, CJS, UMD** — works everywhere
-
+## Quick Start
-
-
+### CDN (fastest)
```html
-
-
+
+
```
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+That's it. The JS-only build auto-injects the required CSS. For separate CSS control:
-
-
-
-Video Tutorial
-
-
-
-
-
-
-JOSv0.9.2 11 Nov 2023Jesvi Jonathan
-
-
-
-### Built With
-
-- [JavaScript](https://www.w3schools.com/js/)
-- [CSS](https://www.w3schools.com/css/)
-
-## Installing JOS
-
-### Embedding JOS
-
-
+```html
+
+
+```
-
-
+### npm
-
-
-
-
+```js
+import JOS from "jos-animation";
+import "jos-animation/css"; // optional — only needed if using the JS-only bundle
-
+
+
-You have the option to use the latest version of JOS from a variety of sources :
+
+
+```
-##### [CDNJS](https://cdnjs.com/libraries/jos-animation)
+## Usage
-
+### 1. Add the `jos` class
```html
-
+
I'll fade in on scroll
```
-##### (or) [JSDELIVR](https://cdnjs.com/libraries/jos-animation)
+### 2. Customize with data attributes
```html
-
+
+ Flip up once with a delay
+
```
-
-
-Click here to check out other Sources / CDNs
-
-- #### [JSDELIVR](https://www.jsdelivr.com/package/npm/jos-animation)
-
-
-
- ```html
-
- ```
-
- (or)
-
- ```html
-
- ```
-
- (or)
-
- ```html
-
- ```
-
-- #### [UNPKG](https://unpkg.com/jos-animation/)
-
-
-
- ```html
-
- ```
-
- (or)
-
- ```html
-
- ```
-
-- #### [Github](https://raw.githubusercontent.com/jesvijonathan/JOS-Animation-Library/master/dist/jos.js)
-
-
-
- ```html
-
- ```
-
-
-
-
-
-You can add minified version of the script by replacing jos.js with
-jos.min.js in the above script tag.
-
-
-
-- jos.js for basic. - jos.min.js for production use. -
- jos.debug.js for debugging along with some other
- function From v0.9 onwards, by default jos.js does not
- require you to add the stylesheet jos.css, it will be exported
- along with the script. But you can still add the stylesheet if you want to for
- some reason. ### Importing JOS 1. Install JOS using npm (yarn or pnpm) : ```bash
- npm install jos-animation
-
-#### Version Tags
-
-
-
-- Latest : jos-animation@latest
-- Stable : jos-animation@0.8.8
-- Beta : jos-animation@0.9.0-beta.1
-
-So it would be https://unpkg.com/jos-animation/@latest/dist/jos.js (embed) for the latest version. or jos-animation/@0.8.8/dist/jos.js (npm install) for a specific version.
-
-
-
-
-
-
-
-
-
-
-## Importing JOS
-
-1. Install JOS using npm (yarn or pnpm) :
-
-```bash
-npm install jos-animation
```
-2. Import JOS in your project :
-
-```js
-// import "jos-animation/dist/jos.css";
-// Above is required only for v0.8.8 & below (or) if you want to overide jos by using style from the stylesheet
+## Animations
-import JOS from "jos-animation";
+### Transform Animations
-// Other ways to import JOS
-// import JOS from "jos-animation/dist/jos.js";
-// import JOS from "jos-animation/dist/jos.min.js";
-// import JOS from "jos-animation/dist/jos.debug.js";
-```
+| Category | Animations |
+|----------|-----------|
+| **Fade** | `fade`, `fade-up`, `fade-down`, `fade-left`, `fade-right`, `fade-left-up`, `fade-left-down`, `fade-right-up`, `fade-right-down` |
+| **Slide** | `slide`, `slide-left`, `slide-up`, `slide-down`, `slide-right-up`, `slide-right-down`, `slide-left-up`, `slide-left-down` |
+| **Zoom** | `zoom`, `zoom-in`, `zoom-out-right`, `zoom-out-left`, `zoom-out-up`, `zoom-out-down`, `zoom-in-right`, `zoom-in-left`, `zoom-in-up`, `zoom-in-down` |
+| **Flip** | `flip`, `flip-left`, `flip-up`, `flip-down` |
+| **Rotate** | `rotate`, `rotate-left` |
+| **Spin** | `spin`, `spin-left` |
+| **Revolve** | `revolve`, `revolve-left` |
+| **Grow** | `grow`, `grow-right`, `grow-left`, `grow-up`, `grow-down` |
+| **Shrink** | `shrink`, `shrink-right`, `shrink-left`, `shrink-up`, `shrink-down` |
+| **Stretch** | `stretch`, `stretch-vertical` |
+| **Skew** | `skew`, `skew-left`, `skew-right`, `skew-up`, `skew-down` |
+| **Slant** | `slant`, `slant-right`, `slant-left` |
+| **Bar** | `bar`, `bar_horizontal` |
-
+### Filter Animations
-### Frameworks
+`blur`, `grey`, `sepia`, `invert`, `brightness`, `saturate`, `hue-rotate`, `backdrop`
-
-Vue / Nuxt.js
+### Playable (Looping) Animations
-```js
-// main.js
+`slide-play`, `slide-vertical-play`, `zoom-in-play`, `zoom-play`, `flip-play`, `rotate-play`, `spin-play`, `revolve-play`, `grow-play`, `shrink-play`, `stretch-play`, `stretch-vertical-play`, `fade-play`, `fade-horizontal-play`, `fade-vertical-play`, `blink-play`, `pulse-play`
-import { createApp } from "vue";
-import { watch, nextTick } from "vue";
+### Utility Classes
-import JOS from "jos-animation"; // jos-animation/dist/jos.debug.js
+`static`, `none`, `hidden`, `visible`, `no-transition`
-import App from "./App.vue";
+## Features
-const app = createApp(App);
-app.mount("#app");
+### Stagger
-JOS.init();
-//JOS.version();
-
-watch(
- () => router.currentRoute.value,
- () => {
- nextTick(() => {
- JOS.refresh();
- });
- }
-);
+Animate children sequentially:
-// To observe elements after a route change
-```
-
-Used in : [https://jos-animation.vercel.app/](https://github.com/jesvijonathan/JOS-Animation-Playground/blob/main/src/main.js)
-
-This above example for Vue.js is also applicable for Nuxt.js
-
-
-
-
-React
-
-```js
-// index.js
-
-import JOS from "jos-animation/dist/jos.js";
-
-onload = () => {
- const options = {
- debugMode: true,
- animation: "flip",
- duration: 0.7,
- rootMargin: "0% 0% 0% 0%",
- };
- JOS.init(options);
- //JOS.version();
-};
-
-function Main() {
- useEffect(() => {
- JOS.refresh();
- }, []);
- // To observe elements after a route change
-
- return (
-
-
-
- );
-}
-
-ReactDOM.createRoot(document.getElementById("root")).render();
-```
-
-Used in : [https://azzle.netlify.app](https://azzle.netlify.app/)
-
-This above example is for React.js is also applicable for Next.js & Preact.js
-
-
-
-Next.js
-
-```js
-// app/layout.tsx
-
-import jos from "jos-animation/dist/jos.js";
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode;
-}) {
-const jos_options = {
- debugMode: false,
- passive: true,
- animation: "fade",
- duration: 0.4,
- rootMargin: "20% 0% 30% 0%",
- };
-
- useEffect(() => {
- jos.init(jos_options);
- }, []); // Once
-
- useEffect(() => {
- jos.refresh();
- }); // For every update
-
- return ();
-}
-// To observe elements after a route change
+```html
+
+
First
+
Second (0.1s later)
+
Third (0.2s later)
+
```
-Used in : [https://bitspace-nextjs-jos.vercel.app](https://github.com/jesvijonathan/bitspace-org-in/blob/master/src/app/layout.tsx)
-
-
-
-
-Angular
+### Scroll Direction
-```js
-import { Component, OnInit, AfterViewChecked } from '@angular/core';
+Animate only when scrolling in a specific direction:
-import JOS from 'jos-animation';
-
-@Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
-})
-export class AppComponent implements OnInit, AfterViewChecked {
-
- ngOnInit(): void {
- JOS.init(); // Once
- }
-
- ngAfterViewChecked(): void {
- JOS.refresh(); // For every update
- }
-
- // ... rest of your code
-
-}
+```html
+
+ Only animates on scroll down
+
```
-
-
-You can check this discussion thread for more information : [JOS for Angular](https://github.com/jesvijonathan/JOS-Animation-Library/issues/41#issuecomment-1914803098)
-
-
-
+### Scroll Progress Callback
-## Setup
-
-1. Use JOS.init(); to initialize the library with default settings.
+Bind element properties to scroll position:
```html
-
-
-```
-
-2. (Or) Use JOS.init(options); to overide the default settings with your custom settings.
+
+ 0%
+
-```html
-
```
-3. Set class="jos" to the element you want to animate :
-
-```html
-
-
-```
+### Anchor Triggers
-4. Set data-jos \*attributes to customize the element you want to animate, (although these attributes are optional and will work without them) :
+Animate an element based on another element's visibility:
```html
-
-
+
Scroll me into view...
+
+ I animate when #trigger-area enters the viewport
+
```
-See [JOS Props](#jos-attributes) for full information regarding the animation, attributes, and options.
-
-## Custom Animation
-
-1. Create a custom animation by adding the following code to your stylesheet :
-
-```css
-/* Custom animation class name starts with 'jos-' keyword followed by the animation name*/
-.jos-my-custom-animation {
- /* Set the initial state of the element */
-}
-```
+### Inverse Animations
-2. Use your custom animation by setting the data-jos_animation attribute to my-custom-animation :
+Apply a different animation on exit:
```html
-
+
+ Normal on enter, custom animation on exit
+
```
-Example : [Custom Animation]()
-
-## Custom Inverse Animation
+### Custom Animations
-1. Create a custom inverse animation by adding the following code to your stylesheet :
+Define your own with a CSS class prefixed with `jos-`:
```css
-/* Custom inverse animation class name starts with 'jos-' keyword followed by the animation name*/
-.jos-my-custom-animation-inverse {
- /* Set the initial state of the element */
+.jos-my-animation {
+ opacity: 0;
+ transform: translateX(-50px) rotate(-10deg);
}
```
-2. Use your custom inverse animation by setting the data-jos_animationInverse attribute to my-custom-animation-inverse :
-
```html
-
+
Custom!
```
-This is especially useful when you want to animate an element when it is **scrolled out of its rootMargin**, this gives more customizability for beautiful animations.
-
-You can also use a combination of both data-jos_animation ("none", "static", no-transition, etc) & data-jos_animationInverse attributes to create a custom animation.
+### Invoke Callbacks
-Example : [Custom Inverse Animation]()
-
-## Playable Animation
-
-1. Create a playable animation by adding the following code to your stylesheet :
-
-```css
-/* Custom playable animation class name starts with 'jos-' keyword followed by the animation name*/
+Run functions on enter/exit:
-/* My Custom Playable Animation */
-.jos-my-custom-animation {
- transition: 1s;
- animation: jos-my-custom-animation 1s ease-in-out infinite;
- transform: translateX(100px);
-}
-/* Add Keyframes */
-@keyframes jos-my-custom-animation {
- 0% {
- opacity: 1;
- }
+```html
+
+ Check the console
+
- 50% {
- transform: translateX(-100px);
- }
-}
+
```
-1. Use the playable animation by setting the data-jos_animation attribute to my-custom-animation & data-jos_animationInverse attribute to my-custom-animation-play :
+### Once / Repeat Count
```html
-
+
Animates once
+
Animates 3 times
```
-Here the data-jos_animationinverse attribute is set to static to prevent the element from animating out of view & to keep it in the final state. The Playable animation is triggered and starts playing when the element is scrolled into view.
-
-Example : [Playable Animation]()
-
-## Custom Timing Function
-
-1. Create a custom timing function by adding the following code to your stylesheet :
-
-```css
-/* Custom timing function attribute name starts with 'data-jos_timing_function' keyword & a custom name of your choice */
-[data-jos_timing_function="myCustom-timingFunc"] {
- /* Set the timing of the element */
- transition-timing-function: cubic-bezier(0.2, 0.5, 0.2, 0.5) !important;
-}
-```
+### Start Visible
-2. Use your custom timing function by setting the data-jos_timing-function attribute to my-custom-timing-function :
+Skip initial animation for above-the-fold elements:
```html
-
+
Visible immediately
+
Visible after 2s
```
-Example : [Custom Timing Function]()
+### Scroll Progress CSS Custom Properties
-## Anchors to trigger animation
+Every element with `data-jos_scroll` gets live CSS custom properties you can use directly in CSS:
-1. Create an element that you want to use as an anchor & add an id to it :
+| Property | Range | Description |
+|----------|-------|-------------|
+| `--jos_scroll` | `0` → `1` | Scroll progress (0 at bottom trigger, 1 at top) |
+| `--jos_scroll_reverse` | `1` → `0` | Inverse of `--jos_scroll` |
+| `--jos_scroll_perc` | `0%` → `100%` | Progress as percentage string |
+| `--jos_scroll_deg` | `0deg` → `360deg` | Progress as rotation |
+| `--jos_windowScroll` | `0` → `1` | Element position relative to viewport |
+| `--jos_windowScroll_reverse` | `1` → `0` | Inverse of window scroll |
+| `--jos_rootScroll` | `0` → `1` | Same as `--jos_scroll` |
+| `--jos_rootScroll_reverse` | `1` → `0` | Same as `--jos_scroll_reverse` |
```html
-
-
-```
-
-1. Create an element that you want to animate & add the data-jos_anchor attribute to it, with the id starting with suffix # :
-
-```html
-
-
+
+
+ Parallax element
+
```
-This triggers the animation when the myElement element is scrolled into view.
-This feature is useful especially when you want to animate an element which is in a fixed position.
-
-Example : [Anchor](https://github.com/jesvijonathan/JOS-Animation-Library/blob/master/dev/index.html?plain=1#L35)
+### Anchor-to-Anchor Scroll Progress
-## Direction Based Animation
-
-1. Create an element that you want to animate & add the data-jos_scrollDirection attribute to it :
+Track scroll between two reference elements instead of the viewport:
```html
-
-
-```
+
Start
-This triggers the animation when the element is scrolled into view from the up to down direction. & you can do the same for down to up direction.
-
-This is particularly useful when you want to animate an element when it is **scrolled into view from a particular direction.**
+
+ 0% at #start-marker, 100% at #end-marker
+
-Example : [Direction Based Animation]()
+
End
+```
-## Start Visible
+### Debug Mode
-1. Create an element that you want to have a visible state when the page is loaded & add the data-jos_startVisible attribute to it :
+Enable `debugMode` to show an interactive overlay with draggable trigger lines:
-```html
-
-
+```js
+JOS.init({ debugMode: true });
```
-This sets the element to be visible when the page is loaded. you can add a delay to it by setting the value in ms :
+The overlay shows top/right/bottom/left trigger lines that can be dragged to adjust `rootMargin` in real-time. Anchor-to-anchor elements get a fixed progress indicator on the left edge.
-```html
-
-
-```
+To auto-hide the overlay while the hero/landing section is visible, add a sentinel element:
-This sets the element to be visible when the page is loaded after 3000ms or instantly if the value is 0 (or) true.
+```html
+
+```
+
+The overlay hides whenever this element is in the viewport and appears once scrolled past it.
+
+## Attributes Reference
+
+| Attribute | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `data-jos_animation` | string | `fade` | Animation type |
+| `data-jos_animationinverse` | string | — | Exit animation type |
+| `data-jos_duration` | number | `0.4` | Transition duration (seconds) |
+| `data-jos_delay` | number | `0` | Transition delay (seconds) |
+| `data-jos_timing_function` | string | `ease-in-out` | CSS timing function |
+| `data-jos_once` | bool/int | `false` | Animate once or N times |
+| `data-jos_mirror` | string | — | `"false"` for instant reverse |
+| `data-jos_rootmargin` | string | — | Override root margin per element |
+| `data-jos_rootmargin_top` | string | — | Override top margin |
+| `data-jos_rootmargin_bottom` | string | — | Override bottom margin |
+| `data-jos_scrollDirection` | string | — | `"up"`, `"down"`, `"left"`, `"right"`, or `"none"` |
+| `data-jos_startVisible` | bool/int | — | `true` or delay in ms |
+| `data-jos_anchor` | string | — | Anchor element ID (e.g. `"#myId"`) |
+| `data-jos_scroll` | string | — | Scroll progress callback function name |
+| `data-jos_invoke` | string | — | Enter callback function name |
+| `data-jos_invoke_out` | string | — | Exit callback function name |
+| `data-jos_rootmargin_top` | string | — | Override top margin |
+| `data-jos_rootmargin_right` | string | — | Override right margin |
+| `data-jos_rootmargin_bottom` | string | — | Override bottom margin |
+| `data-jos_rootmargin_left` | string | — | Override left margin |
+| `data-jos_threshold` | number | `0` | IntersectionObserver threshold |
+| `data-jos_scroll_start` | string | — | Anchor-to-anchor start element ID |
+| `data-jos_scroll_end` | string | — | Anchor-to-anchor end element ID |
+| `data-jos_scroll_axis` | string | `"y"` | Scroll axis: `"x"` or `"y"` |
+
+### Stagger Attributes
+
+| Attribute | Description |
+|-----------|-------------|
+| `data-jos_stagger` | Animation for children |
+| `data-jos_stagger_seq` | Delay between children (seconds) |
+| `data-jos_stagger_delay` | Base delay for all children |
+| `data-jos_stagger_duration` | Duration for all children |
+| `data-jos_stagger_once` | Once setting for children |
+| `data-jos_stagger_anchor` | Anchor for children (`"true"` = parent) |
+| `data-jos_stagger_mirror` | Mirror for children |
+| `data-jos_stagger_rootmargin` | Root margin for children |
+| `data-jos_stagger_scrolldirection` | Scroll direction for children |
+| `data-jos_stagger_startVisible` | Start visible for children |
+| `data-jos_stagger_scroll` | Scroll callback for children |
+| `data-jos_stagger_invoke` | Enter callback for children |
+| `data-jos_stagger_invoke_out` | Exit callback for children |
+| `data-jos_stagger_timingFunction` | Timing function for children |
+| `data-jos_staggerinverse` | Exit animation for children |
+
+## API Methods
+
+| Method | Description | Parameters |
+|--------|-------------|------------|
+| `JOS.init(options)` | Initialize with options | `options: {}` (see above) |
+| `JOS.start(state)` | Start animations | `0`: full restart, `-1`: resume |
+| `JOS.stop(state)` | Stop animations | `0`: stop (show), `1`: stop (hide), `-1`: pause |
+| `JOS.refresh()` | Re-scan DOM for new elements | — |
+| `JOS.destroy(state)` | Destroy instance | `0`: keep styles, `1`: remove styles |
+| `JOS.version()` | Print version info | — |
+
+## Framework Integration
-This feature is useful especially when you want an element which is in a fixed position, or is present in the landing page to be at initially in a visible state with no animation .
+
+React / Next.js
-Example : [Start Visible]()
+```jsx
+import { useEffect } from "react";
+import JOS from "jos-animation";
-## Create Custom Function
+function App() {
+ useEffect(() => {
+ JOS.init({ animation: "fade", duration: 0.4 });
+ return () => JOS.destroy();
+ }, []);
-1. Create a custom function by adding the following code to your script :
+ // Call JOS.refresh() after route changes or dynamic content
+ useEffect(() => { JOS.refresh(); });
-```js
-// Create a custom function
-function myCustomFunction() {
- // Do something
+ return
Hello
;
}
```
+
-2. Use your custom function by setting the data-jos_invoke attribute to myCustomFunction :
-
-```html
-
-```
-
-This triggers the myCustomFunction() function when the element is scrolled into view.
-
-You can use data-jos_invoke_out attribute to trigger the function when the element is scrolled out of view.
+
+Vue / Nuxt
-Example : [Custom Function]()
+```js
+// main.js
+import JOS from "jos-animation";
+import { watch, nextTick } from "vue";
+import { useRouter } from "vue-router";
-## Scroll Progress Callback
+const router = useRouter();
-1. Create an element that you want to animate & add the data-jos_scroll attribute to it :
+JOS.init();
-```html
-
- Scroll Trigger Element
-
+watch(() => router.currentRoute.value, () => {
+ nextTick(() => JOS.refresh());
+});
```
+
+
+
+Angular
-2. Create a custom function by adding the following code to your script :
+```ts
+import { Component, OnInit, AfterViewChecked } from "@angular/core";
+import JOS from "jos-animation";
-```js
-your_callbackFunction = (element) => {
- // windowScrollProgress : element scroll pixel
- console.log(element.id, element.jos.windowScrollProgress);
- // scrollProgress : 0-1
- element.style.opacity = element.jos.scrollProgress;
- // rootScrollProgress : +-0 to +-1
- element.style.innerHTML = element.jos.rootScrollProgress;
-};
+@Component({ selector: "app-root", templateUrl: "./app.component.html" })
+export class AppComponent implements OnInit, AfterViewChecked {
+ ngOnInit() { JOS.init(); }
+ ngAfterViewChecked() { JOS.refresh(); }
+}
```
+
-This triggers the your_callbackFunction() function when the element is scrolled. This way you can handle the scroll progress of the element.
-
-Example : [Custom Function](https://github.com/jesvijonathan/JOS-Animation-Library/releases/tag/v0.8.8)
+
+Svelte
-## Staggering Animation
+```svelte
+
-```html
-
-
-
-
-
-
-
-
-
-
-
-
+
Hello from Svelte
```
+
-The data-jos_stagger attribute along with jos class in parent element is Required/Must to enable staggering even if you are using other attributes.
-
-- data-jos_stagger=true would auto asign id for parent element & use it as a anchor for child elements.
-- data-jos_stagger=#id would use the given id as a anchor for child elements.
-- not using data-jos_stagger_anchor make the element independent of the parent element.
-
-data-jos_stagger_seq is used to set the delay between each element in the sequence (to trigger one after other) whereas data-jos_stagger_delay total delay for each element as a whole.
-
-Example : [Staggering Animation]()
-
-## JOS Attributes
-
-| Attribute | Type | Default | Description | Values |
-| -------------------------------- | ------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| data-jos_animation | string | fade | Set the animation type for the element. | `static`, `no-transition`, `fade`, `fade-up`, `fade-down`, `fade-left`, `fade-right`, `fade-up-right`, `fade-up-left`, `fade-down-right`, `fade-down-left`, `flip`, `flip-up`, `flip-down`, `flip-left`, `flip-right`, `slide`, `slide-up`, `slide-down`, `slide-left`, `slide-right`, `slide-up-right`, `slide-up-left`, `slide-down-right`, `slide-down-left`, `zoom`, `zoom-in`, `zoom-in-up`, `zoom-in-down`, `zoom-in-left`, `zoom-in-right`, `zoom-out`, `zoom-out-up`, `zoom-out-down`, `zoom-out-left`, `zoom-out-right`, `grow`, `grow-right`, `grow-left`, `grow-up`, `grow-down`, `shrink`, `shrink-right`, `shrink-left`, `shrink-up`, `shrink-down`, `rotate`, `rotate-right`, `rotate-left`, `spin`, `spin-right`, `spin-left`, `revolve`, `revolve-right`, `revolve-left`, `stretch`, `stretch-vertical`, `stretch-horizontal`, `skew`, `skew-left`, `skew-right`, `skew-down`, `skew-up`, `slant`, `slant-right`, `slant-left`, `blur`, `sepia`, `invert`, `backdrop`, `brightness`, `saturate`, `hue-rotate`, `bar`, `bar_horizontal`, `grey`, `slide-play`, `slide-horizontal-play`, `slide-vertical-play`, `zoom-in-play`, `pulse-play`, `zoom-play`, `zoom-out-play`, `pulse-out-play`, `flip-play`, `rotate-play`, `spin-play`, `revolve-play`, `grow-play`, `shrink-play`, `stretch-play`, `stretch-vertical-play`, `fade-play`, `fade-horizontal-play`, `fade-vertical-play`, `blink-play`, `my-custom-animation` |
-| data-jos_animationInverse | string | static | Set the Inverse animation type for the element. | `static`, `no-transition`, `fade`, `fade-up`, `fade-down`, `fade-left`, `fade-right`, `fade-up-right`, `fade-up-left`, `fade-down-right`, `fade-down-left`, `flip`, `flip-up`, `flip-down`, `flip-left`, `flip-right`, `slide`, `slide-up`, `slide-down`, `slide-left`, `slide-right`, `slide-up-right`, `slide-up-left`, `slide-down-right`, `slide-down-left`, `zoom`, `zoom-in`, `zoom-in-up`, `zoom-in-down`, `zoom-in-left`, `zoom-in-right`, `zoom-out`, `zoom-out-up`, `zoom-out-down`, `zoom-out-left`, `zoom-out-right`, `grow`, `grow-right`, `grow-left`, `grow-up`, `grow-down`, `shrink`, `shrink-right`, `shrink-left`, `shrink-up`, `shrink-down`, `rotate`, `rotate-right`, `rotate-left`, `spin`, `spin-right`, `spin-left`, `revolve`, `revolve-right`, `revolve-left`, `stretch`, `stretch-vertical`, `stretch-horizontal`, `skew`, `skew-left`, `skew-right`, `skew-down`, `skew-up`, `slant`, `slant-right`, `slant-left`, `blur`, `sepia`, `invert`, `backdrop`, `brightness`, `saturate`, `hue-rotate`, `bar`, `bar_horizontal`, `grey`, `slide-play`, `slide-horizontal-play`, `slide-vertical-play`, `zoom-in-play`, `pulse-play`, `zoom-play`, `zoom-out-play`, `pulse-out-play`, `flip-play`, `rotate-play`, `spin-play`, `revolve-play`, `grow-play`, `shrink-play`, `stretch-play`, `stretch-vertical-play`, `fade-play`, `fade-horizontal-play`, `fade-vertical-play`, `blink-play`, `my-custom-animation` |
-| data-jos_once | boolean | false | Set whether the element should animate only once. | `true`, `false` |
-| data-jos_delay | int | 0 | Set the delay for the animation to start. | `(float: 0-1)` & `(int: 0, 1, 2, 3, 4, 5)` |
-| data-jos_duration | float | 0.4 | Set the duration for the animation playback. | `(float: 0-1)` & `(int: 0, 1, 2, 3, 4, 5)` |
-| data-jos_timing-function | string | ease | Set the timing function for the animation playback. | `ease`, `ease-in`, `ease-out`, `ease-in-out`, `linear`, `step-start`, `step-end`, `steps(1, start)`, `steps(1, end)`, `cubic-bezier(0.1, 0.7, 1.0, 0.1)`, `my-custom-timingFunc` |
-| data-jos_invoke | string | null | Set the function to be invoked when the element is scrolled into view. | `function`, `myCustomFunction` |
-| data-jos_invoke_out | string | null | Set the function to be invoked when the element is scrolled out of view. | `function`, `myCustomFunction` |
-| data-once | boolean & int | false | Set whether the element should animate only | `(boolean: true, false)` & `(int: 0-infinity)` |
-| data-jos_rootMargin | string | 0% -10% 0% -50% | Sets the margin for an element to animate on in a viewport when scrolled. | `(string: "right% top% left% bottom%")` |
-| data-jos_rootMargin_top | string | 0% | Sets the margin for an element to animate on the top of a viewport when scrolled. | `(string: "top%")` |
-| data-jos_rootMargin_bottom | string | 0% | Sets the margin for an element to animate on the bottom of a viewport when scrolled. | `(string: "bottom%")` |
-| data-jos_scrollDirection | string | down | Sets the direction for an element to animate on ina viewport when scrolled. | `(string: "up", "down", "none")` |
-| data-jos_startVisible | boolean & int | false | Set whether the element should start at the final state when the page is loaded (also works with delay). | `(boolean: true, false)` & `(int: 0-10000 ms)` |
-| data-jos_anchor | string | null | Sets the anchor element for an element to animate on in a viewport when scrolled. | `(string: "#elementID")` |
-| data-jos_scroll | string | null | Sets the callback function for an element to animate on in a viewport when scrolled. | `function`, `your_callbackFunction` |
-| data-jos_stagger | string | fade | Sets the stagger animation for an child stagger element to animate on in a viewport when scrolled. | `string`, `fade` |
-| data-jos_staggerinverse | string | static | Sets the stagger inverse animation for an child stagger element to animate on in a viewport when scrolled (play animation). | `string`, `fade-play` |
-| data-jos_stagger_anchor | string | null | Sets the anchor element for an child stagger element to animate on in a viewport when scrolled. | `string`, `#elementID` |
-| data-jos_stagger_seq | float | null | Sets the sequence delay for an child stagger element to animate on in a viewport when scrolled. | `float`, `0-1` |
-| data-jos_stagger_delay | float | null | Sets the delay for an child stagger element to animate on in a viewport when scrolled. | `float`, `0-1` |
-| data-jos_stagger_duration | float | null | Sets the duration for an element to child stagger animate on in a viewport when scrolled. | `float`, `0-1` |
-| data-jos_stagger_timing-function | string | null | Sets the timing function for an child stagger element to animate on in a viewport when scrolled. | `string`, `ease` |
-| data-jos_stagger_mirror | boolean | null | Sets the mirror animation for an child stagger element to animate on in a viewport when scrolled. | `boolean`, `true`, `false` |
-| data-jos_stagger_rootMargin | string | null | Sets the margin for an child stagger element to animate on in a viewport when scrolled. | `(string: "right% top% left% bottom%")` |
-| data-jos_stagger_scrollDirection | string | null | Sets the direction for an child stagger element to animate on ina viewport when scrolled. | `(string: "up", "down", "none")` |
-| data-jos_stagger_startVisible | boolean & int | null | Set whether the child stagger element should start at the final state when the page is loaded (also works with delay). | `(boolean: true, false)` & `(int: 0-10000 ms)` |
-| data-jos_stagger_once | boolean | null | Set whether the element should animate only once or n count. | `true`, `false`, `int` |
-| data-jos_stagger_scroll | string | null | Sets the callback function for an child stagger to animate on in a viewport when scrolled. | `function`, `your_callbackFunction` |
-| data-jos_stagger_invoke | string | null | Set the function to be invoked when the child stagger element is scrolled into view. | `function`, `myCustomFunction` |
-| data-jos_stagger_invoke_out | string | null | Set the function to be invoked when the child stagger element is scrolled out of view. | `function`, `myCustomFunction` |
-
-
-
-## JOS Methods
-
-| Method | Description | Parameters |
-| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------- |
-| init() | Initialize/Reset JOS | options = `{}` (refer [JOS.Init(options)]() ) |
-| refresh() | Refresh JOS | none |
-| stop() | Stop/Pause JOS | state = (`0` - Stop at final state, `1` - Stop at initial state, `-1` - Pause at current state) |
-| start() | Start/Resume JOS Service | state = (`0` - Normal/Full start, `-1` - Resume from current state) |
-| destroy() | Destroy JOS Instance | state = (`0` - Destroy JOS instance excluding stylesheet, `1` - Full Destroy along with JOS-stylesheet) |
-
-## Bundling JOS
-
-Once you are done and have finished developing a version of JOS, you can bundle it using the following command from project root :
+## Development
```bash
-# JOS-Animation-Library
-# |-dev
-# |-dist
-# |-bundler
-# |-config
-# |-export <-- Check this folder for the output files
-# |-jos.css
-# |-jos.js
-# |...
-# |-original
-# |-bundle.sh <-- Run this file to bundle JOS
-# ...
-```
+# Clone
+git clone https://github.com/jesvijonathan/JOS-Animation-Library.git
+cd JOS-Animation-Library
-```bash
-# Change/Move to bundler directory
-cd ./bundler
+# Install
+npm install
-# Bundle the project
-sh bundle.sh
+# Build
+npm run build
-# View the output files
-ls ./export
+# Dev (watch mode)
+npm run dev
```
-## Bugs and Issues
+### Project Structure
-Moved to [issues](https://github.com/jesvijonathan/JOS-Animation-Library/issues)
+```
+src/
+├── index.js # Entry point (JS only)
+├── index.full.js # Entry point (JS + CSS embedded)
+├── core/
+│ ├── JOS.js # Main JOS class
+│ ├── ElementManager.js # Element initialization & stagger
+│ ├── ObserverManager.js# IntersectionObserver management
+│ ├── ScrollTracker.js # Scroll progress tracking (rAF)
+│ ├── StyleManager.js # Dynamic stylesheet injection
+│ ├── DebugOverlay.js # Debug trigger line overlay
+│ └── defaults.js # Default configuration
+├── utils/
+│ └── dom.js # DOM helpers
+└── animations/
+ └── jos.css # All animation definitions
+```
-## Contributing
+### Build Outputs
-- Fork it from [main branch](https://github.com/jesvijonathan/JOS-Animation-Library)
-- Add your useful feature or fix a bug
-- Commit your changes
-- Create a pull request
+| File | Format | Use Case |
+|------|--------|----------|
+| `dist/jos.js` | UMD | `
+
+
+