iobroker.mywebui 1.42.1 → 1.42.2
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/package.json
CHANGED
|
@@ -6,6 +6,8 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
6
6
|
<div id="editor-container" style="width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden;">
|
|
7
7
|
<div id="toolbar" style="height:40px;background:#2a2a2a;border-bottom:1px solid #444;display:flex;align-items:center;padding:0 10px;gap:10px;">
|
|
8
8
|
<button id="saveBtn" style="padding:5px 15px;background:#0078d4;color:white;border:none;cursor:pointer;border-radius:3px;">Save</button>
|
|
9
|
+
<button id="addAssetBtn" style="padding:5px 15px;background:#28a745;color:white;border:none;cursor:pointer;border-radius:3px;">+ Add Asset</button>
|
|
10
|
+
<input id="fileInput" type="file" accept=".glb,.gltf,.fbx,.obj" style="display:none;">
|
|
9
11
|
<button id="undoBtn" style="padding:5px 15px;background:#444;color:#aaa;border:none;cursor:pointer;border-radius:3px;">↶ Undo</button>
|
|
10
12
|
<button id="redoBtn" style="padding:5px 15px;background:#444;color:#aaa;border:none;cursor:pointer;border-radius:3px;">↷ Redo</button>
|
|
11
13
|
<div style="flex:1;"></div>
|
|
@@ -13,9 +15,15 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
13
15
|
<button id="axesToggle" style="padding:5px 10px;background:#444;color:#aaa;border:none;cursor:pointer;border-radius:3px;">Axes</button>
|
|
14
16
|
</div>
|
|
15
17
|
<div id="mainContent" style="flex:1;display:flex;overflow:hidden;">
|
|
16
|
-
<div id="leftPanel" style="width:
|
|
17
|
-
<div style="
|
|
18
|
-
|
|
18
|
+
<div id="leftPanel" style="width:280px;background:#1e1e1e;border-right:1px solid #444;overflow:auto;display:flex;flex-direction:column;">
|
|
19
|
+
<div style="display:flex;border-bottom:1px solid #444;">
|
|
20
|
+
<button id="treeTab" style="flex:1;padding:10px;background:#2a2a2a;color:#0f0;border:none;cursor:pointer;font-weight:bold;">Scene</button>
|
|
21
|
+
<button id="assetsTab" style="flex:1;padding:10px;background:#1e1e1e;color:#aaa;border:none;cursor:pointer;">Assets</button>
|
|
22
|
+
</div>
|
|
23
|
+
<div id="sceneTree" style="padding:10px;flex:1;overflow:auto;"></div>
|
|
24
|
+
<div id="assetsList" style="padding:10px;flex:1;overflow:auto;display:none;">
|
|
25
|
+
<div id="assetsListContent" style="color:#aaa;font-size:12px;">No assets loaded</div>
|
|
26
|
+
</div>
|
|
19
27
|
</div>
|
|
20
28
|
<div id="viewport" style="flex:1;background:#333;position:relative;overflow:hidden;"></div>
|
|
21
29
|
<div id="rightPanel" style="width:300px;background:#1e1e1e;border-left:1px solid #444;overflow:auto;">
|
|
@@ -428,10 +436,14 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
428
436
|
|
|
429
437
|
setupEventListeners() {
|
|
430
438
|
this._getDomElement('saveBtn').addEventListener('click', () => this.saveScene());
|
|
439
|
+
this._getDomElement('addAssetBtn').addEventListener('click', () => this.onAddAssetClick());
|
|
440
|
+
this._getDomElement('fileInput').addEventListener('change', (e) => this.onFileSelected(e));
|
|
431
441
|
this._getDomElement('undoBtn').addEventListener('click', () => console.log('Undo'));
|
|
432
442
|
this._getDomElement('redoBtn').addEventListener('click', () => console.log('Redo'));
|
|
433
443
|
this._getDomElement('gridToggle').addEventListener('click', () => this.toggleGrid());
|
|
434
444
|
this._getDomElement('axesToggle').addEventListener('click', () => this.toggleAxes());
|
|
445
|
+
this._getDomElement('treeTab').addEventListener('click', () => this.switchTab('tree'));
|
|
446
|
+
this._getDomElement('assetsTab').addEventListener('click', () => this.switchTab('assets'));
|
|
435
447
|
}
|
|
436
448
|
|
|
437
449
|
async saveScene() {
|
|
@@ -469,6 +481,96 @@ export class IobrokerWebui3DScreenEditor extends BaseCustomWebComponentConstruct
|
|
|
469
481
|
this.renderer.setSize(width, height);
|
|
470
482
|
}
|
|
471
483
|
|
|
484
|
+
onAddAssetClick() {
|
|
485
|
+
this._getDomElement('fileInput').click();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
onFileSelected(event) {
|
|
489
|
+
const file = event.target.files[0];
|
|
490
|
+
if (!file) return;
|
|
491
|
+
|
|
492
|
+
const reader = new FileReader();
|
|
493
|
+
reader.onload = (e) => {
|
|
494
|
+
const arrayBuffer = e.target.result;
|
|
495
|
+
const blob = new Blob([arrayBuffer]);
|
|
496
|
+
const url = URL.createObjectURL(blob);
|
|
497
|
+
|
|
498
|
+
// Create asset object
|
|
499
|
+
const assetId = 'asset_' + Date.now().toString(36);
|
|
500
|
+
const asset = {
|
|
501
|
+
id: assetId,
|
|
502
|
+
name: file.name,
|
|
503
|
+
type: 'model',
|
|
504
|
+
glbPath: url,
|
|
505
|
+
position: { x: 0, y: 0, z: 0 },
|
|
506
|
+
rotation: { x: 0, y: 0, z: 0 },
|
|
507
|
+
scale: { x: 1, y: 1, z: 1 },
|
|
508
|
+
visible: true
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
// Add to scene data
|
|
512
|
+
if (!this.sceneData.assets) {
|
|
513
|
+
this.sceneData.assets = [];
|
|
514
|
+
}
|
|
515
|
+
this.sceneData.assets.push(asset);
|
|
516
|
+
|
|
517
|
+
// Load and add to scene
|
|
518
|
+
this.loadAsset(asset);
|
|
519
|
+
|
|
520
|
+
// Update assets list
|
|
521
|
+
this.updateAssetsList();
|
|
522
|
+
|
|
523
|
+
console.log('✅ Asset added:', file.name);
|
|
524
|
+
};
|
|
525
|
+
reader.readAsArrayBuffer(file);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
switchTab(tab) {
|
|
529
|
+
const sceneTree = this._getDomElement('sceneTree');
|
|
530
|
+
const assetsList = this._getDomElement('assetsList');
|
|
531
|
+
const treeTab = this._getDomElement('treeTab');
|
|
532
|
+
const assetsTab = this._getDomElement('assetsTab');
|
|
533
|
+
|
|
534
|
+
if (tab === 'tree') {
|
|
535
|
+
sceneTree.style.display = 'block';
|
|
536
|
+
assetsList.style.display = 'none';
|
|
537
|
+
treeTab.style.background = '#2a2a2a';
|
|
538
|
+
treeTab.style.color = '#0f0';
|
|
539
|
+
assetsTab.style.background = '#1e1e1e';
|
|
540
|
+
assetsTab.style.color = '#aaa';
|
|
541
|
+
} else {
|
|
542
|
+
sceneTree.style.display = 'none';
|
|
543
|
+
assetsList.style.display = 'block';
|
|
544
|
+
treeTab.style.background = '#1e1e1e';
|
|
545
|
+
treeTab.style.color = '#aaa';
|
|
546
|
+
assetsTab.style.background = '#2a2a2a';
|
|
547
|
+
assetsTab.style.color = '#0f0';
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
updateAssetsList() {
|
|
552
|
+
const assetsListContent = this._getDomElement('assetsListContent');
|
|
553
|
+
|
|
554
|
+
if (!this.sceneData.assets || this.sceneData.assets.length === 0) {
|
|
555
|
+
assetsListContent.innerHTML = '<div style="color:#888;">No assets loaded</div>';
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
let html = '';
|
|
560
|
+
for (const asset of this.sceneData.assets) {
|
|
561
|
+
html += `
|
|
562
|
+
<div style="padding:8px;background:#242424;margin-bottom:5px;border-radius:3px;cursor:pointer;border:1px solid #333;">
|
|
563
|
+
<div style="color:#0f0;font-weight:bold;">${asset.name}</div>
|
|
564
|
+
<div style="color:#888;font-size:11px;margin-top:3px;">
|
|
565
|
+
Type: ${asset.type}<br>
|
|
566
|
+
Pos: (${asset.position.x.toFixed(1)}, ${asset.position.y.toFixed(1)}, ${asset.position.z.toFixed(1)})
|
|
567
|
+
</div>
|
|
568
|
+
</div>
|
|
569
|
+
`;
|
|
570
|
+
}
|
|
571
|
+
assetsListContent.innerHTML = html;
|
|
572
|
+
}
|
|
573
|
+
|
|
472
574
|
disconnectedCallback() {
|
|
473
575
|
if (this.renderer) {
|
|
474
576
|
this.renderer.dispose();
|