@andresclua/perlindom 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/package.json +5 -5
- package/readme.md +261 -229
- package/src/index.html +33 -7
- package/src/js/PerlinDom.js +14 -8
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.0.3] - 2025-01-07
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **Positioning Issue**: Fixed problem where inline styles (`left`, `top`) were conflicting with transform animations, causing double positioning
|
|
12
|
+
- **Transform Initialization**: PerlinDOM now properly initializes transform property if it doesn't exist
|
|
13
|
+
|
|
14
|
+
### Improved
|
|
15
|
+
- **Automatic Position Detection**: PerlinDOM now automatically detects and works from the element's current position (CSS or inline styles)
|
|
16
|
+
- **Cleaner API**: No need for specific inline styles - elements animate from wherever they are positioned
|
|
17
|
+
- **Better Performance**: Improved transform handling for smoother animations
|
|
18
|
+
|
|
19
|
+
### Documentation
|
|
20
|
+
- **README**: Completely restructured with better organization and clearer examples
|
|
21
|
+
- **Examples**: Cleaned up HTML examples, moved positioning from inline styles to CSS classes
|
|
22
|
+
- **Best Practices**: Added section explaining when to use CSS vs inline styles
|
|
23
|
+
- **Troubleshooting**: New section with common issues and solutions
|
|
24
|
+
|
|
25
|
+
### Code Quality
|
|
26
|
+
- **Examples Cleanup**: Removed unnecessary inline styles from demo particles
|
|
27
|
+
- **CSS Organization**: Better separation of positioning and styling concerns
|
|
28
|
+
|
|
29
|
+
## [0.0.2] - 2024-12-XX
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- **Percentage Support**: Added support for percentage-based movement values (`'-10%'`, `'10%'`)
|
|
33
|
+
- **Responsive Animations**: Animations now adapt to container size changes
|
|
34
|
+
- **Mixed Values**: Support for mixing pixel and percentage values in same animation
|
|
35
|
+
- **Window Resize Handling**: Automatic recalculation when using percentage values
|
|
36
|
+
|
|
37
|
+
### Features
|
|
38
|
+
- **2D Perlin Noise**: Enhanced noise generation for more natural movement patterns
|
|
39
|
+
- **Smooth Transitions**: Improved lerp-based pause/play functionality
|
|
40
|
+
- **Performance Optimization**: Better requestAnimationFrame usage
|
|
41
|
+
|
|
42
|
+
## [0.0.1] - 2024-11-XX
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- **Initial Release**: Basic PerlinDOM functionality
|
|
46
|
+
- **Core Animation**: Smooth organic animations using Perlin noise
|
|
47
|
+
- **Basic API**: Constructor with element, x/y ranges, speed, and seed options
|
|
48
|
+
- **Control Methods**: `play()`, `pause()`, `destroy()`, and `init()` methods
|
|
49
|
+
- **Transform-based Movement**: CSS transform animations for better performance
|
|
50
|
+
|
|
51
|
+
### Features
|
|
52
|
+
- **Perlin Noise Generation**: Custom implementation with seeded random generation
|
|
53
|
+
- **Configurable Ranges**: Separate X and Y movement ranges
|
|
54
|
+
- **Speed Control**: Adjustable animation speed
|
|
55
|
+
- **Seed Support**: Reproducible animations with custom seeds
|
|
56
|
+
- **Element Positioning**: Automatic relative positioning for static elements
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Legend
|
|
61
|
+
|
|
62
|
+
- **Added**: New features
|
|
63
|
+
- **Changed**: Changes in existing functionality
|
|
64
|
+
- **Deprecated**: Soon-to-be removed features
|
|
65
|
+
- **Removed**: Removed features
|
|
66
|
+
- **Fixed**: Bug fixes
|
|
67
|
+
- **Security**: Vulnerability fixes
|
|
68
|
+
- **Improved**: Performance or usability improvements
|
|
69
|
+
- **Documentation**: Documentation changes
|
|
70
|
+
- **Code Quality**: Code organization and cleanup
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andresclua/perlindom",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"description": "A lightweight JavaScript library for creating smooth, organic animations for DOM elements using Perlin noise",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"main": "./dist/
|
|
8
|
-
"module": "./dist/
|
|
7
|
+
"main": "./dist/PerlinDOM.umd.js",
|
|
8
|
+
"module": "./dist/PerlinDOM.es.js",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"import": "./dist/
|
|
12
|
-
"require": "./dist/
|
|
11
|
+
"import": "./dist/PerlinDOM.es.js",
|
|
12
|
+
"require": "./dist/PerlinDOM.umd.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
package/readme.md
CHANGED
|
@@ -1,319 +1,351 @@
|
|
|
1
1
|
# PerlinDOM
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
3
|
+
[](https://badge.fury.io/js/@andresclua%2Fperlindom)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
|
|
6
|
+
|
|
7
|
+
A lightweight JavaScript library for creating smooth, organic animations on DOM elements using Perlin noise. Create natural, fluid movements that bring your web interfaces to life.
|
|
8
|
+
|
|
9
|
+
## 📋 Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Features](#-features)
|
|
12
|
+
- [Installation](#-installation)
|
|
13
|
+
- [Quick Start](#-quick-start)
|
|
14
|
+
- [Configuration](#-configuration)
|
|
15
|
+
- [Examples](#-examples)
|
|
16
|
+
- [Best Practices](#-best-practices)
|
|
17
|
+
- [API Reference](#-api-reference)
|
|
18
|
+
- [Troubleshooting](#-troubleshooting)
|
|
19
|
+
- [Browser Compatibility](#-browser-compatibility)
|
|
20
|
+
- [Changelog](#-changelog)
|
|
21
|
+
- [License](#-license)
|
|
22
|
+
|
|
23
|
+
## ✨ Features
|
|
24
|
+
|
|
25
|
+
- **🌊 Organic Animations**: Natural movements using Perlin noise that avoid mechanical rigidity
|
|
26
|
+
- **📱 Responsive Design**: Support for percentage-based values that adapt to container size
|
|
27
|
+
- **🎯 Smart Positioning**: Automatically works from element's current position (CSS or inline styles)
|
|
28
|
+
- **⚡ High Performance**: Uses `transform` and `requestAnimationFrame` for smooth 60fps animations
|
|
29
|
+
- **🎛️ Full Control**: Play, pause, and destroy animations with smooth transitions
|
|
30
|
+
- **📦 Lightweight**: Minimal footprint with zero dependencies
|
|
31
|
+
- **🔧 Easy Integration**: Simple API that works with any DOM element
|
|
32
|
+
- **🎨 Flexible**: Mix pixel and percentage values, animate on single or both axes
|
|
33
|
+
|
|
34
|
+
## 📦 Installation
|
|
28
35
|
|
|
29
36
|
```bash
|
|
30
|
-
npm install @andresclua/
|
|
37
|
+
npm install @andresclua/perlindom
|
|
31
38
|
```
|
|
32
39
|
|
|
40
|
+
Or include directly in your HTML:
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<script type="module">
|
|
44
|
+
import PerlinDOM from 'https://unpkg.com/@andresclua/perlindom/dist/perlindom.es.js';
|
|
45
|
+
</script>
|
|
46
|
+
```
|
|
33
47
|
|
|
34
|
-
##
|
|
48
|
+
## 🚀 Quick Start
|
|
35
49
|
|
|
36
50
|
```javascript
|
|
37
|
-
import PerlinDOM from '@andresclua/
|
|
51
|
+
import PerlinDOM from '@andresclua/perlindom';
|
|
38
52
|
|
|
39
|
-
//
|
|
53
|
+
// Basic animation - element will animate from its current position
|
|
40
54
|
const animation = new PerlinDOM({
|
|
41
55
|
element: document.querySelector('.my-element'),
|
|
42
|
-
x: { min: -50, max: 50 }, //
|
|
43
|
-
y: { min: -
|
|
56
|
+
x: { min: -50, max: 50 }, // Move ±50px horizontally
|
|
57
|
+
y: { min: -30, max: 30 }, // Move ±30px vertically
|
|
44
58
|
speed: 0.01, // Animation speed
|
|
45
|
-
seed: 123 //
|
|
59
|
+
seed: 123 // Reproducible pattern
|
|
46
60
|
});
|
|
61
|
+
|
|
62
|
+
// Control the animation
|
|
63
|
+
animation.pause(); // Smooth pause
|
|
64
|
+
animation.play(); // Resume
|
|
65
|
+
animation.destroy(); // Clean up
|
|
47
66
|
```
|
|
48
67
|
|
|
49
|
-
|
|
68
|
+
```css
|
|
69
|
+
/* Your element needs positioning for transforms to work */
|
|
70
|
+
.my-element {
|
|
71
|
+
position: relative; /* or absolute, or fixed */
|
|
72
|
+
/* PerlinDOM will animate from wherever this element is positioned */
|
|
73
|
+
}
|
|
74
|
+
```
|
|
50
75
|
|
|
51
|
-
|
|
52
|
-
|--------|------|-------------|
|
|
53
|
-
| `element` | HTMLElement | The DOM element to animate |
|
|
54
|
-
| `x` | Object or null | Horizontal movement configuration: `{min: value, max: value}`. Values can be numbers (pixels) or strings with '%' (percentage of parent width). Use `null` to disable horizontal movement |
|
|
55
|
-
| `y` | Object or null | Vertical movement configuration: `{min: value, max: value}`. Values can be numbers (pixels) or strings with '%' (percentage of parent height). Use `null` to disable vertical movement |
|
|
56
|
-
| `speed` | Number | Animation speed (smaller values = slower movement) |
|
|
57
|
-
| `seed` | Number | Seed for the Perlin noise generator |
|
|
58
|
-
| `lerpSpeed` | Number | Interpolation speed for smooth transitions (default: 0.1) |
|
|
76
|
+
## ⚙️ Configuration
|
|
59
77
|
|
|
60
|
-
|
|
78
|
+
| Option | Type | Default | Description |
|
|
79
|
+
|--------|------|---------|-------------|
|
|
80
|
+
| `element` | `HTMLElement` | **required** | The DOM element to animate |
|
|
81
|
+
| `x` | `Object \| null` | `null` | Horizontal movement: `{min: number, max: number}` |
|
|
82
|
+
| `y` | `Object \| null` | `null` | Vertical movement: `{min: number, max: number}` |
|
|
83
|
+
| `speed` | `number` | `0.01` | Animation speed (lower = slower) |
|
|
84
|
+
| `seed` | `number` | `0` | Seed for reproducible patterns |
|
|
85
|
+
| `lerpSpeed` | `number` | `0.1` | Transition smoothness for pause/play |
|
|
61
86
|
|
|
62
|
-
|
|
87
|
+
### Value Types
|
|
63
88
|
|
|
64
|
-
|
|
89
|
+
- **Pixels**: `{ min: -50, max: 50 }` - Fixed pixel movement
|
|
90
|
+
- **Percentages**: `{ min: '-10%', max: '10%' }` - Responsive to parent size
|
|
91
|
+
- **Mixed**: `x: { min: '-5%', max: '5%' }, y: { min: -20, max: 20 }`
|
|
92
|
+
- **Single Axis**: Set unused axis to `null`
|
|
65
93
|
|
|
66
|
-
|
|
67
|
-
const responsiveAnimation = new PerlinDOM({
|
|
68
|
-
element: document.querySelector('.responsive-element'),
|
|
69
|
-
x: { min: '-10%', max: '10%' }, // 10% of parent width in each direction
|
|
70
|
-
y: { min: '-5%', max: '5%' }, // 5% of parent height in each direction
|
|
71
|
-
speed: 0.01,
|
|
72
|
-
seed: 123
|
|
73
|
-
});
|
|
74
|
-
```
|
|
94
|
+
## 📚 Examples
|
|
75
95
|
|
|
76
|
-
|
|
96
|
+
### 1. Basic Element Animation
|
|
77
97
|
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
element: document.querySelector('.mixed-element'),
|
|
81
|
-
x: { min: '-10%', max: '10%' }, // Percentage-based horizontal movement
|
|
82
|
-
y: { min: -20, max: 20 }, // Pixel-based vertical movement
|
|
83
|
-
speed: 0.01,
|
|
84
|
-
seed: 456
|
|
85
|
-
});
|
|
98
|
+
```html
|
|
99
|
+
<div class="floating-card">Content</div>
|
|
86
100
|
```
|
|
87
101
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
102
|
+
```css
|
|
103
|
+
.floating-card {
|
|
104
|
+
position: relative;
|
|
105
|
+
left: 50%;
|
|
106
|
+
top: 50%;
|
|
107
|
+
transform: translate(-50%, -50%);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
95
110
|
|
|
96
111
|
```javascript
|
|
97
|
-
|
|
98
|
-
element: document.querySelector('.
|
|
99
|
-
x: { min: -
|
|
100
|
-
y: { min: -
|
|
101
|
-
speed: 0.
|
|
102
|
-
seed:
|
|
112
|
+
new PerlinDOM({
|
|
113
|
+
element: document.querySelector('.floating-card'),
|
|
114
|
+
x: { min: -20, max: 20 },
|
|
115
|
+
y: { min: -15, max: 15 },
|
|
116
|
+
speed: 0.008,
|
|
117
|
+
seed: 42
|
|
103
118
|
});
|
|
104
119
|
```
|
|
105
120
|
|
|
106
|
-
### 2.
|
|
107
|
-
|
|
108
|
-
Animate an element only on the horizontal axis.
|
|
121
|
+
### 2. Responsive Background Elements
|
|
109
122
|
|
|
110
123
|
```javascript
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
// Elements adapt to container size changes
|
|
125
|
+
document.querySelectorAll('.bg-particle').forEach((el, index) => {
|
|
126
|
+
new PerlinDOM({
|
|
127
|
+
element: el,
|
|
128
|
+
x: { min: '-15%', max: '15%' }, // 15% of parent width
|
|
129
|
+
y: { min: '-10%', max: '10%' }, // 10% of parent height
|
|
130
|
+
speed: 0.003,
|
|
131
|
+
seed: index * 1000
|
|
132
|
+
});
|
|
116
133
|
});
|
|
117
134
|
```
|
|
118
135
|
|
|
119
|
-
### 3.
|
|
120
|
-
|
|
121
|
-
Animate multiple elements with different patterns.
|
|
136
|
+
### 3. Interactive Hover Effects
|
|
122
137
|
|
|
123
138
|
```javascript
|
|
124
|
-
document.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
const button = document.querySelector('.animated-button');
|
|
140
|
+
let animation;
|
|
141
|
+
|
|
142
|
+
button.addEventListener('mouseenter', () => {
|
|
143
|
+
animation = new PerlinDOM({
|
|
144
|
+
element: button.querySelector('.effect'),
|
|
145
|
+
x: { min: -5, max: 5 },
|
|
146
|
+
y: { min: -5, max: 5 },
|
|
147
|
+
speed: 0.02,
|
|
148
|
+
lerpSpeed: 0.15
|
|
131
149
|
});
|
|
132
150
|
});
|
|
133
|
-
```
|
|
134
151
|
|
|
135
|
-
|
|
152
|
+
button.addEventListener('mouseleave', () => {
|
|
153
|
+
animation?.pause();
|
|
154
|
+
});
|
|
155
|
+
```
|
|
136
156
|
|
|
137
|
-
|
|
157
|
+
### 4. Multiple Elements with Synchronized Patterns
|
|
138
158
|
|
|
139
159
|
```javascript
|
|
140
|
-
|
|
160
|
+
// Same seed = synchronized movement
|
|
161
|
+
document.querySelectorAll('.sync-element').forEach(el => {
|
|
141
162
|
new PerlinDOM({
|
|
142
163
|
element: el,
|
|
143
|
-
x: { min: -
|
|
144
|
-
y: { min: -
|
|
145
|
-
speed: 0.
|
|
146
|
-
seed:
|
|
164
|
+
x: { min: -30, max: 30 },
|
|
165
|
+
y: { min: -30, max: 30 },
|
|
166
|
+
speed: 0.01,
|
|
167
|
+
seed: 12345 // Same seed for all elements
|
|
147
168
|
});
|
|
148
169
|
});
|
|
149
170
|
```
|
|
150
171
|
|
|
151
|
-
### 5.
|
|
152
|
-
|
|
153
|
-
Control the animation with mouse events.
|
|
172
|
+
### 5. Custom Animation Patterns
|
|
154
173
|
|
|
155
174
|
```javascript
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
lerpSpeed: 0.05 // Controls how smooth the transition is
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// Pause on mouse leave
|
|
166
|
-
document.querySelector('.container').addEventListener('mouseleave', () => {
|
|
167
|
-
pausePlayAnimation.pause();
|
|
175
|
+
// Horizontal-only movement for sliding effects
|
|
176
|
+
new PerlinDOM({
|
|
177
|
+
element: document.querySelector('.slider'),
|
|
178
|
+
x: { min: -100, max: 100 },
|
|
179
|
+
y: null, // No vertical movement
|
|
180
|
+
speed: 0.005
|
|
168
181
|
});
|
|
169
182
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
183
|
+
// Vertical-only for floating effects
|
|
184
|
+
new PerlinDOM({
|
|
185
|
+
element: document.querySelector('.floater'),
|
|
186
|
+
x: null, // No horizontal movement
|
|
187
|
+
y: { min: -40, max: 40 },
|
|
188
|
+
speed: 0.008
|
|
173
189
|
});
|
|
174
190
|
```
|
|
175
191
|
|
|
176
|
-
### 6.
|
|
177
|
-
|
|
178
|
-
Allow the user to adjust animation parameters.
|
|
192
|
+
### 6. Advanced: SVG Path Animation
|
|
179
193
|
|
|
180
194
|
```javascript
|
|
181
|
-
//
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
195
|
+
// Animate SVG elements or paths
|
|
196
|
+
const svgElement = document.querySelector('#animated-path');
|
|
197
|
+
const pathAnimation = new PerlinDOM({
|
|
198
|
+
element: null, // No direct element
|
|
199
|
+
x: { min: -20, max: 20 },
|
|
200
|
+
y: { min: -15, max: 15 },
|
|
186
201
|
speed: 0.01,
|
|
187
|
-
seed:
|
|
202
|
+
seed: 999
|
|
188
203
|
});
|
|
189
204
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
205
|
+
function updatePath() {
|
|
206
|
+
const offsetX = pathAnimation.lastX;
|
|
207
|
+
const offsetY = pathAnimation.lastY;
|
|
208
|
+
|
|
209
|
+
// Update SVG path or transform
|
|
210
|
+
svgElement.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
|
|
211
|
+
|
|
212
|
+
requestAnimationFrame(updatePath);
|
|
213
|
+
}
|
|
214
|
+
updatePath();
|
|
195
215
|
```
|
|
196
216
|
|
|
197
|
-
|
|
217
|
+
## 💡 Best Practices
|
|
218
|
+
|
|
219
|
+
### ✅ Do
|
|
220
|
+
|
|
221
|
+
- **Use CSS for initial positioning**: Position elements with CSS classes rather than inline styles
|
|
222
|
+
- **Set proper positioning**: Ensure elements have `position: relative`, `absolute`, or `fixed`
|
|
223
|
+
- **Use percentage values for responsive designs**: Great for mobile-friendly animations
|
|
224
|
+
- **Choose appropriate speeds**: Start with `0.01` and adjust based on desired effect
|
|
225
|
+
- **Clean up animations**: Call `destroy()` when removing elements from DOM
|
|
226
|
+
|
|
227
|
+
### ❌ Don't
|
|
198
228
|
|
|
199
|
-
|
|
229
|
+
- **Don't rely on inline positioning**: PerlinDOM works from any position, but CSS is cleaner
|
|
230
|
+
- **Don't use on static elements**: Transform won't work without proper positioning
|
|
231
|
+
- **Don't forget to destroy**: Memory leaks can occur if animations aren't cleaned up
|
|
232
|
+
- **Don't use extreme speeds**: Very high speeds can cause jittery animations
|
|
233
|
+
|
|
234
|
+
### 🎯 Performance Tips
|
|
200
235
|
|
|
201
236
|
```javascript
|
|
202
|
-
//
|
|
203
|
-
const
|
|
204
|
-
let circleAnimations = [];
|
|
205
|
-
|
|
206
|
-
// Function to initialize animations
|
|
207
|
-
function initCircleAnimations() {
|
|
208
|
-
// Clear existing animations
|
|
209
|
-
circleAnimations.forEach(anim => anim.destroy());
|
|
210
|
-
circleAnimations = [];
|
|
211
|
-
|
|
212
|
-
// Create new animations for each circle
|
|
213
|
-
circleElements.forEach((el, index) => {
|
|
214
|
-
const animation = new PerlinDOM({
|
|
215
|
-
element: el,
|
|
216
|
-
x: { min: -15, max: 15 },
|
|
217
|
-
y: { min: -15, max: 15 },
|
|
218
|
-
speed: 0.03,
|
|
219
|
-
seed: index * 1000,
|
|
220
|
-
lerpSpeed: 0.1
|
|
221
|
-
});
|
|
222
|
-
circleAnimations.push(animation);
|
|
223
|
-
});
|
|
224
|
-
}
|
|
237
|
+
// Good: Reuse animation instances
|
|
238
|
+
const sharedAnimation = new PerlinDOM({...});
|
|
225
239
|
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
initCircleAnimations();
|
|
229
|
-
circleAnimations.forEach(anim => anim.play());
|
|
230
|
-
});
|
|
240
|
+
// Good: Use percentage values for responsive design
|
|
241
|
+
x: { min: '-5%', max: '5%' }
|
|
231
242
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
243
|
+
// Good: Appropriate speeds for smooth animation
|
|
244
|
+
speed: 0.01 // Smooth and natural
|
|
245
|
+
|
|
246
|
+
// Good: Clean up when done
|
|
247
|
+
animation.destroy();
|
|
235
248
|
```
|
|
236
249
|
|
|
237
|
-
|
|
250
|
+
## 📖 API Reference
|
|
238
251
|
|
|
239
|
-
|
|
252
|
+
### Constructor
|
|
240
253
|
|
|
241
254
|
```javascript
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// Store the original points
|
|
246
|
-
const originalPoints = {
|
|
247
|
-
x1: 150, y1: 50, // Top vertex
|
|
248
|
-
x2: 250, y2: 250, // Bottom right
|
|
249
|
-
x3: 50, y3: 250 // Bottom left
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
// Create a custom animation function
|
|
253
|
-
function animateTriangle() {
|
|
254
|
-
// Create a PerlinDOM instance for the top vertex
|
|
255
|
-
const topVertexAnimation = new PerlinDOM({
|
|
256
|
-
element: null, // We're not moving a DOM element directly
|
|
257
|
-
x: { min: -30, max: 30 },
|
|
258
|
-
y: { min: -20, max: 20 },
|
|
259
|
-
speed: 0.005,
|
|
260
|
-
seed: 42
|
|
261
|
-
});
|
|
255
|
+
new PerlinDOM(options)
|
|
256
|
+
```
|
|
262
257
|
|
|
263
|
-
|
|
264
|
-
function updateTriangle() {
|
|
265
|
-
// Get the current noise values
|
|
266
|
-
const offsetX = topVertexAnimation.lastX;
|
|
267
|
-
const offsetY = topVertexAnimation.lastY;
|
|
258
|
+
### Methods
|
|
268
259
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
260
|
+
| Method | Description | Returns |
|
|
261
|
+
|--------|-------------|---------|
|
|
262
|
+
| `play()` | Start or resume animation | `void` |
|
|
263
|
+
| `pause()` | Smoothly pause animation | `void` |
|
|
264
|
+
| `destroy()` | Stop animation and clean up resources | `void` |
|
|
265
|
+
| `init(seed?)` | Reinitialize with optional new seed | `void` |
|
|
272
266
|
|
|
273
|
-
|
|
274
|
-
requestAnimationFrame(updateTriangle);
|
|
275
|
-
}
|
|
267
|
+
### Properties
|
|
276
268
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
269
|
+
| Property | Type | Description |
|
|
270
|
+
|----------|------|-------------|
|
|
271
|
+
| `lastX` | `number` | Current X offset value |
|
|
272
|
+
| `lastY` | `number` | Current Y offset value |
|
|
273
|
+
| `isPlaying` | `boolean` | Current animation state |
|
|
274
|
+
| `speed` | `number` | Animation speed (writable) |
|
|
275
|
+
| `lerpSpeed` | `number` | Transition speed (writable) |
|
|
280
276
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
277
|
+
## 🔧 Troubleshooting
|
|
278
|
+
|
|
279
|
+
### Common Issues
|
|
284
280
|
|
|
285
|
-
|
|
281
|
+
**❓ Animation not visible**
|
|
282
|
+
```css
|
|
283
|
+
/* Ensure element has positioning */
|
|
284
|
+
.my-element {
|
|
285
|
+
position: relative; /* or absolute/fixed */
|
|
286
|
+
}
|
|
287
|
+
```
|
|
286
288
|
|
|
287
|
-
|
|
289
|
+
**❓ Element jumps on initialization**
|
|
290
|
+
- PerlinDOM automatically detects current position
|
|
291
|
+
- If element has conflicting inline styles, consider moving to CSS
|
|
288
292
|
|
|
293
|
+
**❓ Animation too fast/slow**
|
|
289
294
|
```javascript
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
seed: 789
|
|
296
|
-
});
|
|
295
|
+
// Adjust speed value
|
|
296
|
+
speed: 0.001 // Very slow
|
|
297
|
+
speed: 0.01 // Normal
|
|
298
|
+
speed: 0.1 // Fast
|
|
299
|
+
```
|
|
297
300
|
|
|
298
|
-
|
|
299
|
-
|
|
301
|
+
**❓ Percentage values not working**
|
|
302
|
+
- Ensure parent container has defined dimensions
|
|
303
|
+
- PerlinDOM calculates percentages based on parent size
|
|
304
|
+
|
|
305
|
+
**❓ Memory leaks**
|
|
306
|
+
```javascript
|
|
307
|
+
// Always clean up when removing elements
|
|
308
|
+
animation.destroy();
|
|
300
309
|
```
|
|
301
310
|
|
|
302
|
-
|
|
311
|
+
### Browser DevTools
|
|
312
|
+
|
|
313
|
+
Monitor performance in DevTools:
|
|
314
|
+
- Check for smooth 60fps in Performance tab
|
|
315
|
+
- Verify transform properties are being animated (not layout properties)
|
|
316
|
+
|
|
317
|
+
## 🌐 Browser Compatibility
|
|
318
|
+
|
|
319
|
+
PerlinDOM works in all modern browsers supporting:
|
|
320
|
+
|
|
321
|
+
- ✅ **ES6 Modules** (2015+)
|
|
322
|
+
- ✅ **requestAnimationFrame** (IE10+)
|
|
323
|
+
- ✅ **CSS Transforms** (IE9+)
|
|
324
|
+
- ✅ **getComputedStyle** (IE9+)
|
|
325
|
+
|
|
326
|
+
### Tested Browsers
|
|
327
|
+
|
|
328
|
+
- Chrome 60+
|
|
329
|
+
- Firefox 55+
|
|
330
|
+
- Safari 12+
|
|
331
|
+
- Edge 79+
|
|
332
|
+
|
|
333
|
+
## 📝 Changelog
|
|
334
|
+
|
|
335
|
+
See [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
|
|
336
|
+
|
|
337
|
+
### Recent Updates
|
|
338
|
+
|
|
339
|
+
- **v0.0.3**: Fixed positioning conflicts, improved automatic position detection
|
|
340
|
+
- **v0.0.2**: Added percentage support and responsive animations
|
|
341
|
+
- **v0.0.1**: Initial release with core Perlin noise animations
|
|
303
342
|
|
|
304
|
-
|
|
305
|
-
- **Hover effects**: Enhance the interactivity of buttons and links
|
|
306
|
-
- **Data visualizations**: Add subtle movement to charts and visualizations
|
|
307
|
-
- **Decorative elements**: Bring decorative elements to life on your website
|
|
308
|
-
- **User interfaces**: Create more dynamic and attractive interfaces
|
|
343
|
+
## 📄 License
|
|
309
344
|
|
|
310
|
-
|
|
345
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
311
346
|
|
|
312
|
-
|
|
313
|
-
- ES6 (ECMAScript 2015)
|
|
314
|
-
- requestAnimationFrame
|
|
315
|
-
- CSS positioning (absolute, relative, fixed)
|
|
347
|
+
---
|
|
316
348
|
|
|
317
|
-
|
|
349
|
+
**Made with ❤️ by [Andres Clua](https://github.com/andresclua)**
|
|
318
350
|
|
|
319
|
-
|
|
351
|
+
*PerlinDOM - Bringing organic motion to the web*
|
package/src/index.html
CHANGED
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
background-color: #3498db;
|
|
60
60
|
border-radius: 50%;
|
|
61
61
|
position: absolute;
|
|
62
|
-
left: calc(50% - 40px);
|
|
63
|
-
top: calc(50% - 40px);
|
|
62
|
+
left: calc(50% - 40px);
|
|
63
|
+
top: calc(50% - 40px);
|
|
64
64
|
filter: blur(5px);
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -86,6 +86,32 @@
|
|
|
86
86
|
filter: blur(10px);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/* Positioning for particles - these are initial positions, PerlinDOM will animate from here */
|
|
90
|
+
.particle:nth-child(1) {
|
|
91
|
+
left: 30%;
|
|
92
|
+
top: 30%;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.particle:nth-child(2) {
|
|
96
|
+
left: 50%;
|
|
97
|
+
top: 50%;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.particle:nth-child(3) {
|
|
101
|
+
left: 70%;
|
|
102
|
+
top: 70%;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.particle:nth-child(4) {
|
|
106
|
+
left: 30%;
|
|
107
|
+
top: 70%;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.particle:nth-child(5) {
|
|
111
|
+
left: 70%;
|
|
112
|
+
top: 30%;
|
|
113
|
+
}
|
|
114
|
+
|
|
89
115
|
/* Example 4: Background Effect */
|
|
90
116
|
.bg-container {
|
|
91
117
|
background-color: #34495e;
|
|
@@ -403,11 +429,11 @@
|
|
|
403
429
|
});
|
|
404
430
|
</div>
|
|
405
431
|
<div class="example-container">
|
|
406
|
-
<div class="particle"
|
|
407
|
-
<div class="particle"
|
|
408
|
-
<div class="particle"
|
|
409
|
-
<div class="particle"
|
|
410
|
-
<div class="particle"
|
|
432
|
+
<div class="particle"></div>
|
|
433
|
+
<div class="particle"></div>
|
|
434
|
+
<div class="particle"></div>
|
|
435
|
+
<div class="particle"></div>
|
|
436
|
+
<div class="particle"></div>
|
|
411
437
|
</div>
|
|
412
438
|
|
|
413
439
|
<!-- Example 4: Background Effect -->
|
package/src/js/PerlinDom.js
CHANGED
|
@@ -60,17 +60,24 @@ class PerlinDOM {
|
|
|
60
60
|
|
|
61
61
|
// Solo inicializar estas propiedades si el elemento no es null
|
|
62
62
|
if (element) {
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
// Ensure element has positioning for transform to work properly
|
|
64
|
+
const computedStyle = window.getComputedStyle(element);
|
|
65
|
+
if (computedStyle.position === 'static') {
|
|
66
|
+
element.style.position = 'relative';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Initialize transform if it doesn't exist
|
|
70
|
+
const currentTransform = computedStyle.transform;
|
|
71
|
+
if (!currentTransform || currentTransform === 'none') {
|
|
72
|
+
element.style.transform = 'translate3d(0px, 0px, 0px)';
|
|
73
|
+
}
|
|
65
74
|
|
|
66
75
|
// If using percentages, add resize listener
|
|
67
76
|
if (this.hasPercentages) {
|
|
68
77
|
this.handleResize = this.handleResize.bind(this);
|
|
69
78
|
window.addEventListener('resize', this.handleResize);
|
|
70
79
|
}
|
|
71
|
-
|
|
72
|
-
this.initialX = 0;
|
|
73
|
-
this.initialY = 0;
|
|
80
|
+
|
|
74
81
|
}
|
|
75
82
|
|
|
76
83
|
this.animate = this.animate.bind(this);
|
|
@@ -263,9 +270,8 @@ class PerlinDOM {
|
|
|
263
270
|
this.lastX = valX;
|
|
264
271
|
this.lastY = valY;
|
|
265
272
|
|
|
266
|
-
// Update position using
|
|
267
|
-
this.el.style.
|
|
268
|
-
this.el.style.top = `${this.initialY + valY}px`;
|
|
273
|
+
// Update position using transform for better performance
|
|
274
|
+
this.el.style.transform = `translate3d(${valX}px, ${valY}px, 0)`;
|
|
269
275
|
} else {
|
|
270
276
|
// If no element, just calculate and store the values
|
|
271
277
|
const valX = this.xRange
|