iobroker.mywebui 1.38.2 → 1.38.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/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "mywebui",
4
- "version": "1.38.02",
4
+ "version": "1.38.04",
5
5
  "titleLang": {
6
6
  "en": "mywebui",
7
7
  "de": "mywebui",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.mywebui",
3
- "version": "1.38.02",
3
+ "version": "1.38.04",
4
4
  "description": "ioBroker mywebui - Custom edited mywebui by gokturk413",
5
5
  "type": "module",
6
6
  "main": "dist/backend/main.js",
@@ -1229,7 +1229,9 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
1229
1229
  ['slideInTop','Slide In Top'],['slideInBottom','Slide In Bottom'],
1230
1230
  ['bounce','Bounce'],['pulse','Pulse'],['shake','Shake'],
1231
1231
  ['glow','Glow'],['blur','Blur'],['spin','Spin'],['flip','Flip 3D'],
1232
- ['pulseRing','Pulse Ring']
1232
+ ['pulseRing','Pulse Ring'],
1233
+ ['flowDash','Flow Dash (SVG)'],
1234
+ ['pathFlow','Path Flow Shapes (SVG)']
1233
1235
  ], cfg.type || '');
1234
1236
 
1235
1237
  const triggerSel = sel([
@@ -1252,6 +1254,19 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
1252
1254
  const blurInp = inp(cfg.blurAmount || 5, 'number');
1253
1255
  const pulseScaleInp = inp(cfg.scale ?? 2.5, 'number');
1254
1256
  const pulseOpacityInp= inp(cfg.opacityFrom ?? 1, 'number');
1257
+ // flowDash inputs
1258
+ const flowDashLenInp = inp(cfg.dashLen ?? 10, 'number');
1259
+ const flowGapLenInp = inp(cfg.gapLen ?? 20, 'number');
1260
+ const flowColorInp = inp(cfg.color || '#0066ff', 'color');
1261
+ const flowDirSel = sel([['normal','Forward'],['reverse','Reverse']], cfg.direction || 'normal');
1262
+ // pathFlow inputs
1263
+ const pathFlowShapeSel = sel([
1264
+ ['triangle','Triangle'],['arrow','Arrow'],['circle','Circle'],
1265
+ ['square','Square'],['star','Star'],['dash','Dash']
1266
+ ], cfg.shape || 'triangle');
1267
+ const pathFlowCountInp = inp(cfg.count ?? 5, 'number');
1268
+ const pathFlowSizeInp = inp(cfg.size ?? 8, 'number');
1269
+ const pathFlowColorInp = inp(cfg.color || '#0066ff', 'color');
1255
1270
 
1256
1271
  body.appendChild(field('Type', 'type', typeSel));
1257
1272
  body.appendChild(field('Trigger', null, triggerSel));
@@ -1300,6 +1315,26 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
1300
1315
  body.appendChild(pulseRingSection);
1301
1316
  typeSel.addEventListener('change', () => { pulseRingSection.style.display = typeSel.value === 'pulseRing' ? '' : 'none'; });
1302
1317
 
1318
+ // Flow Dash section
1319
+ const flowDashSection = document.createElement('div');
1320
+ flowDashSection.style.display = cfg.type === 'flowDash' ? '' : 'none';
1321
+ flowDashSection.appendChild(field('Dash Length', 'dashLen', flowDashLenInp));
1322
+ flowDashSection.appendChild(field('Gap Length', 'gapLen', flowGapLenInp));
1323
+ flowDashSection.appendChild(field('Color', 'color', flowColorInp));
1324
+ flowDashSection.appendChild(field('Direction', 'direction', flowDirSel));
1325
+ body.appendChild(flowDashSection);
1326
+ typeSel.addEventListener('change', () => { flowDashSection.style.display = typeSel.value === 'flowDash' ? '' : 'none'; });
1327
+
1328
+ // Path Flow section
1329
+ const pathFlowSection = document.createElement('div');
1330
+ pathFlowSection.style.display = cfg.type === 'pathFlow' ? '' : 'none';
1331
+ pathFlowSection.appendChild(field('Shape', 'shape', pathFlowShapeSel));
1332
+ pathFlowSection.appendChild(field('Count', 'count', pathFlowCountInp));
1333
+ pathFlowSection.appendChild(field('Size', 'size', pathFlowSizeInp));
1334
+ pathFlowSection.appendChild(field('Color', 'color', pathFlowColorInp));
1335
+ body.appendChild(pathFlowSection);
1336
+ typeSel.addEventListener('change', () => { pathFlowSection.style.display = typeSel.value === 'pathFlow' ? '' : 'none'; });
1337
+
1303
1338
  // _collect: read current UI values back into a plain object
1304
1339
  cfg._collect = () => {
1305
1340
  const out = {};
@@ -1313,6 +1348,8 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
1313
1348
  if (typeSel.value === 'glow') { out.glowColor = glowColorInp.value; out.glowSize = parseInt(glowSizeInp.value) || 10; }
1314
1349
  if (typeSel.value === 'blur') out.blurAmount = parseInt(blurInp.value) || 5;
1315
1350
  if (typeSel.value === 'pulseRing') { out.scale = parseFloat(pulseScaleInp.value) || 2.5; out.opacityFrom = parseFloat(pulseOpacityInp.value) ?? 1; }
1351
+ if (typeSel.value === 'flowDash') { out.dashLen = parseFloat(flowDashLenInp.value) || 10; out.gapLen = parseFloat(flowGapLenInp.value) || 20; out.color = flowColorInp.value; out.direction = flowDirSel.value; }
1352
+ if (typeSel.value === 'pathFlow') { out.shape = pathFlowShapeSel.value; out.count = parseInt(pathFlowCountInp.value) || 5; out.size = parseFloat(pathFlowSizeInp.value) || 8; out.color = pathFlowColorInp.value; }
1316
1353
  for (const [k, v] of Object.entries(cfg)) { if (k.endsWith('_bind') && v) out[k] = v; }
1317
1354
  return out;
1318
1355
  };
@@ -58,6 +58,13 @@ function svgShapeToPathData(el) {
58
58
  const h = parseFloat(el.getAttribute('height') || 0);
59
59
  return `M ${x},${y} H ${x+w} V ${y+h} H ${x} Z`;
60
60
  }
61
+ if (tag === 'line') {
62
+ const x1 = el.getAttribute('x1') || 0;
63
+ const y1 = el.getAttribute('y1') || 0;
64
+ const x2 = el.getAttribute('x2') || 0;
65
+ const y2 = el.getAttribute('y2') || 0;
66
+ return `M ${x1},${y1} L ${x2},${y2}`;
67
+ }
61
68
  if (tag === 'polyline' || tag === 'polygon') {
62
69
  const pts = (el.getAttribute('points') || '').trim().split(/[\s,]+/);
63
70
  if (pts.length < 2) return null;
@@ -663,10 +670,87 @@ async function _applyEffect(el, cfg) {
663
670
  { scale, opacity: 0, duration: dur, ease: ringEase, repeat: pulseRepeat, delay, transformOrigin: '50% 50%' }
664
671
  ); break;
665
672
  }
673
+ case 'flowDash': {
674
+ const dashLen = parseFloat(cfg.dashLen) || 10;
675
+ const gapLen = parseFloat(cfg.gapLen) || 20;
676
+ const flowColor = cfg.color || null;
677
+ const flowDir = cfg.direction === 'reverse' ? 'reverse' : 'normal';
678
+ el.style.strokeDasharray = `${dashLen} ${gapLen}`;
679
+ if (flowColor) el.style.stroke = flowColor;
680
+ _flowDashAnim = el.animate(
681
+ [{ strokeDashoffset: dashLen + gapLen }, { strokeDashoffset: 0 }],
682
+ { duration: dur * 1000, iterations: Infinity, easing: 'linear', direction: flowDir, delay: delay * 1000 }
683
+ );
684
+ break;
685
+ }
686
+ case 'pathFlow': {
687
+ const count = parseInt(cfg.count) || 5;
688
+ const shapeType = cfg.shape || 'triangle';
689
+ const flowColor = cfg.color || '#0066ff';
690
+ const size = parseFloat(cfg.size) || 8;
691
+ const svg = el.ownerSVGElement || el.closest('svg');
692
+ if (!svg) break;
693
+ // Convert line/polyline/circle/rect → <path> so GSAP MotionPath works
694
+ const { pathEl: motionPathEl, tempEl: tempMotionEl } = ensurePathEl(el);
695
+ if (tempMotionEl) _pathFlowEls.push(tempMotionEl);
696
+ const svgNS = 'http://www.w3.org/2000/svg';
697
+ const makeShape = () => {
698
+ let s;
699
+ switch (shapeType) {
700
+ case 'triangle':
701
+ s = document.createElementNS(svgNS, 'polygon');
702
+ s.setAttribute('points', `${size},0 0,${-size/2} 0,${size/2}`);
703
+ break;
704
+ case 'arrow':
705
+ s = document.createElementNS(svgNS, 'path');
706
+ s.setAttribute('d', `M${size},0 L0,${-size/2} L${size*0.35},0 L0,${size/2} Z`);
707
+ break;
708
+ case 'circle':
709
+ s = document.createElementNS(svgNS, 'circle');
710
+ s.setAttribute('r', String(size / 2));
711
+ break;
712
+ case 'square':
713
+ s = document.createElementNS(svgNS, 'rect');
714
+ s.setAttribute('width', String(size)); s.setAttribute('height', String(size));
715
+ s.setAttribute('x', String(-size/2)); s.setAttribute('y', String(-size/2));
716
+ break;
717
+ case 'star': {
718
+ s = document.createElementNS(svgNS, 'polygon');
719
+ const pts = [];
720
+ for (let i = 0; i < 10; i++) {
721
+ const r = i % 2 === 0 ? size : size * 0.4;
722
+ const a = (i * Math.PI / 5) - Math.PI / 2;
723
+ pts.push(`${r * Math.cos(a)},${r * Math.sin(a)}`);
724
+ }
725
+ s.setAttribute('points', pts.join(' '));
726
+ break;
727
+ }
728
+ default:
729
+ s = document.createElementNS(svgNS, 'rect');
730
+ s.setAttribute('width', String(size * 2)); s.setAttribute('height', String(size / 3));
731
+ s.setAttribute('x', String(-size)); s.setAttribute('y', String(-size / 6));
732
+ break;
733
+ }
734
+ s.setAttribute('fill', flowColor);
735
+ svg.appendChild(s);
736
+ _pathFlowEls.push(s);
737
+ return s;
738
+ };
739
+ for (let i = 0; i < count; i++) {
740
+ const shape = makeShape();
741
+ gsap.to(shape, {
742
+ motionPath: { path: motionPathEl, align: motionPathEl, autoRotate: true, alignOrigin: [0.5, 0.5], start: i / count, end: (i / count) + 1 },
743
+ duration: dur, repeat: -1, ease: 'none', delay: delay
744
+ });
745
+ }
746
+ break;
747
+ }
666
748
  }
667
749
  };
668
750
 
669
751
  let _hoverFn = null, _clickFn = null;
752
+ let _flowDashAnim = null;
753
+ const _pathFlowEls = [];
670
754
  const effectSubs = [];
671
755
 
672
756
  if (cfg.trigger === 'load') {
@@ -701,5 +785,7 @@ async function _applyEffect(el, cfg) {
701
785
  if (_hoverFn) el.removeEventListener('mouseenter', _hoverFn);
702
786
  if (_clickFn) el.removeEventListener('click', _clickFn);
703
787
  _cleanupSubs(effectSubs);
788
+ if (_flowDashAnim) _flowDashAnim.cancel();
789
+ for (const e of _pathFlowEls) { gsap.killTweensOf(e); e.remove(); }
704
790
  };
705
791
  }