@vanduo-oss/framework 1.3.4 → 1.3.5
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/LICENSE +0 -14
- package/README.md +33 -176
- package/css/components/tooltips.css +8 -8
- package/css/effects/morph.css +259 -0
- package/css/vanduo.css +1 -0
- package/dist/build-info.json +3 -3
- package/dist/vanduo.cjs.js +113 -2
- package/dist/vanduo.cjs.js.map +3 -3
- package/dist/vanduo.cjs.min.js +4 -4
- package/dist/vanduo.cjs.min.js.map +4 -4
- package/dist/vanduo.css +241 -9
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +113 -2
- package/dist/vanduo.esm.js.map +3 -3
- package/dist/vanduo.esm.min.js +4 -4
- package/dist/vanduo.esm.min.js.map +4 -4
- package/dist/vanduo.js +113 -2
- package/dist/vanduo.js.map +3 -3
- package/dist/vanduo.min.css +2 -2
- package/dist/vanduo.min.css.map +1 -1
- package/dist/vanduo.min.js +4 -4
- package/dist/vanduo.min.js.map +4 -4
- package/js/components/morph.js +137 -0
- package/js/index.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanduo Framework - Water Morph Effect Component
|
|
3
|
+
* Liquid wave content-swap animation on click
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* Add .vd-morph or [data-vd-morph] to any element.
|
|
7
|
+
* Provide .vd-morph-content.vd-morph-current and .vd-morph-content.vd-morph-next children.
|
|
8
|
+
* Wave and shine layers are auto-created if absent.
|
|
9
|
+
*
|
|
10
|
+
* JS API:
|
|
11
|
+
* VanduoMorph.morph(el) — trigger morph programmatically (from center)
|
|
12
|
+
* VanduoMorph.destroy(el) — tear down listeners for one element
|
|
13
|
+
* VanduoMorph.destroyAll() — tear down all instances
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
(function () {
|
|
17
|
+
'use strict';
|
|
18
|
+
|
|
19
|
+
const MORPH_DURATION_MS = 750;
|
|
20
|
+
|
|
21
|
+
const Morph = {
|
|
22
|
+
instances: new Map(),
|
|
23
|
+
|
|
24
|
+
init: function () {
|
|
25
|
+
const elements = document.querySelectorAll('.vd-morph, [data-vd-morph]');
|
|
26
|
+
elements.forEach(function (el) {
|
|
27
|
+
if (Morph.instances.has(el)) return;
|
|
28
|
+
if (el.getAttribute('data-vd-morph') === 'manual') return;
|
|
29
|
+
Morph.initInstance(el);
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
initInstance: function (el) {
|
|
34
|
+
Morph._ensureLayers(el);
|
|
35
|
+
|
|
36
|
+
const cleanup = [];
|
|
37
|
+
let morphing = false;
|
|
38
|
+
|
|
39
|
+
const handleClick = function (e) {
|
|
40
|
+
if (morphing) return;
|
|
41
|
+
Morph._runMorph(el, e, function () { morphing = false; });
|
|
42
|
+
morphing = true;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
el.addEventListener('click', handleClick);
|
|
46
|
+
cleanup.push(function () { el.removeEventListener('click', handleClick); });
|
|
47
|
+
|
|
48
|
+
this.instances.set(el, { cleanup: cleanup });
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
morph: function (el) {
|
|
52
|
+
if (!el) return;
|
|
53
|
+
if (!this.instances.has(el)) this.initInstance(el);
|
|
54
|
+
this._runMorph(el, null, null);
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
destroy: function (el) {
|
|
58
|
+
const instance = this.instances.get(el);
|
|
59
|
+
if (!instance) return;
|
|
60
|
+
instance.cleanup.forEach(function (fn) { fn(); });
|
|
61
|
+
this.instances.delete(el);
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
destroyAll: function () {
|
|
65
|
+
this.instances.forEach(function (_, el) { Morph.destroy(el); });
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
/* ── Internal helpers ── */
|
|
69
|
+
|
|
70
|
+
_ensureLayers: function (el) {
|
|
71
|
+
if (!el.querySelector('.vd-morph-wave')) {
|
|
72
|
+
const wave = document.createElement('span');
|
|
73
|
+
wave.className = 'vd-morph-wave';
|
|
74
|
+
wave.setAttribute('aria-hidden', 'true');
|
|
75
|
+
el.insertBefore(wave, el.firstChild);
|
|
76
|
+
}
|
|
77
|
+
if (!el.querySelector('.vd-morph-shine')) {
|
|
78
|
+
const shine = document.createElement('span');
|
|
79
|
+
shine.className = 'vd-morph-shine';
|
|
80
|
+
shine.setAttribute('aria-hidden', 'true');
|
|
81
|
+
const waveEl = el.querySelector('.vd-morph-wave');
|
|
82
|
+
if (waveEl && waveEl.nextSibling) {
|
|
83
|
+
el.insertBefore(shine, waveEl.nextSibling);
|
|
84
|
+
} else {
|
|
85
|
+
el.insertBefore(shine, el.firstChild);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
_runMorph: function (el, pointerEvent, onComplete) {
|
|
91
|
+
const wave = el.querySelector('.vd-morph-wave');
|
|
92
|
+
if (wave) {
|
|
93
|
+
const rect = el.getBoundingClientRect();
|
|
94
|
+
const cx = rect.left + rect.width / 2;
|
|
95
|
+
const cy = rect.top + rect.height / 2;
|
|
96
|
+
const px = pointerEvent ? (pointerEvent.clientX || cx) : cx;
|
|
97
|
+
const py = pointerEvent ? (pointerEvent.clientY || cy) : cy;
|
|
98
|
+
wave.style.left = (px - rect.left) + 'px';
|
|
99
|
+
wave.style.top = (py - rect.top) + 'px';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
el.classList.add('is-morphing');
|
|
103
|
+
|
|
104
|
+
let duration = MORPH_DURATION_MS;
|
|
105
|
+
const custom = getComputedStyle(el).getPropertyValue('--morph-duration');
|
|
106
|
+
if (custom) {
|
|
107
|
+
const parsed = parseFloat(custom);
|
|
108
|
+
if (!isNaN(parsed)) duration = parsed * (custom.indexOf('ms') !== -1 ? 1 : 1000);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
setTimeout(function () {
|
|
112
|
+
el.classList.remove('is-morphing');
|
|
113
|
+
|
|
114
|
+
const current = el.querySelector('.vd-morph-current');
|
|
115
|
+
const next = el.querySelector('.vd-morph-next');
|
|
116
|
+
if (current && next) {
|
|
117
|
+
current.classList.remove('vd-morph-current');
|
|
118
|
+
current.classList.add('vd-morph-next');
|
|
119
|
+
next.classList.remove('vd-morph-next');
|
|
120
|
+
next.classList.add('vd-morph-current');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
el.classList.add('morph-done');
|
|
124
|
+
setTimeout(function () { el.classList.remove('morph-done'); }, 350);
|
|
125
|
+
|
|
126
|
+
if (typeof onComplete === 'function') onComplete();
|
|
127
|
+
}, duration);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
if (typeof window.Vanduo !== 'undefined') {
|
|
132
|
+
window.Vanduo.register('morph', Morph);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
window.VanduoMorph = Morph;
|
|
136
|
+
|
|
137
|
+
})();
|
package/js/index.js
CHANGED
|
@@ -47,8 +47,9 @@ import './components/doc-search.js';
|
|
|
47
47
|
import './components/draggable.js';
|
|
48
48
|
import './components/lazy-load.js';
|
|
49
49
|
|
|
50
|
-
// Effects (glass scroll activation)
|
|
50
|
+
// Effects (glass scroll activation, water morph)
|
|
51
51
|
import './components/glass.js';
|
|
52
|
+
import './components/morph.js';
|
|
52
53
|
|
|
53
54
|
// Phase 10 (v1.2.7) components
|
|
54
55
|
import './components/flow.js';
|