Improve visibility

This commit is contained in:
2025-12-09 16:16:47 +01:00
parent 8ad4f267da
commit 77c2775b7f
3 changed files with 142 additions and 16 deletions

View File

@@ -122,6 +122,12 @@ body {
box-shadow: none;
}
.ghost {
background: transparent;
border: 1px solid #2d3a57;
box-shadow: none;
}
.secondary {
background: #475569;
}
@@ -176,6 +182,12 @@ body {
border-color: rgba(148, 163, 184, 0.2);
}
.badge.danger {
background: rgba(248, 113, 113, 0.12);
color: #fecdd3;
border-color: rgba(248, 113, 113, 0.45);
}
.badge-row {
display: flex;
gap: 8px;
@@ -475,6 +487,29 @@ body {
margin: 0;
}
.selected-asset-banner {
display: grid;
grid-template-columns: 1fr auto;
gap: 12px;
padding: 14px;
border-radius: 12px;
background: linear-gradient(135deg, rgba(124, 58, 237, 0.08), rgba(59, 130, 246, 0.05));
border: 1px solid rgba(124, 58, 237, 0.2);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.selected-asset-main {
display: flex;
flex-direction: column;
gap: 6px;
}
.selected-asset-actions {
display: flex;
align-items: center;
gap: 8px;
}
.panel ul {
list-style: none;
padding: 0;
@@ -560,6 +595,38 @@ body {
gap: 8px;
}
.icon-button {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 10px;
border-radius: 8px;
border: 1px solid rgba(148, 163, 184, 0.25);
background: rgba(255, 255, 255, 0.04);
color: #e2e8f0;
transition: all 0.15s ease;
}
.icon-button .icon {
font-size: 16px;
line-height: 1;
}
.icon-button:hover {
border-color: rgba(124, 58, 237, 0.4);
box-shadow: 0 5px 18px rgba(0, 0, 0, 0.25);
}
.icon-button.danger {
border-color: rgba(248, 113, 113, 0.35);
color: #fecdd3;
}
.icon-button.danger:hover {
border-color: rgba(248, 113, 113, 0.6);
background: rgba(248, 113, 113, 0.08);
}
.asset-item.hidden {
opacity: 0.6;
}
@@ -602,6 +669,27 @@ body {
color: #e2e8f0;
}
.number-input {
position: relative;
padding-right: 48px !important;
font-variant-numeric: tabular-nums;
}
.number-input::-webkit-outer-spin-button,
.number-input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.number-input {
-moz-appearance: textfield;
}
.number-input:focus {
border-color: #7c3aed;
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.25);
}
.control-actions {
display: flex;
gap: 8px;

View File

@@ -27,12 +27,29 @@ const selectedAssetName = document.getElementById('selected-asset-name');
const selectedAssetMeta = document.getElementById('selected-asset-meta');
const selectedZLabel = document.getElementById('asset-z-level');
const selectedTypeLabel = document.getElementById('asset-type-label');
const selectedVisibilityBadge = document.getElementById('selected-asset-visibility');
const selectedToggleBtn = document.getElementById('selected-asset-toggle');
const selectedDeleteBtn = document.getElementById('selected-asset-delete');
const aspectLockState = new Map();
if (widthInput) widthInput.addEventListener('input', () => handleSizeInputChange('width'));
if (heightInput) heightInput.addEventListener('input', () => handleSizeInputChange('height'));
if (speedInput) speedInput.addEventListener('change', updatePlaybackFromInputs);
if (muteInput) muteInput.addEventListener('change', updateMuteFromInput);
if (selectedToggleBtn) selectedToggleBtn.addEventListener('click', (event) => {
event.stopPropagation();
const asset = getSelectedAsset();
if (asset) {
updateVisibility(asset, !asset.hidden);
}
});
if (selectedDeleteBtn) selectedDeleteBtn.addEventListener('click', (event) => {
event.stopPropagation();
const asset = getSelectedAsset();
if (asset) {
deleteAsset(asset);
}
});
function connect() {
const socket = new SockJS('/ws');
@@ -599,8 +616,8 @@ function renderAssetList() {
const toggleBtn = document.createElement('button');
toggleBtn.type = 'button';
toggleBtn.className = 'secondary';
toggleBtn.textContent = asset.hidden ? 'Show' : 'Hide';
toggleBtn.className = 'ghost icon-button';
toggleBtn.innerHTML = `<span class="icon" aria-hidden="true">${asset.hidden ? '👁️' : '🙈'}</span><span class="label">${asset.hidden ? 'Show' : 'Hide'}</span>`;
toggleBtn.addEventListener('click', (e) => {
e.stopPropagation();
selectedAssetId = asset.id;
@@ -609,8 +626,8 @@ function renderAssetList() {
const deleteBtn = document.createElement('button');
deleteBtn.type = 'button';
deleteBtn.className = 'secondary';
deleteBtn.textContent = 'Delete';
deleteBtn.className = 'ghost danger icon-button';
deleteBtn.innerHTML = '<span class="icon" aria-hidden="true">🗑️</span><span class="label">Delete</span>';
deleteBtn.addEventListener('click', (e) => {
e.stopPropagation();
deleteAsset(asset);
@@ -678,6 +695,14 @@ function updateSelectedAssetControls() {
if (selectedTypeLabel) {
selectedTypeLabel.textContent = getDisplayMediaType(asset);
}
if (selectedVisibilityBadge) {
selectedVisibilityBadge.textContent = asset.hidden ? 'Hidden' : 'Visible';
selectedVisibilityBadge.classList.toggle('danger', !!asset.hidden);
}
if (selectedToggleBtn) {
selectedToggleBtn.querySelector('.label').textContent = asset.hidden ? 'Show' : 'Hide';
selectedToggleBtn.querySelector('.icon').textContent = asset.hidden ? '👁️' : '🙈';
}
if (widthInput) widthInput.value = Math.round(asset.width);
if (heightInput) heightInput.value = Math.round(asset.height);
@@ -686,7 +711,7 @@ function updateSelectedAssetControls() {
aspectLockInput.onchange = () => setAspectLock(asset.id, aspectLockInput.checked);
}
if (speedInput) {
speedInput.value = Math.round((asset.speed && asset.speed > 0 ? asset.speed : 1) * 100) / 100;
speedInput.value = Math.round((asset.speed && asset.speed > 0 ? asset.speed : 1) * 100);
}
if (muteInput) {
muteInput.checked = !!asset.muted;
@@ -723,8 +748,8 @@ function applyTransformFromInputs() {
function updatePlaybackFromInputs() {
const asset = getSelectedAsset();
if (!asset) return;
const nextSpeed = Math.max(0.1, parseFloat(speedInput?.value) || asset.speed || 1);
asset.speed = nextSpeed;
const percent = Math.max(10, Math.min(400, parseFloat(speedInput?.value) || 100));
asset.speed = percent / 100;
renderStates.set(asset.id, { ...asset });
persistTransform(asset);
drawAndList();

View File

@@ -27,12 +27,25 @@
<ul id="asset-list" class="asset-list"></ul>
<div id="asset-controls" class="panel hidden asset-settings">
<div class="panel-header">
<div>
<p class="eyebrow subtle">Asset settings</p>
<div class="title-row">
<h4 id="selected-asset-name">Selected asset</h4>
<div class="selected-asset-banner">
<div class="selected-asset-main">
<p class="eyebrow subtle">Asset settings</p>
<div class="title-row">
<h4 id="selected-asset-name">Selected asset</h4>
<span class="badge subtle" id="selected-asset-visibility">Visible</span>
</div>
<p class="muted meta-text" id="selected-asset-meta"></p>
</div>
<div class="selected-asset-actions">
<button type="button" id="selected-asset-toggle" class="ghost icon-button" title="Toggle visibility">
<span class="icon" aria-hidden="true">🙈</span>
<span class="label">Hide</span>
</button>
<button type="button" id="selected-asset-delete" class="ghost danger icon-button" title="Delete asset">
<span class="icon" aria-hidden="true">🗑️</span>
<span class="label">Delete</span>
</button>
</div>
<p class="muted meta-text" id="selected-asset-meta"></p>
</div>
<div class="panel-summary">
<p class="muted">Fine-tune the selected overlay item with sizing, playback, and layering controls.</p>
@@ -47,11 +60,11 @@
<div class="control-grid condensed">
<label>
Width
<input id="asset-width" type="number" min="10" step="5" />
<input id="asset-width" class="number-input" type="number" min="10" step="5" />
</label>
<label>
Height
<input id="asset-height" type="number" min="10" step="5" />
<input id="asset-height" class="number-input" type="number" min="10" step="5" />
</label>
<label class="checkbox-inline">
<input id="maintain-aspect" type="checkbox" checked />
@@ -68,8 +81,8 @@
</div>
<div class="control-grid condensed">
<label>
Animation speed
<input id="asset-speed" type="number" min="0.1" step="0.1" value="1" />
Animation speed (% of original)
<input id="asset-speed" class="number-input" type="number" min="10" max="400" step="5" value="100" />
</label>
<label class="checkbox-inline">
<input id="asset-muted" type="checkbox" />