iobroker.mywebui 1.37.95 → 1.37.97
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/io-package.json
CHANGED
package/package.json
CHANGED
|
@@ -32,6 +32,62 @@ function findElementAcrossShadows(fromElement, id) {
|
|
|
32
32
|
// AnimationService.js is at dist/frontend/runtime/ → ../../vendor/gsap/ = dist/vendor/gsap/
|
|
33
33
|
const _gsapBase = new URL('../../vendor/gsap/', import.meta.url).href;
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Convert circle/ellipse/rect/polyline/polygon to SVG path data string.
|
|
37
|
+
* GSAP MotionPathPlugin only accepts <path> elements — other SVG shapes must be converted.
|
|
38
|
+
*/
|
|
39
|
+
function svgShapeToPathData(el) {
|
|
40
|
+
const tag = el.tagName.toLowerCase();
|
|
41
|
+
if (tag === 'circle') {
|
|
42
|
+
const cx = parseFloat(el.getAttribute('cx') || 0);
|
|
43
|
+
const cy = parseFloat(el.getAttribute('cy') || 0);
|
|
44
|
+
const r = parseFloat(el.getAttribute('r') || 0);
|
|
45
|
+
return `M ${cx-r},${cy} A ${r},${r} 0 1,1 ${cx+r},${cy} A ${r},${r} 0 1,1 ${cx-r},${cy} Z`;
|
|
46
|
+
}
|
|
47
|
+
if (tag === 'ellipse') {
|
|
48
|
+
const cx = parseFloat(el.getAttribute('cx') || 0);
|
|
49
|
+
const cy = parseFloat(el.getAttribute('cy') || 0);
|
|
50
|
+
const rx = parseFloat(el.getAttribute('rx') || 0);
|
|
51
|
+
const ry = parseFloat(el.getAttribute('ry') || 0);
|
|
52
|
+
return `M ${cx-rx},${cy} A ${rx},${ry} 0 1,1 ${cx+rx},${cy} A ${rx},${ry} 0 1,1 ${cx-rx},${cy} Z`;
|
|
53
|
+
}
|
|
54
|
+
if (tag === 'rect') {
|
|
55
|
+
const x = parseFloat(el.getAttribute('x') || 0);
|
|
56
|
+
const y = parseFloat(el.getAttribute('y') || 0);
|
|
57
|
+
const w = parseFloat(el.getAttribute('width') || 0);
|
|
58
|
+
const h = parseFloat(el.getAttribute('height') || 0);
|
|
59
|
+
return `M ${x},${y} H ${x+w} V ${y+h} H ${x} Z`;
|
|
60
|
+
}
|
|
61
|
+
if (tag === 'polyline' || tag === 'polygon') {
|
|
62
|
+
const pts = (el.getAttribute('points') || '').trim().split(/[\s,]+/);
|
|
63
|
+
if (pts.length < 2) return null;
|
|
64
|
+
let d = `M ${pts[0]},${pts[1]}`;
|
|
65
|
+
for (let i = 2; i + 1 < pts.length; i += 2) d += ` L ${pts[i]},${pts[i+1]}`;
|
|
66
|
+
if (tag === 'polygon') d += ' Z';
|
|
67
|
+
return d;
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Ensure we have a real SVG <path> element for GSAP MotionPathPlugin.
|
|
74
|
+
* If el is already a <path>, returns it directly.
|
|
75
|
+
* Otherwise converts the shape to path data and creates a temporary hidden <path>
|
|
76
|
+
* inside the same <svg>. Caller must store _tempPathEl and remove it on destroy.
|
|
77
|
+
*/
|
|
78
|
+
function ensurePathEl(el) {
|
|
79
|
+
if (el.tagName.toLowerCase() === 'path') return { pathEl: el, tempEl: null };
|
|
80
|
+
const d = svgShapeToPathData(el);
|
|
81
|
+
if (!d) return { pathEl: el, tempEl: null };
|
|
82
|
+
const svgParent = el.closest('svg') ?? el.parentElement;
|
|
83
|
+
const tmp = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
84
|
+
tmp.setAttribute('d', d);
|
|
85
|
+
tmp.setAttribute('fill', 'none');
|
|
86
|
+
tmp.style.cssText = 'visibility:hidden;pointer-events:none;';
|
|
87
|
+
svgParent.appendChild(tmp);
|
|
88
|
+
return { pathEl: tmp, tempEl: tmp };
|
|
89
|
+
}
|
|
90
|
+
|
|
35
91
|
async function ensureGSAP() {
|
|
36
92
|
if (window.gsap) return window.gsap;
|
|
37
93
|
if (_gsapLoadPromise) return _gsapLoadPromise;
|
|
@@ -440,11 +496,15 @@ class AnimationInstance {
|
|
|
440
496
|
const effect = this.cfg.effect;
|
|
441
497
|
|
|
442
498
|
if (effect === 'motionPath' && this.cfg.pathId) {
|
|
443
|
-
let
|
|
444
|
-
if (!
|
|
445
|
-
// If ID is on <svg> container, use the first
|
|
446
|
-
if (
|
|
447
|
-
|
|
499
|
+
let found = findElementAcrossShadows(this.element, this.cfg.pathId);
|
|
500
|
+
if (!found) { console.warn('[AnimationService] motionPath: path element not found:', this.cfg.pathId); return; }
|
|
501
|
+
// If ID is on <svg> container, use the first shape inside it
|
|
502
|
+
if (found.tagName.toLowerCase() === 'svg')
|
|
503
|
+
found = found.querySelector('path, circle, ellipse, rect, polyline, polygon') ?? found;
|
|
504
|
+
// GSAP MotionPathPlugin only accepts <path> — convert other shapes to a hidden <path>
|
|
505
|
+
if (this._tempPathEl) { this._tempPathEl.remove(); this._tempPathEl = null; }
|
|
506
|
+
const { pathEl, tempEl } = ensurePathEl(found);
|
|
507
|
+
this._tempPathEl = tempEl;
|
|
448
508
|
this.tween = gsap.to(this.element, {
|
|
449
509
|
duration: parseFloat(this.cfg.duration) || 1,
|
|
450
510
|
ease: this.cfg.ease || 'none',
|
|
@@ -479,6 +539,7 @@ class AnimationInstance {
|
|
|
479
539
|
|
|
480
540
|
destroy() {
|
|
481
541
|
if (this.tween) { this.tween.kill(); this.tween = null; }
|
|
542
|
+
if (this._tempPathEl) { this._tempPathEl.remove(); this._tempPathEl = null; }
|
|
482
543
|
_cleanupSubs(this._subs);
|
|
483
544
|
}
|
|
484
545
|
}
|