├── .DS_Store
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── babel.librc
├── components
├── DemoContainer.tsx
└── DemoControls.tsx
├── dist
└── index.js
├── logo.png
├── murphyjs-2.4.4.tgz
├── murphyjs-2.5.0.tgz
├── murphyjs-2.5.1.tgz
├── next-env.d.ts
├── next.config.js
├── package-lock.json
├── package.json
├── pages
├── _app.tsx
├── _meta.json
├── api-reference.mdx
├── examples.mdx
├── getting-started.mdx
└── index.mdx
├── postcss.config.js
├── src
├── .DS_Store
└── core
│ ├── config.js
│ └── index.js
├── static
└── favicon.ico
├── styles
└── globals.css
├── tailwind.config.js
├── theme.config.tsx
├── tsconfig.json
├── types
└── murphy.d.ts
├── vercel.json
├── webpack.config.js
└── yarn.lock
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cesarolvr/murphyjs/e60256f01938cc0e686a56cf9ab69beb1c91a736/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 | /.pnp
4 | .pnp.js
5 |
6 | # testing
7 | /coverage
8 |
9 | # next.js
10 | /.next/
11 | /out/
12 |
13 | # production
14 | /build
15 | /dist
16 |
17 | # cache
18 | .cache/
19 |
20 | # misc
21 | .DS_Store
22 | *.pem
23 |
24 | # debug
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
29 | # local env files
30 | .env*.local
31 |
32 | # vercel
33 | .vercel
34 |
35 | # typescript
36 | *.tsbuildinfo
37 | next-env.d.ts
38 |
39 | # IDE
40 | .idea
41 | .vscode
42 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Development files
2 | .git
3 | .github
4 | .gitignore
5 | .editorconfig
6 | .prettierrc
7 | .eslintrc
8 | .eslintignore
9 | .prettierignore
10 | .vscode
11 | node_modules
12 | coverage
13 | .DS_Store
14 |
15 | # Source files
16 | src
17 | tests
18 | docs
19 | examples
20 | *.test.js
21 | *.spec.js
22 |
23 | # Build files
24 | dist/*.map
25 | *.map
26 |
27 | # Documentation
28 | *.md
29 | !README.md
30 | LICENSE
31 |
32 | # Assets
33 | logo.png
34 | *.png
35 | *.jpg
36 | *.jpeg
37 | *.gif
38 | *.svg
39 | *.ico
40 |
41 | # Config files
42 | *.config.js
43 | *.config.json
44 | tsconfig.json
45 | babel.config.js
46 | jest.config.js
47 | webpack.config.js
48 | rollup.config.js
49 |
50 | # Misc
51 | .env
52 | .env.*
53 | *.log
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Cesar Oliveira
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MurphyJS
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | A lightweight JavaScript library for creating smooth animations with a simple API.
15 |
16 |
17 |
18 | ## Features
19 |
20 | - 🚀 Lightweight and fast (only 3.7KB)
21 | - 🎨 Simple and intuitive API
22 | - 🌈 Beautiful animations
23 | - 📱 Mobile-friendly
24 | - 🎯 No dependencies
25 | - 🎮 Total control of IntersectionObserver parameters
26 | - 🎁 Some animations implemented by default
27 | - 🏝 Plug and play solution to landing pages and simple projects
28 | - ❎ Native fallback to not supported browsers
29 | - 🛎️ Built-in event system for animation lifecycle (in, out, finish, cancel, reset, cleanup)
30 | - 🔄 Mirror animations for smooth scroll transitions
31 | - 📏 Viewport position control with predefined aliases
32 | - 📱 Mobile optimization with device detection
33 |
34 | ## Installation
35 |
36 | Using npm:
37 | ```bash
38 | npm install murphyjs
39 | ```
40 |
41 | Using yarn:
42 | ```bash
43 | yarn add murphyjs
44 | ```
45 |
46 | Using CDN:
47 | ```html
48 |
49 |
55 | ```
56 |
57 | For detailed documentation and examples, visit our [documentation site](https://www.murphyjs.org/).
58 |
59 | ## Quick Start
60 |
61 | ```javascript
62 | import { Murphy } from 'murphyjs';
63 |
64 | // Create a new instance
65 | const murphy = new Murphy();
66 |
67 | // Animate elements
68 | murphy.animate('.box', {
69 | opacity: [0, 1],
70 | y: [20, 0],
71 | duration: 1000
72 | });
73 | ```
74 |
75 | ## Usage
76 |
77 | ### 1. Tag your HTML
78 |
79 | In your markup, decorate your element with attribute `data-murphy`:
80 |
81 | ```html
82 |
Any content here
83 | ```
84 |
85 | The default effect of murphy is `bottom-to-top`, but you can also use:
86 | - `top-to-bottom`
87 | - `left-to-right`
88 | - `right-to-left`
89 |
90 | ### 2. Reset your CSS
91 |
92 | In your CSS, reset all the tagged elements:
93 |
94 | ```css
95 | *[data-murphy] {
96 | opacity: 0;
97 | }
98 | ```
99 |
100 | ### 3. Start murphy
101 |
102 | In JavaScript, import and run `play` when your page is completely loaded:
103 |
104 | ```javascript
105 | import murphy from "murphyjs";
106 | murphy.play();
107 | ```
108 |
109 | Or if you're using the script tag:
110 |
111 | ```html
112 |
113 |
116 | ```
117 |
118 | ## Configuration
119 |
120 | You can configure the animation of each decorated element individually using these attributes:
121 |
122 | | Attribute | Type | Default | Description |
123 | |-----------|------|---------|-------------|
124 | | data-murphy | String | 'bottom-to-top' | Animation direction |
125 | | data-murphy-appearance-distance | Int | 50px | Distance from viewport edge to trigger animation |
126 | | data-murphy-element-distance | Int | 30px | Distance the element moves during animation |
127 | | data-murphy-ease | String | 'ease' | Animation easing function (can be a cubic-bezier) |
128 | | data-murphy-animation-delay | Int | 300ms | Delay before animation starts |
129 | | data-murphy-element-threshold | Float | 1.0 | How much of the element needs to be visible to trigger (0-1) |
130 | | data-murphy-animation-duration | Int | 300ms | Duration of the animation |
131 | | data-murphy-root-margin | String | '0px 0px -50px 0px' | Custom root margin for the Intersection Observer. Use this to control when animations trigger based on viewport position. You can use predefined aliases: 'top', 'middle', 'bottom', 'quarter', 'three-quarters' |
132 | | data-murphy-group | String | undefined | Group identifier for controlling animations for specific groups of elements |
133 | | data-murphy-mirror | Boolean | false | Whether to play the animation in reverse when the element leaves the viewport |
134 | | data-murphy-disable-mobile | Boolean | false | Whether to disable animations on mobile devices (screen width <= 768px or mobile user agent) |
135 |
136 | ## Advanced Features
137 |
138 | ### Mirror Animations
139 |
140 | Enable mirror animations to create smooth transitions when elements leave the viewport:
141 |
142 | ```html
143 |
144 | This element will animate in when scrolling down and animate out when scrolling up
145 |
146 | ```
147 |
148 | ### Viewport Position Control
149 |
150 | Control when animations trigger based on the element's position in the viewport using the `data-murphy-root-margin` attribute. For convenience, we provide several aliases:
151 |
152 | ```html
153 |
154 |
155 | This will animate when it reaches the middle of the viewport
156 |
157 |
158 |
159 |
160 | This will animate when it reaches the bottom of the viewport
161 |
162 |
163 |
164 |
165 | This will animate when it's 25% from the bottom of the viewport
166 |
167 |
168 |
169 |
170 | This will animate when it's 75% from the bottom of the viewport
171 |
172 | ```
173 |
174 | You can also use raw CSS margin values if you need more precise control:
175 |
176 | ```html
177 |
178 | This will animate when it reaches the middle of the viewport
179 |
180 | ```
181 |
182 | The root margin follows the CSS margin syntax: `top right bottom left`. Negative values create an inset margin, which means the animation will trigger when the element reaches that point in the viewport.
183 |
184 | ### Available Viewport Position Aliases
185 |
186 | | Alias | Description | Raw Value |
187 | |-------|-------------|-----------|
188 | | `top` | Triggers at top of viewport | `'0px 0px 0px 0px'` |
189 | | `middle` | Triggers at middle of viewport | `'0px 0px -50% 0px'` |
190 | | `bottom` | Triggers at bottom of viewport | `'0px 0px 0px 0px'` |
191 | | `quarter` | Triggers at 25% from bottom | `'0px 0px -25% 0px'` |
192 | | `three-quarters` | Triggers at 75% from bottom | `'0px 0px -75% 0px'` |
193 |
194 | ## Group-based Animations
195 |
196 | You can group elements using the `data-murphy-group` attribute. This allows you to control animations for specific groups of elements. For example, you can play or reset animations for only a subset of elements by specifying a group name:
197 |
198 | ```html
199 |
Group 1
200 |
Group 1
201 |
Group 2
202 |
Group 2
203 | ```
204 |
205 | You can then control animations for a specific group using the API:
206 |
207 | ```js
208 | // Play animations for group1 only
209 | murphy.play('group1');
210 |
211 | // Reset animations for group2 only
212 | murphy.reset('group2');
213 | ```
214 |
215 | ## API
216 |
217 | ### Global Methods
218 |
219 | | Method | Description |
220 | |--------|-------------|
221 | | `play(group?: string)` | Start monitoring elements in DOM tagged with `data-murphy` attribute. Optionally specify a group to animate only elements in that group. |
222 | | `cancel()` | Cancel all animations and reset elements to their final state. |
223 | | `reset(group?: string)` | Reset all animations to their initial state. Optionally specify a group to reset only elements in that group. |
224 | | `cleanup()` | Disconnect all Intersection Observers and clean up resources. |
225 |
226 | ### Murphy Class
227 |
228 | The `Murphy` class provides a programmatic way to create animations:
229 |
230 | ```javascript
231 | import { Murphy } from 'murphyjs';
232 |
233 | // Create a new instance
234 | const murphy = new Murphy();
235 |
236 | // Animate elements
237 | murphy.animate('.box', {
238 | opacity: [0, 1],
239 | y: [20, 0],
240 | duration: 1000
241 | });
242 | ```
243 |
244 | #### `animate(selector, options)`
245 |
246 | Animates elements matching the selector with the specified options.
247 |
248 | ##### Parameters
249 |
250 | | Parameter | Type | Description |
251 | |-----------|------|-------------|
252 | | `selector` | String | CSS selector for target elements |
253 | | `options` | Object | Animation configuration |
254 |
255 | ##### Options
256 |
257 | | Option | Type | Default | Description |
258 | |--------|------|---------|-------------|
259 | | `opacity` | Array | [0, 1] | Start and end opacity values |
260 | | `x` | Array | [0, 0] | Start and end x translation in pixels |
261 | | `y` | Array | [0, 0] | Start and end y translation in pixels |
262 | | `duration` | Number | 1000 | Animation duration in milliseconds |
263 | | `delay` | Number | 0 | Delay before animation starts in milliseconds |
264 | | `ease` | String | 'ease' | Easing function name |
265 |
266 | ### Events
267 |
268 | MurphyJS provides a set of events that you can listen to for better control and integration:
269 |
270 | | Event | Description |
271 | |-------|-------------|
272 | | `murphy:in` | Fired when an element enters the viewport |
273 | | `murphy:out` | Fired when an element leaves the viewport |
274 | | `murphy:finish` | Fired when an animation completes |
275 | | `murphy:cancel` | Fired when an animation is cancelled |
276 | | `murphy:reset` | Fired when an element is reset |
277 | | `murphy:cleanup` | Fired when observers are cleaned up |
278 |
279 | #### Event Example
280 |
281 | ```javascript
282 | document.addEventListener('murphy:in', (event) => {
283 | const { element } = event.detail;
284 | console.log('Element entered viewport:', element);
285 | });
286 |
287 | document.addEventListener('murphy:finish', (event) => {
288 | const { element } = event.detail;
289 | console.log('Animation finished:', element);
290 | });
291 | ```
292 |
293 | ### Available Animations
294 |
295 | MurphyJS comes with several built-in animations that you can use with the `data-murphy` attribute:
296 |
297 | #### Basic Animations
298 | - `bottom-to-top`
299 | - `top-to-bottom`
300 | - `left-to-right`
301 | - `right-to-left`
302 |
303 | #### Flip Animations
304 | - `flip-left`
305 | - `flip-right`
306 | - `flip-up`
307 | - `flip-down`
308 |
309 | #### Zoom Animations
310 | - `zoom-in`
311 | - `zoom-out`
312 |
313 | #### Fade Animations
314 | - `fade`
315 | - `fade-up`
316 | - `fade-down`
317 | - `fade-left`
318 | - `fade-right`
319 |
320 | #### Rotate Animations
321 | - `rotate-left`
322 | - `rotate-right`
323 |
324 | #### Scale Animations
325 | - `scale-up`
326 | - `scale-down`
327 |
328 | #### Slide Animations
329 | - `slide-up`
330 | - `slide-down`
331 | - `slide-left`
332 | - `slide-right`
333 |
334 | #### Bounce Animations
335 | - `bounce-in`
336 | - `bounce-out`
--------------------------------------------------------------------------------
/babel.librc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["@babel/preset-env", {
4 | "targets": {
5 | "node": "current"
6 | }
7 | }]
8 | ]
9 | }
--------------------------------------------------------------------------------
/components/DemoContainer.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 |
3 | interface DemoContainerProps {
4 | children: React.ReactNode
5 | className?: string
6 | }
7 |
8 | export function DemoContainer({ children, className = '' }: DemoContainerProps) {
9 | useEffect(() => {
10 | if (typeof window !== 'undefined' && window.murphy) {
11 | window.murphy.play()
12 | }
13 | }, [])
14 |
15 | return (
16 |
140 | ```
141 |
142 | ## Group-based Animations
143 |
144 | You can group elements using the `data-murphy-group` attribute. This allows you to control animations for specific groups of elements.
145 |
146 | ```html copy
147 |
Group 1
148 |
Group 1
149 |
Group 2
150 |
Group 2
151 | ```
152 |
153 | ## Configuration Options
154 |
155 | You can configure the animation of each decorated element individually using these attributes:
156 |
157 | | Attribute | Value type | Default value | What controls |
158 | |-----------|------------|---------------|---------------|
159 | | data-murphy | String | 'bottom-to-top' | Animation direction |
160 | | data-murphy-appearance-distance | Int | 50 *(px)* | Distance from viewport edge to trigger animation |
161 | | data-murphy-element-distance | Int | 30 *(px)* | Distance the element moves during animation |
162 | | data-murphy-ease | String | 'ease' | Define a função de easing da animação. Opções: 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'cubic-in', 'cubic-out', 'cubic-in-out', 'quad-in', 'quad-out', 'quad-in-out' |
163 | | data-murphy-animation-delay | Int | 300 *(ms)* | Delay before animation starts |
164 | | data-murphy-element-threshold | Float | 1.0 | How much of the element needs to be visible to trigger (0-1) |
165 | | data-murphy-animation-duration | Int | 300 *(ms)* | Duration of the animation |
166 | | data-murphy-root-margin | String | '0px 0px -50px 0px' | Custom root margin for the Intersection Observer. Use this to control when animations trigger based on viewport position. You can use predefined aliases: 'top', 'middle', 'bottom', 'quarter', 'three-quarters' |
167 | | data-murphy-mirror | Boolean | false | Whether to play the animation in reverse when the element leaves the viewport |
168 |
169 | ### Viewport Position Control
170 |
171 | You can control when animations trigger based on the element's position in the viewport using the `data-murphy-root-margin` attribute. For convenience, we provide several aliases:
172 |
173 | ```html
174 |
175 |
176 | This will animate when it reaches the middle of the viewport
177 |
178 |
179 |
180 |
181 | This will animate when it reaches the bottom of the viewport
182 |
183 |
184 |
185 |
186 | This will animate when it's 25% from the bottom of the viewport
187 |
188 |
189 |
190 |
191 | This will animate when it's 75% from the bottom of the viewport
192 |
193 | ```
194 |
195 | You can also use raw CSS margin values if you need more precise control:
196 |
197 | ```html
198 |
199 | This will animate when it reaches the middle of the viewport
200 |
201 | ```
202 |
203 | The root margin follows the CSS margin syntax: `top right bottom left`. Negative values create an inset margin, which means the animation will trigger when the element reaches that point in the viewport.
204 |
205 | ### Methods
206 |
207 | | Method | What happens |
208 | |--------|--------------|
209 | | play | Start monitoring elements in DOM tagged with `data-murphy` |
210 | | reset | Resets all data-murphy elements to their initial state |
211 | | cleanup | Disconnects all Intersection Observers and cleans up resources |
212 |
213 | ## Advanced: Mirror Animations
214 |
215 | You can enable mirror animations to create smooth transitions when elements leave the viewport:
216 |
217 | ```html copy
218 |
219 | This element will animate in when scrolling down and animate out when scrolling up
220 |
232 | 👋 Just a quick tip: While these animations are triggered by scrolling, they also work great for elements that are already visible on the page. Think of it like having those cool entrance animations from React Transition Group, but without the extra setup! Perfect for spicing up your landing pages and first-time visits. Give it a try! ✨
233 |
234 |
235 | ## Advanced: Listening to Animation Events
236 |
237 | murphy.js emits custom events for each animation lifecycle. You can listen to these events for advanced integrations:
238 |
239 | | Event | Description |
240 | |-----------------|---------------------------------------------|
241 | | murphy:in | Fired when an element enters the viewport |
242 | | murphy:out | Fired when an element leaves the viewport |
243 | | murphy:finish | Fired when an animation completes |
244 | | murphy:cancel | Fired when an animation is cancelled |
245 | | murphy:reset | Fired when an element is reset |
246 | | murphy:cleanup | Fired when observers are cleaned up |
247 |
248 | **Example:**
249 |
250 | ```javascript copy
251 | document.addEventListener('murphy:in', ({ detail }) => {
252 | console.log('Element entered viewport:', detail.element);
253 | });
254 | document.addEventListener('murphy:finish', ({ detail }) => {
255 | console.log('Animation finished:', detail.element);
256 | });
257 | ```
--------------------------------------------------------------------------------
/pages/index.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Murphy.js'
3 | ---
4 |
5 | #
murphy.js
6 |
7 | A JavaScript vanilla library to scroll based reveal animations.
8 | The murphy.js is a lightweight JavaScript animation library with a simple implementation way. All this works by joining of data-attributes, Web animate API and Intersection Observer API. Now with a built-in event system for advanced control!
9 |
10 | ## Why use
11 |
12 | - ⚡️ Lightweight library (only 3.7KB)
13 | - 🍎 Easy and fast implementation
14 | - 🎮 Total control of IntersectionObserver parameters
15 | - 🎨 Full customization of time, duration, ease, delay and distance of each element individually
16 | - 🎁 Some animations implemented by default
17 | - 🏝 Plug and play solution to landing pages and simple projects
18 | - ❎ Native fallback to not supported browsers
19 | - 🛎️ Built-in event system for animation lifecycle (in, out, finish, cancel, reset, cleanup)
20 |
21 | ## Quick Start
22 |
23 | ### Installation
24 |
25 | ```bash copy copy
26 | npm install murphyjs
27 | ```
28 |
29 | Or via CDN:
30 | ```html copy copy
31 |
32 |
38 | ```
39 |
40 | ### Basic Usage
41 |
42 | Just do three steps:
43 |
44 | 1. Tag your HTML with `data-murphy`:
45 | ```html copy copy
46 |