@andresclua/perlindom 0.0.4 → 0.0.6
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 +27 -0
- package/dist/PerlinDOM.es.js +98 -81
- package/dist/PerlinDOM.umd.js +1 -1
- package/package.json +1 -1
- package/readme.md +2 -0
- package/src/index.html +2 -0
- package/src/js/PerlinDom.js +293 -285
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.0.6] - 2025-02-09
|
|
9
|
+
|
|
10
|
+
## Changed
|
|
11
|
+
- **Transform Handling**: Movement now composes `translate3d` with existing CSS transforms (`scale`, `rotate`, etc.) instead of overriding them
|
|
12
|
+
- **Base Transform Extraction**: Introduced `#extractBaseTransform()` to strip prior translations while keeping scale/rotate/skew intact
|
|
13
|
+
- **Destroy Behavior**: `destroy()` now restores the original inline `transform` value of the element
|
|
14
|
+
|
|
15
|
+
### Improved
|
|
16
|
+
- **Configuration**: Added `preserveBaseTranslation` option to control whether original translations are kept
|
|
17
|
+
- **Flexibility**: New `refreshBaseTransform()` method allows recalculating the base transform when classes or styles change dynamically
|
|
18
|
+
|
|
19
|
+
## [0.0.5] - 2025-01-07
|
|
20
|
+
|
|
21
|
+
- **Remove logs** : remove logs
|
|
22
|
+
|
|
23
|
+
## [0.0.4] - 2025-01-07
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- **Package Configuration**: Updated package to be public (removed `"private": true`)
|
|
27
|
+
- **NPM Publishing**: Package is now available for public installation via npm
|
|
28
|
+
- **Module Exports**: Enhanced module exports configuration for better compatibility
|
|
29
|
+
- **Package Metadata**: Updated package name to `@andresclua/perlindom` with proper scoping
|
|
30
|
+
|
|
31
|
+
### Improved
|
|
32
|
+
- **Distribution**: Better UMD and ES module support through improved exports configuration
|
|
33
|
+
- **Accessibility**: Package now publicly available on npm registry
|
|
34
|
+
|
|
8
35
|
## [0.0.3] - 2025-01-07
|
|
9
36
|
|
|
10
37
|
### Fixed
|
package/dist/PerlinDOM.es.js
CHANGED
|
@@ -1,121 +1,138 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
1
|
+
var D = Object.defineProperty;
|
|
2
|
+
var z = (c) => {
|
|
3
3
|
throw TypeError(c);
|
|
4
4
|
};
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var A = (c, t,
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
const
|
|
5
|
+
var H = (c, t, s) => t in c ? D(c, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : c[t] = s;
|
|
6
|
+
var S = (c, t, s) => H(c, typeof t != "symbol" ? t + "" : t, s), j = (c, t, s) => t.has(c) || z("Cannot " + s);
|
|
7
|
+
var A = (c, t, s) => t.has(c) ? z("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(c) : t.set(c, s);
|
|
8
|
+
var n = (c, t, s) => (j(c, t, "access private method"), s);
|
|
9
|
+
var r, E, I, d, P, f, W, C, T, B;
|
|
10
|
+
const l = class l {
|
|
11
11
|
constructor({
|
|
12
12
|
element: t,
|
|
13
|
-
x:
|
|
14
|
-
y:
|
|
15
|
-
speed:
|
|
16
|
-
seed:
|
|
17
|
-
lerpSpeed:
|
|
13
|
+
x: s = null,
|
|
14
|
+
y: e = null,
|
|
15
|
+
speed: h = 0.01,
|
|
16
|
+
seed: o = 0,
|
|
17
|
+
lerpSpeed: i = 0.1,
|
|
18
|
+
preserveBaseTranslation: a = !1
|
|
19
|
+
// <-- si querés mantener la traslación base
|
|
18
20
|
}) {
|
|
19
|
-
A(this,
|
|
20
|
-
|
|
21
|
-
var t,
|
|
22
|
-
if (this.lerpFactor !== this.targetLerpFactor && (this.lerpFactor =
|
|
21
|
+
A(this, f);
|
|
22
|
+
S(this, "animate", () => {
|
|
23
|
+
var t, s, e, h, o, i, a, m, g, p, u, R;
|
|
24
|
+
if (this.lerpFactor !== this.targetLerpFactor && (this.lerpFactor = n(this, f, C).call(this, this.lerpFactor, this.targetLerpFactor, this.lerpSpeed), Math.abs(this.lerpFactor - this.targetLerpFactor) < 1e-3 && (this.lerpFactor = this.targetLerpFactor)), this.lerpFactor > 0) {
|
|
23
25
|
this.time += this.speed * this.lerpFactor;
|
|
24
|
-
const
|
|
26
|
+
const x = this.noise.perlin2(this.time, 0), b = this.noise.perlin2(this.time, 100);
|
|
25
27
|
if (this.el) {
|
|
26
|
-
let
|
|
28
|
+
let F, y, v, L;
|
|
27
29
|
if (this.hasPercentages) {
|
|
28
|
-
const
|
|
29
|
-
this.xRange && (
|
|
30
|
+
const Y = this.el.parentElement || document.body, $ = Y.clientWidth, M = Y.clientHeight;
|
|
31
|
+
this.xRange && (F = n(t = l, r, d).call(t, this.xRange.min) ? n(s = l, r, P).call(s, this.xRange.min, $) : this.xRange.min, y = n(e = l, r, d).call(e, this.xRange.max) ? n(h = l, r, P).call(h, this.xRange.max, $) : this.xRange.max), this.yRange && (v = n(o = l, r, d).call(o, this.yRange.min) ? n(i = l, r, P).call(i, this.yRange.min, M) : this.yRange.min, L = n(a = l, r, d).call(a, this.yRange.max) ? n(m = l, r, P).call(m, this.yRange.max, M) : this.yRange.max);
|
|
30
32
|
} else
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
this.lastX =
|
|
33
|
+
F = (g = this.xRange) == null ? void 0 : g.min, y = (p = this.xRange) == null ? void 0 : p.max, v = (u = this.yRange) == null ? void 0 : u.min, L = (R = this.yRange) == null ? void 0 : R.max;
|
|
34
|
+
const X = this.xRange ? n(this, f, T).call(this, x, -1, 1, F, y) : 0, w = this.yRange ? n(this, f, T).call(this, b, -1, 1, v, L) : 0;
|
|
35
|
+
this.lastX = X, this.lastY = w, this.el.style.transform = `translate3d(${X}px, ${w}px, 0) ${this.baseTransform}`.trim();
|
|
34
36
|
} else {
|
|
35
|
-
const
|
|
36
|
-
this.lastX =
|
|
37
|
+
const F = this.xRange ? n(this, f, T).call(this, x, -1, 1, this.xRange.min, this.xRange.max) : 0, y = this.yRange ? n(this, f, T).call(this, b, -1, 1, this.yRange.min, this.yRange.max) : 0;
|
|
38
|
+
this.lastX = F, this.lastY = y;
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
(this.lerpFactor > 0 || this.targetLerpFactor > 0) && (this.raf = requestAnimationFrame(this.animate));
|
|
40
42
|
});
|
|
41
|
-
var
|
|
42
|
-
this.el = t, this.xRange =
|
|
43
|
+
var m, g, p, u;
|
|
44
|
+
if (this.el = t, this.xRange = s, this.yRange = e, this.speed = h, this.time = o, this.isPlaying = !0, this.lerpFactor = 1, this.lerpSpeed = i, this.targetLerpFactor = 1, this.lastX = 0, this.lastY = 0, this.preserveBaseTranslation = a, this.hasPercentages = !!(s && (n(m = l, r, d).call(m, s.min) || n(g = l, r, d).call(g, s.max)) || e && (n(p = l, r, d).call(p, e.min) || n(u = l, r, d).call(u, e.max))), t) {
|
|
45
|
+
const R = window.getComputedStyle(t);
|
|
46
|
+
R.position === "static" && (t.style.position = "relative"), this.originalInlineTransform = t.style.transform || "", this.baseTransform = n(this, f, B).call(this, R.transform, this.preserveBaseTranslation), this.hasPercentages && (this.handleResize = this.handleResize.bind(this), window.addEventListener("resize", this.handleResize));
|
|
47
|
+
} else
|
|
48
|
+
this.originalInlineTransform = "", this.baseTransform = "";
|
|
49
|
+
this.animate = this.animate.bind(this), this.init(o);
|
|
43
50
|
}
|
|
44
51
|
init(t) {
|
|
45
|
-
var
|
|
46
|
-
this.noise =
|
|
52
|
+
var s;
|
|
53
|
+
this.noise = n(this, f, W).call(this, n(s = l, r, I).call(s, t)), this.isPlaying = !0, this.lerpFactor = 1, this.targetLerpFactor = 1, this.raf = requestAnimationFrame(this.animate);
|
|
54
|
+
}
|
|
55
|
+
// Permite refrescar el transform base si cambian clases/estilos en runtime
|
|
56
|
+
refreshBaseTransform(t = this.preserveBaseTranslation) {
|
|
57
|
+
if (!this.el) return;
|
|
58
|
+
const s = window.getComputedStyle(this.el);
|
|
59
|
+
this.baseTransform = n(this, f, B).call(this, s.transform, t);
|
|
47
60
|
}
|
|
48
61
|
// Handle window resize for percentage-based values
|
|
49
62
|
handleResize() {
|
|
50
|
-
this.hasPercentages && this.el && (this.needsRecalculation = !0);
|
|
51
63
|
}
|
|
52
64
|
pause() {
|
|
53
|
-
this.isPlaying && (this.targetLerpFactor = 0, this.isPlaying = !1
|
|
65
|
+
this.isPlaying && (this.targetLerpFactor = 0, this.isPlaying = !1);
|
|
54
66
|
}
|
|
55
67
|
play() {
|
|
56
|
-
this.isPlaying || (this.targetLerpFactor = 1, this.isPlaying = !0, this.lerpFactor === 0 && (this.raf = requestAnimationFrame(this.animate))
|
|
68
|
+
this.isPlaying || (this.targetLerpFactor = 1, this.isPlaying = !0, this.lerpFactor === 0 && (this.raf = requestAnimationFrame(this.animate)));
|
|
57
69
|
}
|
|
58
70
|
destroy() {
|
|
59
|
-
cancelAnimationFrame(this.raf), this.hasPercentages && window.removeEventListener("resize", this.handleResize);
|
|
71
|
+
cancelAnimationFrame(this.raf), this.el && (this.el.style.transform = this.originalInlineTransform || ""), this.hasPercentages && window.removeEventListener("resize", this.handleResize);
|
|
60
72
|
}
|
|
61
73
|
};
|
|
62
|
-
|
|
74
|
+
r = new WeakSet(), E = function(t) {
|
|
63
75
|
return function() {
|
|
64
|
-
let
|
|
65
|
-
return
|
|
76
|
+
let s = t += 1831565813;
|
|
77
|
+
return s = Math.imul(s ^ s >>> 15, s | 1), s ^= s + Math.imul(s ^ s >>> 7, s | 61), ((s ^ s >>> 14) >>> 0) / 4294967296;
|
|
66
78
|
};
|
|
67
|
-
},
|
|
68
|
-
var
|
|
69
|
-
const
|
|
70
|
-
for (let
|
|
71
|
-
const
|
|
72
|
-
[
|
|
79
|
+
}, I = function(t = 0) {
|
|
80
|
+
var h;
|
|
81
|
+
const s = Array.from({ length: 256 }, (o, i) => i), e = n(h = l, r, E).call(h, t);
|
|
82
|
+
for (let o = 255; o > 0; o--) {
|
|
83
|
+
const i = Math.floor(e() * (o + 1));
|
|
84
|
+
[s[o], s[i]] = [s[i], s[o]];
|
|
73
85
|
}
|
|
74
|
-
return
|
|
75
|
-
},
|
|
86
|
+
return s.concat(s);
|
|
87
|
+
}, d = function(t) {
|
|
76
88
|
return typeof t == "string" && t.endsWith("%");
|
|
77
|
-
},
|
|
78
|
-
var
|
|
79
|
-
return
|
|
80
|
-
},
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
return (
|
|
84
|
-
},
|
|
89
|
+
}, P = function(t, s) {
|
|
90
|
+
var h;
|
|
91
|
+
return n(h = l, r, d).call(h, t) ? parseFloat(t) / 100 * s : t;
|
|
92
|
+
}, f = new WeakSet(), W = function(t) {
|
|
93
|
+
const s = (i) => i * i * i * (i * (i * 6 - 15) + 10), e = (i, a, m) => a + i * (m - a), h = (i, a, m) => {
|
|
94
|
+
const g = i & 15, p = g < 8 ? a : m, u = g < 4 ? m : g === 12 || g === 14 ? a : 0;
|
|
95
|
+
return (g & 1 ? -p : p) + (g & 2 ? -u : u);
|
|
96
|
+
}, o = (i, a) => i & 1 ? -a : a;
|
|
85
97
|
return {
|
|
86
98
|
// Original 1D Perlin noise function
|
|
87
|
-
perlin1(
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
return
|
|
99
|
+
perlin1(i) {
|
|
100
|
+
const a = Math.floor(i) & 255;
|
|
101
|
+
i -= Math.floor(i);
|
|
102
|
+
const m = s(i);
|
|
103
|
+
return e(m, o(t[a], i), o(t[a + 1], i - 1));
|
|
92
104
|
},
|
|
93
105
|
// New 2D Perlin noise function
|
|
94
|
-
perlin2(
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
h(
|
|
101
|
-
|
|
102
|
-
r(t[Y], s, e),
|
|
103
|
-
r(t[F], s - 1, e)
|
|
104
|
-
),
|
|
105
|
-
h(
|
|
106
|
-
f,
|
|
107
|
-
r(t[d], s, e - 1),
|
|
108
|
-
r(t[x], s - 1, e - 1)
|
|
109
|
-
)
|
|
106
|
+
perlin2(i, a) {
|
|
107
|
+
const m = Math.floor(i) & 255, g = Math.floor(a) & 255;
|
|
108
|
+
i -= Math.floor(i), a -= Math.floor(a);
|
|
109
|
+
const p = s(i), u = s(a), R = t[m] + g, x = t[m + 1] + g, b = t[R], F = t[R + 1], y = t[x], v = t[x + 1];
|
|
110
|
+
return e(
|
|
111
|
+
u,
|
|
112
|
+
e(p, h(t[b], i, a), h(t[y], i - 1, a)),
|
|
113
|
+
e(p, h(t[F], i, a - 1), h(t[v], i - 1, a - 1))
|
|
110
114
|
);
|
|
111
115
|
}
|
|
112
116
|
};
|
|
113
|
-
},
|
|
114
|
-
return t +
|
|
115
|
-
},
|
|
116
|
-
return (t -
|
|
117
|
-
},
|
|
118
|
-
|
|
117
|
+
}, C = function(t, s, e) {
|
|
118
|
+
return t + e * (s - t);
|
|
119
|
+
}, T = function(t, s, e, h, o) {
|
|
120
|
+
return (t - s) * (o - h) / (e - s) + h;
|
|
121
|
+
}, // Quita o preserva la traslación del transform base en 2D según flag
|
|
122
|
+
B = function(t, s = !1) {
|
|
123
|
+
if (!t || t === "none") return "";
|
|
124
|
+
try {
|
|
125
|
+
const e = new DOMMatrixReadOnly(t);
|
|
126
|
+
if (e.is2D) {
|
|
127
|
+
const h = s ? e.e : 0, o = s ? e.f : 0;
|
|
128
|
+
return `matrix(${e.a}, ${e.b}, ${e.c}, ${e.d}, ${h}, ${o})`;
|
|
129
|
+
} else
|
|
130
|
+
return t;
|
|
131
|
+
} catch {
|
|
132
|
+
return t;
|
|
133
|
+
}
|
|
134
|
+
}, A(l, r);
|
|
135
|
+
let q = l;
|
|
119
136
|
export {
|
|
120
|
-
|
|
137
|
+
q as default
|
|
121
138
|
};
|
package/dist/PerlinDOM.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(h,s){typeof exports=="object"&&typeof module<"u"?module.exports=s():typeof define=="function"&&define.amd?define(s):(h=typeof globalThis<"u"?globalThis:h||self,h.PerlinDOM=s())})(this,function(){"use strict";var j=Object.defineProperty;var S=h=>{throw TypeError(h)};var C=(h,s,u)=>s in h?j(h,s,{enumerable:!0,configurable:!0,writable:!0,value:u}):h[s]=u;var q=(h,s,u)=>C(h,typeof s!="symbol"?s+"":s,u),H=(h,s,u)=>s.has(h)||S("Cannot "+u);var B=(h,s,u)=>s.has(h)?S("Cannot add the same private member more than once"):s instanceof WeakSet?s.add(h):s.set(h,u);var r=(h,s,u)=>(H(h,s,"access private method"),u);var s,D,E,R,P,g,I,W,b,X;const c=class c{constructor({element:t,x:i=null,y:n=null,speed:o=.01,seed:l=0,lerpSpeed:e=.1,preserveBaseTranslation:a=!1}){B(this,g);q(this,"animate",()=>{var t,i,n,o,l,e,a,m,f,p,d,y;if(this.lerpFactor!==this.targetLerpFactor&&(this.lerpFactor=r(this,g,W).call(this,this.lerpFactor,this.targetLerpFactor,this.lerpSpeed),Math.abs(this.lerpFactor-this.targetLerpFactor)<.001&&(this.lerpFactor=this.targetLerpFactor)),this.lerpFactor>0){this.time+=this.speed*this.lerpFactor;const T=this.noise.perlin2(this.time,0),L=this.noise.perlin2(this.time,100);if(this.el){let F,x,v,A;if(this.hasPercentages){const Y=this.el.parentElement||document.body,$=Y.clientWidth,z=Y.clientHeight;this.xRange&&(F=r(t=c,s,R).call(t,this.xRange.min)?r(i=c,s,P).call(i,this.xRange.min,$):this.xRange.min,x=r(n=c,s,R).call(n,this.xRange.max)?r(o=c,s,P).call(o,this.xRange.max,$):this.xRange.max),this.yRange&&(v=r(l=c,s,R).call(l,this.yRange.min)?r(e=c,s,P).call(e,this.yRange.min,z):this.yRange.min,A=r(a=c,s,R).call(a,this.yRange.max)?r(m=c,s,P).call(m,this.yRange.max,z):this.yRange.max)}else F=(f=this.xRange)==null?void 0:f.min,x=(p=this.xRange)==null?void 0:p.max,v=(d=this.yRange)==null?void 0:d.min,A=(y=this.yRange)==null?void 0:y.max;const w=this.xRange?r(this,g,b).call(this,T,-1,1,F,x):0,M=this.yRange?r(this,g,b).call(this,L,-1,1,v,A):0;this.lastX=w,this.lastY=M,this.el.style.transform=`translate3d(${w}px, ${M}px, 0) ${this.baseTransform}`.trim()}else{const F=this.xRange?r(this,g,b).call(this,T,-1,1,this.xRange.min,this.xRange.max):0,x=this.yRange?r(this,g,b).call(this,L,-1,1,this.yRange.min,this.yRange.max):0;this.lastX=F,this.lastY=x}}(this.lerpFactor>0||this.targetLerpFactor>0)&&(this.raf=requestAnimationFrame(this.animate))});var m,f,p,d;if(this.el=t,this.xRange=i,this.yRange=n,this.speed=o,this.time=l,this.isPlaying=!0,this.lerpFactor=1,this.lerpSpeed=e,this.targetLerpFactor=1,this.lastX=0,this.lastY=0,this.preserveBaseTranslation=a,this.hasPercentages=!!(i&&(r(m=c,s,R).call(m,i.min)||r(f=c,s,R).call(f,i.max))||n&&(r(p=c,s,R).call(p,n.min)||r(d=c,s,R).call(d,n.max))),t){const y=window.getComputedStyle(t);y.position==="static"&&(t.style.position="relative"),this.originalInlineTransform=t.style.transform||"",this.baseTransform=r(this,g,X).call(this,y.transform,this.preserveBaseTranslation),this.hasPercentages&&(this.handleResize=this.handleResize.bind(this),window.addEventListener("resize",this.handleResize))}else this.originalInlineTransform="",this.baseTransform="";this.animate=this.animate.bind(this),this.init(l)}init(t){var i;this.noise=r(this,g,I).call(this,r(i=c,s,E).call(i,t)),this.isPlaying=!0,this.lerpFactor=1,this.targetLerpFactor=1,this.raf=requestAnimationFrame(this.animate)}refreshBaseTransform(t=this.preserveBaseTranslation){if(!this.el)return;const i=window.getComputedStyle(this.el);this.baseTransform=r(this,g,X).call(this,i.transform,t)}handleResize(){}pause(){this.isPlaying&&(this.targetLerpFactor=0,this.isPlaying=!1)}play(){this.isPlaying||(this.targetLerpFactor=1,this.isPlaying=!0,this.lerpFactor===0&&(this.raf=requestAnimationFrame(this.animate)))}destroy(){cancelAnimationFrame(this.raf),this.el&&(this.el.style.transform=this.originalInlineTransform||""),this.hasPercentages&&window.removeEventListener("resize",this.handleResize)}};s=new WeakSet,D=function(t){return function(){let i=t+=1831565813;return i=Math.imul(i^i>>>15,i|1),i^=i+Math.imul(i^i>>>7,i|61),((i^i>>>14)>>>0)/4294967296}},E=function(t=0){var o;const i=Array.from({length:256},(l,e)=>e),n=r(o=c,s,D).call(o,t);for(let l=255;l>0;l--){const e=Math.floor(n()*(l+1));[i[l],i[e]]=[i[e],i[l]]}return i.concat(i)},R=function(t){return typeof t=="string"&&t.endsWith("%")},P=function(t,i){var o;return r(o=c,s,R).call(o,t)?parseFloat(t)/100*i:t},g=new WeakSet,I=function(t){const i=e=>e*e*e*(e*(e*6-15)+10),n=(e,a,m)=>a+e*(m-a),o=(e,a,m)=>{const f=e&15,p=f<8?a:m,d=f<4?m:f===12||f===14?a:0;return(f&1?-p:p)+(f&2?-d:d)},l=(e,a)=>e&1?-a:a;return{perlin1(e){const a=Math.floor(e)&255;e-=Math.floor(e);const m=i(e);return n(m,l(t[a],e),l(t[a+1],e-1))},perlin2(e,a){const m=Math.floor(e)&255,f=Math.floor(a)&255;e-=Math.floor(e),a-=Math.floor(a);const p=i(e),d=i(a),y=t[m]+f,T=t[m+1]+f,L=t[y],F=t[y+1],x=t[T],v=t[T+1];return n(d,n(p,o(t[L],e,a),o(t[x],e-1,a)),n(p,o(t[F],e,a-1),o(t[v],e-1,a-1)))}}},W=function(t,i,n){return t+n*(i-t)},b=function(t,i,n,o,l){return(t-i)*(l-o)/(n-i)+o},X=function(t,i=!1){if(!t||t==="none")return"";try{const n=new DOMMatrixReadOnly(t);if(n.is2D){const o=i?n.e:0,l=i?n.f:0;return`matrix(${n.a}, ${n.b}, ${n.c}, ${n.d}, ${o}, ${l})`}else return t}catch{return t}},B(c,s);let h=c;return h});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andresclua/perlindom",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.6",
|
|
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
|
@@ -336,6 +336,8 @@ See [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
|
|
|
336
336
|
|
|
337
337
|
### Recent Updates
|
|
338
338
|
|
|
339
|
+
- **v0.0.6**: Enhanced PerlinDOM to preserve design transforms
|
|
340
|
+
- **v0.0.4**: Package now public on npm, enhanced module exports configuration
|
|
339
341
|
- **v0.0.3**: Fixed positioning conflicts, improved automatic position detection
|
|
340
342
|
- **v0.0.2**: Added percentage support and responsive animations
|
|
341
343
|
- **v0.0.1**: Initial release with core Perlin noise animations
|
package/src/index.html
CHANGED
package/src/js/PerlinDom.js
CHANGED
|
@@ -1,310 +1,318 @@
|
|
|
1
1
|
class PerlinDOM {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
static #generatePermutation(seed = 0) {
|
|
13
|
-
const permutation = Array.from({ length: 256 }, (_, i) => i);
|
|
14
|
-
const rand = PerlinDOM.#mulberry32(seed);
|
|
15
|
-
for (let i = 255; i > 0; i--) {
|
|
16
|
-
const j = Math.floor(rand() * (i + 1));
|
|
17
|
-
[permutation[i], permutation[j]] = [permutation[j], permutation[i]];
|
|
18
|
-
}
|
|
19
|
-
return permutation.concat(permutation);
|
|
20
|
-
}
|
|
2
|
+
/* ---------- helpers privados y estáticos ---------- */
|
|
3
|
+
static #mulberry32(a) {
|
|
4
|
+
return function () {
|
|
5
|
+
let t = (a += 0x6d2b79f5);
|
|
6
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
7
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
8
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
21
11
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
static #generatePermutation(seed = 0) {
|
|
13
|
+
const permutation = Array.from({ length: 256 }, (_, i) => i);
|
|
14
|
+
const rand = PerlinDOM.#mulberry32(seed);
|
|
15
|
+
for (let i = 255; i > 0; i--) {
|
|
16
|
+
const j = Math.floor(rand() * (i + 1));
|
|
17
|
+
[permutation[i], permutation[j]] = [permutation[j], permutation[i]];
|
|
25
18
|
}
|
|
19
|
+
return permutation.concat(permutation);
|
|
20
|
+
}
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
22
|
+
// Helper to check if a value is a percentage string
|
|
23
|
+
static #isPercentage(value) {
|
|
24
|
+
return typeof value === 'string' && value.endsWith('%');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Helper to convert percentage to pixels
|
|
28
|
+
static #percentToPixels(percentage, dimension) {
|
|
29
|
+
if (!PerlinDOM.#isPercentage(percentage)) return percentage;
|
|
30
|
+
const value = parseFloat(percentage);
|
|
31
|
+
return (value / 100) * dimension;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
constructor({
|
|
35
|
+
element,
|
|
36
|
+
x = null,
|
|
37
|
+
y = null,
|
|
38
|
+
speed = 0.01,
|
|
39
|
+
seed = 0,
|
|
40
|
+
lerpSpeed = 0.1,
|
|
41
|
+
preserveBaseTranslation = false, // <-- si querés mantener la traslación base
|
|
42
|
+
}) {
|
|
43
|
+
this.el = element;
|
|
44
|
+
this.xRange = x;
|
|
45
|
+
this.yRange = y;
|
|
46
|
+
this.speed = speed;
|
|
47
|
+
this.time = seed;
|
|
48
|
+
this.isPlaying = true;
|
|
49
|
+
this.lerpFactor = 1; // 1 = full speed, 0 = paused
|
|
50
|
+
this.lerpSpeed = lerpSpeed; // How fast to transition between play/pause states
|
|
51
|
+
this.targetLerpFactor = 1; // Target state (1 = play, 0 = pause)
|
|
52
|
+
this.lastX = 0;
|
|
53
|
+
this.lastY = 0;
|
|
54
|
+
this.preserveBaseTranslation = preserveBaseTranslation;
|
|
55
|
+
|
|
56
|
+
// Check if we have percentage values (paréntesis para evitar precedencia ambigua)
|
|
57
|
+
this.hasPercentages = !!(
|
|
58
|
+
(x && (PerlinDOM.#isPercentage(x.min) || PerlinDOM.#isPercentage(x.max))) ||
|
|
59
|
+
(y && (PerlinDOM.#isPercentage(y.min) || PerlinDOM.#isPercentage(y.max)))
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Solo inicializar estas propiedades si el elemento no es null
|
|
63
|
+
if (element) {
|
|
64
|
+
// Ensure element has positioning for transform to work properly
|
|
65
|
+
const computedStyle = window.getComputedStyle(element);
|
|
66
|
+
if (computedStyle.position === 'static') {
|
|
67
|
+
element.style.position = 'relative';
|
|
59
68
|
}
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// If using percentages, add resize listener
|
|
76
|
-
if (this.hasPercentages) {
|
|
77
|
-
this.handleResize = this.handleResize.bind(this);
|
|
78
|
-
window.addEventListener('resize', this.handleResize);
|
|
79
|
-
}
|
|
80
|
-
|
|
69
|
+
|
|
70
|
+
// Guardamos el transform inline original para restaurar en destroy()
|
|
71
|
+
this.originalInlineTransform = element.style.transform || '';
|
|
72
|
+
|
|
73
|
+
// Capturamos el transform base (quitando translate en 2D por defecto)
|
|
74
|
+
this.baseTransform = this.#extractBaseTransform(
|
|
75
|
+
computedStyle.transform,
|
|
76
|
+
this.preserveBaseTranslation
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Si usamos porcentajes, escuchamos resize
|
|
80
|
+
if (this.hasPercentages) {
|
|
81
|
+
this.handleResize = this.handleResize.bind(this);
|
|
82
|
+
window.addEventListener('resize', this.handleResize);
|
|
81
83
|
}
|
|
82
|
-
|
|
83
|
-
this.
|
|
84
|
-
|
|
85
|
-
this.init(seed);
|
|
84
|
+
} else {
|
|
85
|
+
this.originalInlineTransform = '';
|
|
86
|
+
this.baseTransform = '';
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
+
|
|
89
|
+
this.animate = this.animate.bind(this);
|
|
90
|
+
this.init(seed);
|
|
91
|
+
}
|
|
92
|
+
|
|
88
93
|
init(seed) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
this.noise = this.#createPerlin(PerlinDOM.#generatePermutation(seed));
|
|
95
|
+
this.isPlaying = true;
|
|
96
|
+
this.lerpFactor = 1;
|
|
97
|
+
this.targetLerpFactor = 1;
|
|
98
|
+
this.raf = requestAnimationFrame(this.animate);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Permite refrescar el transform base si cambian clases/estilos en runtime
|
|
102
|
+
refreshBaseTransform(preserveTranslation = this.preserveBaseTranslation) {
|
|
103
|
+
if (!this.el) return;
|
|
104
|
+
const cs = window.getComputedStyle(this.el);
|
|
105
|
+
this.baseTransform = this.#extractBaseTransform(cs.transform, preserveTranslation);
|
|
106
|
+
}
|
|
107
|
+
|
|
97
108
|
// Handle window resize for percentage-based values
|
|
98
109
|
handleResize() {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
110
|
+
// No necesitamos recalcular nada fuera de animate; se leen dimensiones en cada frame
|
|
111
|
+
// Este método queda por si querés extender la lógica (debounce, etc.).
|
|
112
|
+
}
|
|
113
|
+
|
|
106
114
|
pause() {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
console.log('PerlinDOM pausing...');
|
|
111
|
-
}
|
|
115
|
+
if (this.isPlaying) {
|
|
116
|
+
this.targetLerpFactor = 0; // Target paused state
|
|
117
|
+
this.isPlaying = false;
|
|
112
118
|
}
|
|
113
|
-
|
|
119
|
+
}
|
|
120
|
+
|
|
114
121
|
play() {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
console.log('PerlinDOM playing...');
|
|
122
|
+
if (!this.isPlaying) {
|
|
123
|
+
this.targetLerpFactor = 1; // Target playing state
|
|
124
|
+
this.isPlaying = true;
|
|
125
|
+
|
|
126
|
+
// Solo arrancar un nuevo frame si estaba completamente pausado
|
|
127
|
+
if (this.lerpFactor === 0) {
|
|
128
|
+
this.raf = requestAnimationFrame(this.animate);
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
grad2D(p[BA], x - 1, y)
|
|
181
|
-
),
|
|
182
|
-
lerp(
|
|
183
|
-
u,
|
|
184
|
-
grad2D(p[AB], x, y - 1),
|
|
185
|
-
grad2D(p[BB], x - 1, y - 1)
|
|
186
|
-
)
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
#lerp(a, b, t) {
|
|
193
|
-
return a + t * (b - a);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
animate = () => {
|
|
197
|
-
// Update lerp factor towards target
|
|
198
|
-
if (this.lerpFactor !== this.targetLerpFactor) {
|
|
199
|
-
this.lerpFactor = this.#lerp(
|
|
200
|
-
this.lerpFactor,
|
|
201
|
-
this.targetLerpFactor,
|
|
202
|
-
this.lerpSpeed
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
#createPerlin(p) {
|
|
134
|
+
const fade = t => t * t * t * (t * (t * 6 - 15) + 10);
|
|
135
|
+
const lerp = (t, a, b) => a + t * (b - a);
|
|
136
|
+
|
|
137
|
+
// Enhanced gradient function for 2D
|
|
138
|
+
const grad2D = (hash, x, y) => {
|
|
139
|
+
const h = hash & 15;
|
|
140
|
+
const u = h < 8 ? x : y;
|
|
141
|
+
const v = h < 4 ? y : (h === 12 || h === 14 ? x : 0);
|
|
142
|
+
return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// 1D gradient (kept for backward compatibility)
|
|
146
|
+
const grad1D = (hash, x) => (hash & 1 ? -x : x);
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
// Original 1D Perlin noise function
|
|
150
|
+
perlin1(x) {
|
|
151
|
+
const X = Math.floor(x) & 255;
|
|
152
|
+
x -= Math.floor(x);
|
|
153
|
+
const u = fade(x);
|
|
154
|
+
return lerp(u, grad1D(p[X], x), grad1D(p[X + 1], x - 1));
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// New 2D Perlin noise function
|
|
158
|
+
perlin2(x, y) {
|
|
159
|
+
// Integer parts
|
|
160
|
+
const X = Math.floor(x) & 255;
|
|
161
|
+
const Y = Math.floor(y) & 255;
|
|
162
|
+
|
|
163
|
+
// Fractional parts
|
|
164
|
+
x -= Math.floor(x);
|
|
165
|
+
y -= Math.floor(y);
|
|
166
|
+
|
|
167
|
+
// Fade curves
|
|
168
|
+
const u = fade(x);
|
|
169
|
+
const v = fade(y);
|
|
170
|
+
|
|
171
|
+
// Hash coordinates of the 4 corners
|
|
172
|
+
const A = p[X] + Y;
|
|
173
|
+
const B = p[X + 1] + Y;
|
|
174
|
+
const AA = p[A];
|
|
175
|
+
const AB = p[A + 1];
|
|
176
|
+
const BA = p[B];
|
|
177
|
+
const BB = p[B + 1];
|
|
178
|
+
|
|
179
|
+
// Blend the four corner gradients
|
|
180
|
+
return lerp(
|
|
181
|
+
v,
|
|
182
|
+
lerp(u, grad2D(p[AA], x, y), grad2D(p[BA], x - 1, y)),
|
|
183
|
+
lerp(u, grad2D(p[AB], x, y - 1), grad2D(p[BB], x - 1, y - 1))
|
|
203
184
|
);
|
|
204
|
-
|
|
205
|
-
// Snap to target if very close
|
|
206
|
-
if (Math.abs(this.lerpFactor - this.targetLerpFactor) < 0.001) {
|
|
207
|
-
this.lerpFactor = this.targetLerpFactor;
|
|
208
|
-
}
|
|
209
185
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#lerp(a, b, t) {
|
|
190
|
+
return a + t * (b - a);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
animate = () => {
|
|
194
|
+
// Update lerp factor towards target
|
|
195
|
+
if (this.lerpFactor !== this.targetLerpFactor) {
|
|
196
|
+
this.lerpFactor = this.#lerp(this.lerpFactor, this.targetLerpFactor, this.lerpSpeed);
|
|
197
|
+
|
|
198
|
+
// Snap to target if very close
|
|
199
|
+
if (Math.abs(this.lerpFactor - this.targetLerpFactor) < 0.001) {
|
|
200
|
+
this.lerpFactor = this.targetLerpFactor;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Only update time if not completely paused
|
|
205
|
+
if (this.lerpFactor > 0) {
|
|
206
|
+
// Scale time increment by lerp factor for smooth speed transition
|
|
207
|
+
this.time += this.speed * this.lerpFactor;
|
|
208
|
+
|
|
209
|
+
// 2D Perlin noise for more natural movement
|
|
210
|
+
const noiseX = this.noise.perlin2(this.time, 0);
|
|
211
|
+
const noiseY = this.noise.perlin2(this.time, 100); // Different slice
|
|
212
|
+
|
|
213
|
+
// Only process if we have an element
|
|
214
|
+
if (this.el) {
|
|
215
|
+
let minX, maxX, minY, maxY;
|
|
216
|
+
|
|
217
|
+
// Get parent dimensions for percentage calculations if needed
|
|
218
|
+
if (this.hasPercentages) {
|
|
219
|
+
const parent = this.el.parentElement || document.body;
|
|
220
|
+
const parentWidth = parent.clientWidth;
|
|
221
|
+
const parentHeight = parent.clientHeight;
|
|
222
|
+
|
|
223
|
+
// Convert percentage values to pixels if needed
|
|
224
|
+
if (this.xRange) {
|
|
225
|
+
minX = PerlinDOM.#isPercentage(this.xRange.min)
|
|
226
|
+
? PerlinDOM.#percentToPixels(this.xRange.min, parentWidth)
|
|
227
|
+
: this.xRange.min;
|
|
228
|
+
|
|
229
|
+
maxX = PerlinDOM.#isPercentage(this.xRange.max)
|
|
230
|
+
? PerlinDOM.#percentToPixels(this.xRange.max, parentWidth)
|
|
231
|
+
: this.xRange.max;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (this.yRange) {
|
|
235
|
+
minY = PerlinDOM.#isPercentage(this.yRange.min)
|
|
236
|
+
? PerlinDOM.#percentToPixels(this.yRange.min, parentHeight)
|
|
237
|
+
: this.yRange.min;
|
|
238
|
+
|
|
239
|
+
maxY = PerlinDOM.#isPercentage(this.yRange.max)
|
|
240
|
+
? PerlinDOM.#percentToPixels(this.yRange.max, parentHeight)
|
|
241
|
+
: this.yRange.max;
|
|
258
242
|
}
|
|
259
|
-
|
|
260
|
-
// Calculate the actual pixel values
|
|
261
|
-
const valX = this.xRange
|
|
262
|
-
? this.#map(noiseX, -1, 1, minX, maxX)
|
|
263
|
-
: 0;
|
|
264
|
-
|
|
265
|
-
const valY = this.yRange
|
|
266
|
-
? this.#map(noiseY, -1, 1, minY, maxY)
|
|
267
|
-
: 0;
|
|
268
|
-
|
|
269
|
-
// Store current values for interpolation
|
|
270
|
-
this.lastX = valX;
|
|
271
|
-
this.lastY = valY;
|
|
272
|
-
|
|
273
|
-
// Update position using transform for better performance
|
|
274
|
-
this.el.style.transform = `translate3d(${valX}px, ${valY}px, 0)`;
|
|
275
243
|
} else {
|
|
276
|
-
//
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const valY = this.yRange
|
|
282
|
-
? this.#map(noiseY, -1, 1, this.yRange.min, this.yRange.max)
|
|
283
|
-
: 0;
|
|
284
|
-
|
|
285
|
-
// Store current values for interpolation
|
|
286
|
-
this.lastX = valX;
|
|
287
|
-
this.lastY = valY;
|
|
244
|
+
// Use original values if not using percentages
|
|
245
|
+
minX = this.xRange?.min;
|
|
246
|
+
maxX = this.xRange?.max;
|
|
247
|
+
minY = this.yRange?.min;
|
|
248
|
+
maxY = this.yRange?.max;
|
|
288
249
|
}
|
|
250
|
+
|
|
251
|
+
// Calculate pixel values
|
|
252
|
+
const valX = this.xRange ? this.#map(noiseX, -1, 1, minX, maxX) : 0;
|
|
253
|
+
const valY = this.yRange ? this.#map(noiseY, -1, 1, minY, maxY) : 0;
|
|
254
|
+
|
|
255
|
+
// Store current values for potential external use
|
|
256
|
+
this.lastX = valX;
|
|
257
|
+
this.lastY = valY;
|
|
258
|
+
|
|
259
|
+
// Compose translate3d with the base transform (scale/rotate/skew)
|
|
260
|
+
// Orden: primero translate (nuestro movimiento), luego el transform base del diseño
|
|
261
|
+
this.el.style.transform = `translate3d(${valX}px, ${valY}px, 0) ${this.baseTransform}`.trim();
|
|
262
|
+
} else {
|
|
263
|
+
// If no element, just calculate and store the values
|
|
264
|
+
const valX = this.xRange ? this.#map(noiseX, -1, 1, this.xRange.min, this.xRange.max) : 0;
|
|
265
|
+
const valY = this.yRange ? this.#map(noiseY, -1, 1, this.yRange.min, this.yRange.max) : 0;
|
|
266
|
+
|
|
267
|
+
this.lastX = valX;
|
|
268
|
+
this.lastY = valY;
|
|
289
269
|
}
|
|
290
|
-
|
|
291
|
-
// Continue animation if not completely paused or still transitioning
|
|
292
|
-
if (this.lerpFactor > 0 || this.targetLerpFactor > 0) {
|
|
293
|
-
this.raf = requestAnimationFrame(this.animate);
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
#map(n, inMin, inMax, outMin, outMax) {
|
|
298
|
-
return ((n - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
|
|
299
270
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
271
|
+
|
|
272
|
+
// Continue animation if not completely paused or still transitioning
|
|
273
|
+
if (this.lerpFactor > 0 || this.targetLerpFactor > 0) {
|
|
274
|
+
this.raf = requestAnimationFrame(this.animate);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
#map(n, inMin, inMax, outMin, outMax) {
|
|
279
|
+
return ((n - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Quita o preserva la traslación del transform base en 2D según flag
|
|
283
|
+
#extractBaseTransform(transformValue, preserveTranslation = false) {
|
|
284
|
+
if (!transformValue || transformValue === 'none') return '';
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const m = new DOMMatrixReadOnly(transformValue);
|
|
288
|
+
if (m.is2D) {
|
|
289
|
+
// matrix(a, b, c, d, e, f) -> rearmamos con e,f = 0 si NO preservamos traslación
|
|
290
|
+
const e = preserveTranslation ? m.e : 0;
|
|
291
|
+
const f = preserveTranslation ? m.f : 0;
|
|
292
|
+
return `matrix(${m.a}, ${m.b}, ${m.c}, ${m.d}, ${e}, ${f})`;
|
|
293
|
+
} else {
|
|
294
|
+
// 3D: lo dejamos tal cual (remover traslación en 3D requiere descomposición)
|
|
295
|
+
return transformValue;
|
|
307
296
|
}
|
|
297
|
+
} catch {
|
|
298
|
+
// Fallback si DOMMatrix no está disponible o hay un valor raro
|
|
299
|
+
return transformValue;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
destroy() {
|
|
304
|
+
cancelAnimationFrame(this.raf);
|
|
305
|
+
|
|
306
|
+
// Restaurar transform inline original
|
|
307
|
+
if (this.el) {
|
|
308
|
+
this.el.style.transform = this.originalInlineTransform || '';
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Remove resize listener if it was added
|
|
312
|
+
if (this.hasPercentages) {
|
|
313
|
+
window.removeEventListener('resize', this.handleResize);
|
|
308
314
|
}
|
|
309
315
|
}
|
|
310
|
-
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export default PerlinDOM;
|