@andresclua/perlindom 0.0.2 → 0.0.3

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 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,7 +1,7 @@
1
1
  {
2
2
  "name": "@andresclua/perlindom",
3
3
  "private": false,
4
- "version": "0.0.2",
4
+ "version": "0.0.3",
5
5
  "description": "A lightweight JavaScript library for creating smooth, organic animations for DOM elements using Perlin noise",
6
6
  "type": "module",
7
7
  "main": "./dist/perlindom.umd.js",
package/readme.md CHANGED
@@ -1,319 +1,351 @@
1
1
  # PerlinDOM
2
2
 
3
- A lightweight JavaScript library for creating organic and fluid animations on DOM elements using Perlin noise.
4
-
5
- ## Description
6
-
7
- PerlinDOM allows you to animate HTML elements with natural and organic movements based on Perlin noise. This technique creates movements that appear random but are smooth and predictable, perfect for subtle and attractive visual effects.
8
-
9
- ## Methods
10
-
11
- | Method | Description |
12
- |--------|-------------|
13
- | `play()` | Starts or resumes the animation |
14
- | `pause()` | Pauses the animation |
15
- | `destroy()` | Stops the animation and cleans up resources |
16
- | `init(seed)` | Reinitializes the animation with an optional new seed |
17
-
18
- ## Features
19
-
20
- - **Organic animations**: Natural movements that avoid the rigidity of traditional animations
21
- - **Customizable**: Control over movement ranges, speed, and noise seed
22
- - **Responsive**: Support for percentage-based values that adapt to container size
23
- - **Lightweight**: Minimal implementation with no external dependencies
24
- - **Easy to use**: Simple API to implement complex effects
25
- - **Optimized performance**: Uses requestAnimationFrame for smooth animations
26
-
27
- ## Installation
3
+ [![npm version](https://badge.fury.io/js/@andresclua%2Fperlindom.svg)](https://badge.fury.io/js/@andresclua%2Fperlindom)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![JavaScript](https://img.shields.io/badge/JavaScript-ES6+-yellow.svg)](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/PerlinDOM
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
- ## Basic Usage
48
+ ## 🚀 Quick Start
35
49
 
36
50
  ```javascript
37
- import PerlinDOM from '@andresclua/PerlinDOM';
51
+ import PerlinDOM from '@andresclua/perlindom';
38
52
 
39
- // Create a basic animation
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 }, // Horizontal movement range in pixels
43
- y: { min: -50, max: 50 }, // Vertical movement range in pixels
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 // Seed for the noise generator
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
- ## Configuration Options
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
- | Option | Type | Description |
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
- > **⚠️ Important**: For PerlinDOM to work correctly, the animated element **must** have a CSS `position` property set to `absolute`, `relative`, or `fixed`. Without this property, the animation will not function as expected.
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
- ## Percentage-Based Values
87
+ ### Value Types
63
88
 
64
- PerlinDOM now supports percentage-based values for movement ranges, allowing for responsive animations that adapt to the size of the parent container:
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
- ```javascript
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
- You can also mix pixel and percentage values:
96
+ ### 1. Basic Element Animation
77
97
 
78
- ```javascript
79
- const mixedAnimation = new PerlinDOM({
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
- When using percentage values, PerlinDOM automatically recalculates the movement range when the window is resized, ensuring that your animations remain proportional to their container.
89
-
90
- ## Examples
91
-
92
- ### 1. Basic Animation
93
-
94
- Create an element with smooth movement on both axes.
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
- const basicAnimation = new PerlinDOM({
98
- element: document.querySelector('.element'),
99
- x: { min: -50, max: 50 },
100
- y: { min: -50, max: 50 },
101
- speed: 0.01,
102
- seed: 123
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. Horizontal-Only Movement
107
-
108
- Animate an element only on the horizontal axis.
121
+ ### 2. Responsive Background Elements
109
122
 
110
123
  ```javascript
111
- const horizontalAnimation = new PerlinDOM({
112
- element: document.querySelector('.horizontal-element'),
113
- x: { min: -100, max: 100 },
114
- y: null, // No vertical movement
115
- speed: 0.02
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. Multiple Elements with Different Seeds
120
-
121
- Animate multiple elements with different patterns.
136
+ ### 3. Interactive Hover Effects
122
137
 
123
138
  ```javascript
124
- document.querySelectorAll('.particle').forEach((el, index) => {
125
- new PerlinDOM({
126
- element: el,
127
- x: { min: -100, max: 100 },
128
- y: { min: -100, max: 100 },
129
- speed: 0.01,
130
- seed: index * 100 // Different seed for each element
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
- ### 4. Background Effect
152
+ button.addEventListener('mouseleave', () => {
153
+ animation?.pause();
154
+ });
155
+ ```
136
156
 
137
- Create a dynamic background with slowly moving elements.
157
+ ### 4. Multiple Elements with Synchronized Patterns
138
158
 
139
159
  ```javascript
140
- document.querySelectorAll('.bg-element').forEach(el => {
160
+ // Same seed = synchronized movement
161
+ document.querySelectorAll('.sync-element').forEach(el => {
141
162
  new PerlinDOM({
142
163
  element: el,
143
- x: { min: -10, max: 10 },
144
- y: { min: -10, max: 10 },
145
- speed: 0.002, // Very slow movement
146
- seed: Math.random() * 2000
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. Pause and Play with Mouse Events
152
-
153
- Control the animation with mouse events.
172
+ ### 5. Custom Animation Patterns
154
173
 
155
174
  ```javascript
156
- const pausePlayAnimation = new PerlinDOM({
157
- element: document.querySelector('.pause-element'),
158
- x: { min: -80, max: 80 },
159
- y: { min: -80, max: 80 },
160
- speed: 0.01,
161
- seed: 42,
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
- // Play on mouse enter
171
- document.querySelector('.container').addEventListener('mouseenter', () => {
172
- pausePlayAnimation.play();
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. Interactive Controls
177
-
178
- Allow the user to adjust animation parameters.
192
+ ### 6. Advanced: SVG Path Animation
179
193
 
180
194
  ```javascript
181
- // Create the animation with initial settings
182
- const interactiveAnimation = new PerlinDOM({
183
- element: document.querySelector('.interactive-element'),
184
- x: { min: -50, max: 50 },
185
- y: { min: -50, max: 50 },
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: 0
202
+ seed: 999
188
203
  });
189
204
 
190
- // Update settings based on user input
191
- speedControl.addEventListener('input', () => {
192
- interactiveAnimation.speed = parseFloat(speedControl.value);
193
- interactiveAnimation.init(); // Restart with new settings
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
- ### 7. Animated Button with Circles
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
- Create a button with animated hover effects.
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
- // Get all the circle elements inside the button
203
- const circleElements = document.querySelectorAll('.animated-button .circle');
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
- // Add event listeners to the button
227
- document.querySelector('.animated-button').addEventListener('mouseenter', () => {
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
- document.querySelector('.animated-button').addEventListener('mouseleave', () => {
233
- circleAnimations.forEach(anim => anim.pause());
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
- ### 8. Triangle with Animated Vertex
250
+ ## 📖 API Reference
238
251
 
239
- Use PerlinDOM to animate a vertex of an SVG polygon.
252
+ ### Constructor
240
253
 
241
254
  ```javascript
242
- // Get the polygon element
243
- const trianglePath = document.getElementById('trianglePath');
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
- // Animation function
264
- function updateTriangle() {
265
- // Get the current noise values
266
- const offsetX = topVertexAnimation.lastX;
267
- const offsetY = topVertexAnimation.lastY;
258
+ ### Methods
268
259
 
269
- // Update the polygon points
270
- const newPoints = `${originalPoints.x1 + offsetX},${originalPoints.y1 + offsetY} ${originalPoints.x2},${originalPoints.y2} ${originalPoints.x3},${originalPoints.y3}`;
271
- trianglePath.setAttribute('points', newPoints);
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
- // Continue animation
274
- requestAnimationFrame(updateTriangle);
275
- }
267
+ ### Properties
276
268
 
277
- // Start the animation
278
- updateTriangle();
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
- // Initialize the animation
282
- animateTriangle();
283
- ```
277
+ ## 🔧 Troubleshooting
278
+
279
+ ### Common Issues
284
280
 
285
- ### 9. Responsive Animation with Percentage Values
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
- Create an animation that adapts to the size of its container.
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
- const responsiveAnimation = new PerlinDOM({
291
- element: document.querySelector('.responsive-element'),
292
- x: { min: '-15%', max: '15%' }, // 15% of parent width in each direction
293
- y: { min: '-10%', max: '10%' }, // 10% of parent height in each direction
294
- speed: 0.008,
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
- // The animation will automatically adjust when the window is resized
299
- // No additional code needed for responsiveness
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
- ## Use Cases
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
- - **Background elements**: Create dynamic and organic backgrounds
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
- ## Compatibility
345
+ MIT License - see [LICENSE](./LICENSE) file for details.
311
346
 
312
- PerlinDOM works in all modern browsers that support:
313
- - ES6 (ECMAScript 2015)
314
- - requestAnimationFrame
315
- - CSS positioning (absolute, relative, fixed)
347
+ ---
316
348
 
317
- ## License
349
+ **Made with ❤️ by [Andres Clua](https://github.com/andresclua)**
318
350
 
319
- MIT
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); /* 50% - half width */
63
- top: calc(50% - 40px); /* 50% - half height */
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" style="left: 30%; top: 30%"></div>
407
- <div class="particle" style="left: 50%; top: 50%"></div>
408
- <div class="particle" style="left: 70%; top: 70%"></div>
409
- <div class="particle" style="left: 30%; top: 70%"></div>
410
- <div class="particle" style="left: 70%; top: 30%"></div>
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 -->
@@ -60,17 +60,23 @@ class PerlinDOM {
60
60
 
61
61
  // Solo inicializar estas propiedades si el elemento no es null
62
62
  if (element) {
63
- this.initialX = element.offsetLeft;
64
- this.initialY = element.offsetTop;
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
- } else {
72
- this.initialX = 0;
73
- this.initialY = 0;
74
80
  }
75
81
 
76
82
  this.animate = this.animate.bind(this);
@@ -263,9 +269,8 @@ class PerlinDOM {
263
269
  this.lastX = valX;
264
270
  this.lastY = valY;
265
271
 
266
- // Update position using left/top
267
- this.el.style.left = `${this.initialX + valX}px`;
268
- this.el.style.top = `${this.initialY + valY}px`;
272
+ // Update position using transform for better performance
273
+ this.el.style.transform = `translate3d(${valX}px, ${valY}px, 0)`;
269
274
  } else {
270
275
  // If no element, just calculate and store the values
271
276
  const valX = this.xRange