Model library: remembered GLBs with one-click switching
Every loaded model (GLB or converted FBX) is added to 'I miei modelli' in the Animazioni 3D tab: click a name to switch the dancer instantly (active one highlighted), x removes it from the list (file untouched). Persisted in localStorage; the current model is seeded on first run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
06ae7bc422
commit
a8da0a4c9d
3 files changed
+80
-1
No files matched your search
@@ -167,6 +167,8 @@
|
|||||||
<input type="file" id="glb-input" accept=".glb,.fbx" hidden />
|
<input type="file" id="glb-input" accept=".glb,.fbx" hidden />
|
||||||
<div class="hint-mini" id="glb-name">Il modello ruota e balla a tempo di musica nella famiglia “Modello 3D”;
|
<div class="hint-mini" id="glb-name">Il modello ruota e balla a tempo di musica nella famiglia “Modello 3D”;
|
||||||
con la camera lo comandi in “Interattivo Avatar”.</div>
|
con la camera lo comandi in “Interattivo Avatar”.</div>
|
||||||
|
<label>I miei modelli</label>
|
||||||
|
<div id="glb-models" class="glb-models"></div>
|
||||||
<label>Sfondo</label>
|
<label>Sfondo</label>
|
||||||
<select id="glb-bg">
|
<select id="glb-bg">
|
||||||
<option value="gradient">Gradiente</option>
|
<option value="gradient">Gradiente</option>
|
||||||
|
|||||||
+51
-1
@@ -186,12 +186,61 @@ function renderGlbClips(names) {
|
|||||||
box.appendChild(l);
|
box.appendChild(l);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Model library: every loaded model is remembered for one-click switching.
|
||||||
|
let glbModels = [];
|
||||||
|
try { glbModels = JSON.parse(localStorage.getItem('glbmodels') || '[]'); } catch (e) {}
|
||||||
|
function saveGlbModels() { localStorage.setItem('glbmodels', JSON.stringify(glbModels)); }
|
||||||
|
function addGlbModel(name, p) {
|
||||||
|
const i = glbModels.findIndex(m => m.path === p);
|
||||||
|
if (i < 0) glbModels.push({ name, path: p }); else glbModels[i].name = name;
|
||||||
|
saveGlbModels();
|
||||||
|
renderGlbModels();
|
||||||
|
}
|
||||||
|
function renderGlbModels() {
|
||||||
|
const box = $('#glb-models');
|
||||||
|
box.innerHTML = '';
|
||||||
|
if (!glbModels.length) {
|
||||||
|
box.innerHTML = '<span class="hint-mini">I modelli caricati appariranno qui per il cambio rapido.</span>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glbModels.forEach((mo) => {
|
||||||
|
const row = document.createElement('div');
|
||||||
|
row.className = 'glb-model' + (mo.path === glbPath ? ' on' : '');
|
||||||
|
const nm = document.createElement('span');
|
||||||
|
nm.className = 'gm-name';
|
||||||
|
nm.textContent = mo.name;
|
||||||
|
nm.title = mo.path;
|
||||||
|
nm.addEventListener('click', () => {
|
||||||
|
glbPath = mo.path;
|
||||||
|
localStorage.setItem('glb3d', glbPath);
|
||||||
|
send({ type: 'glb', path: glbPath });
|
||||||
|
glbLabel(mo.name);
|
||||||
|
renderGlbModels();
|
||||||
|
});
|
||||||
|
const del = document.createElement('button');
|
||||||
|
del.className = 'gm-del';
|
||||||
|
del.textContent = '✕';
|
||||||
|
del.title = 'Togli dalla lista (il file resta sul disco)';
|
||||||
|
del.addEventListener('click', () => {
|
||||||
|
glbModels = glbModels.filter(x => x.path !== mo.path);
|
||||||
|
saveGlbModels();
|
||||||
|
renderGlbModels();
|
||||||
|
});
|
||||||
|
row.appendChild(nm);
|
||||||
|
row.appendChild(del);
|
||||||
|
box.appendChild(row);
|
||||||
|
});
|
||||||
|
}
|
||||||
function glbLabel(name) {
|
function glbLabel(name) {
|
||||||
$('#glb-name').textContent = name
|
$('#glb-name').textContent = name
|
||||||
? '🧊 ' + name + ' — attiva la famiglia “Modello 3D” per vederlo.'
|
? '🧊 ' + name + ' — attiva la famiglia “Modello 3D” per vederlo.'
|
||||||
: 'Il modello ruota a tempo di musica nella famiglia “Modello 3D”.';
|
: 'Il modello ruota a tempo di musica nella famiglia “Modello 3D”.';
|
||||||
}
|
}
|
||||||
if (glbPath) glbLabel(glbPath.split('/').pop());
|
if (glbPath) {
|
||||||
|
glbLabel(glbPath.split('/').pop());
|
||||||
|
if (!glbModels.some(m => m.path === glbPath)) addGlbModel(glbPath.split('/').pop(), glbPath);
|
||||||
|
}
|
||||||
|
renderGlbModels();
|
||||||
// every shader family can be a backdrop too (fluid/interactive/3D excluded:
|
// every shader family can be a backdrop too (fluid/interactive/3D excluded:
|
||||||
// fluids are the explicit options above, the others can't render as layers)
|
// fluids are the explicit options above, the others can't render as layers)
|
||||||
EFFECTS.families.forEach((name, fi) => {
|
EFFECTS.families.forEach((name, fi) => {
|
||||||
@@ -307,6 +356,7 @@ $('#glb-input').addEventListener('change', async (e) => {
|
|||||||
localStorage.setItem('glb3d', p);
|
localStorage.setItem('glb3d', p);
|
||||||
glbSend();
|
glbSend();
|
||||||
glbLabel(f.name.replace(/\.fbx$/i, '.glb'));
|
glbLabel(f.name.replace(/\.fbx$/i, '.glb'));
|
||||||
|
addGlbModel(f.name.replace(/\.fbx$/i, '.glb'), p);
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- Effect sequence (playlist of effects with auto-cycle) ---
|
// --- Effect sequence (playlist of effects with auto-cycle) ---
|
||||||
|
|||||||
@@ -850,3 +850,30 @@ kbd {
|
|||||||
accent-color: #4caf50;
|
accent-color: #4caf50;
|
||||||
}
|
}
|
||||||
#glb-anims .hint-mini { grid-column: 1 / -1; }
|
#glb-anims .hint-mini { grid-column: 1 / -1; }
|
||||||
|
|
||||||
|
/* Model library: remembered GLBs for one-click switching */
|
||||||
|
.glb-models { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 10px; }
|
||||||
|
.glb-model {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 5px 8px;
|
||||||
|
border: 1px solid #444;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 11.5px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.glb-model.on { border-color: #7aa2ff; background: rgba(110,150,255,0.14); opacity: 1; }
|
||||||
|
.glb-model .gm-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
|
.glb-model .gm-del {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: auto;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #ff8a8a;
|
||||||
|
padding: 0 2px;
|
||||||
|
font-size: 11px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
.glb-models .hint-mini { grid-column: 1 / -1; }
|
||||||
Reference in new issue
Block a user