beam: align zoom slider with engine controls

This commit is contained in:
CODEX 2026-06-04 23:33:28 +03:00
parent 6d65b2ba41
commit 43accba61c
3 changed files with 104 additions and 37 deletions

View File

@ -1167,58 +1167,105 @@ header {
} }
.inspector-slider.slider-row { .inspector-slider.slider-row {
display: grid; position: relative;
grid-template-columns: minmax(0, 1fr) auto; display: block;
grid-template-areas: width: 100%;
"label value" height: 40px;
"input input"; overflow: hidden;
gap: 8px; border-radius: 14px;
align-items: center; background: var(--nodedc-glass-control-bg);
padding: 0; box-shadow: var(--nodedc-glass-control-shadow);
backdrop-filter: blur(24px) saturate(128%) brightness(1.05);
-webkit-backdrop-filter: blur(24px) saturate(128%) brightness(1.05);
}
.inspector-slider.slider-row::before {
content: "";
position: absolute;
inset: 0 auto 0 0;
z-index: 1;
width: var(--slider-percent, 0%);
border-radius: inherit;
background: var(--modal-btn-primary, var(--accent));
} }
.inspector-slider .slider-label { .inspector-slider .slider-label {
grid-area: label; position: absolute;
min-width: 0; top: 50%;
color: var(--muted); left: 16px;
font-size: 11px; z-index: 2;
max-width: calc(100% - 116px);
overflow: hidden;
color: rgba(255, 255, 255, 0.92);
font-size: 12px;
font-weight: 760; font-weight: 760;
line-height: 1.2; line-height: 1;
text-overflow: ellipsis;
white-space: nowrap;
transform: translateY(-50%);
pointer-events: none;
} }
.inspector-slider .slider-value { .inspector-slider .slider-value {
grid-area: value; position: absolute;
min-width: 38px; top: 50%;
color: rgba(245, 245, 250, 0.82); right: 16px;
z-index: 2;
color: rgba(245, 245, 250, 0.9);
font-size: 12px;
font-weight: 760;
line-height: 1;
text-align: right; text-align: right;
transform: translateY(-50%);
pointer-events: none;
} }
.inspector-slider .slider-input { .inspector-slider .slider-input {
grid-area: input; position: absolute;
height: 40px; inset: 0;
border-radius: 14px; z-index: 4;
background: linear-gradient( width: 100%;
90deg, height: 100%;
var(--modal-btn-primary, var(--accent)) var(--slider-percent, 0%), margin: 0;
var(--nodedc-glass-control-bg) var(--slider-percent, 0%) appearance: none;
); -webkit-appearance: none;
box-shadow: var(--nodedc-glass-control-shadow); border-radius: inherit;
background: transparent;
opacity: 0;
cursor: pointer;
} }
.inspector-slider .slider-input::-webkit-slider-thumb { .inspector-slider .slider-input::-webkit-slider-thumb {
width: 20px; width: 24px;
height: 20px; height: 40px;
background: var(--modal-btn-primary, var(--accent)); margin-top: 0;
appearance: none;
-webkit-appearance: none;
border: 0; border: 0;
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.32); background: transparent;
box-shadow: none;
} }
.inspector-slider .slider-input::-moz-range-thumb { .inspector-slider .slider-input::-moz-range-thumb {
width: 20px; width: 24px;
height: 20px; height: 40px;
background: var(--modal-btn-primary, var(--accent));
border: 0; border: 0;
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.32); background: transparent;
box-shadow: none;
}
.inspector-slider .slider-fill-text {
position: absolute;
inset: 0;
z-index: 3;
overflow: hidden;
clip-path: inset(0 calc(100% - var(--slider-percent, 0%)) 0 0);
pointer-events: none;
}
.inspector-slider .slider-fill-text .slider-label,
.inspector-slider .slider-fill-text .slider-value {
color: var(--modal-btn-primary-contrast, #15170f);
} }
.settings-panel input[type="color"] { .settings-panel input[type="color"] {

View File

@ -87,7 +87,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./dcViewer.css?v=7"> <link rel="stylesheet" href="./dcViewer.css?v=8">
</head> </head>
<body> <body>
<header> <header>
@ -239,6 +239,6 @@
<input id="fileInput" class="hidden" type="file" <input id="fileInput" class="hidden" type="file"
accept=".xkt,.glb,.gltf,.bim,.las,.laz,.obj,.stl"> accept=".xkt,.glb,.gltf,.bim,.las,.laz,.obj,.stl">
<script type="module" src="./dcViewer.js?v=7"></script> <script type="module" src="./dcViewer.js?v=8"></script>
</body> </body>
</html> </html>

View File

@ -27,11 +27,30 @@ export function createSliderControl({
const valueEl = document.createElement("div"); const valueEl = document.createElement("div");
valueEl.className = "slider-value"; valueEl.className = "slider-value";
const fillText = document.createElement("span");
fillText.className = "slider-fill-text";
fillText.setAttribute("aria-hidden", "true");
const fillLabel = document.createElement("span");
fillLabel.textContent = label;
fillLabel.className = "slider-label";
const fillValue = document.createElement("span");
fillValue.className = "slider-value";
fillText.appendChild(fillLabel);
fillText.appendChild(fillValue);
const updateFill = () => { const updateFill = () => {
const percent = ((input.value - input.min) / (input.max - input.min)) * 100; const range = Number(input.max) - Number(input.min);
const percent = range
? Math.max(0, Math.min(100, ((Number(input.value) - Number(input.min)) / range) * 100))
: 0;
row.style.setProperty("--slider-percent", `${percent}%`);
input.style.setProperty("--slider-percent", `${percent}%`); input.style.setProperty("--slider-percent", `${percent}%`);
if (showValue) { if (showValue) {
valueEl.textContent = formatValue(Number(input.value)); const formattedValue = formatValue(Number(input.value));
valueEl.textContent = formattedValue;
fillValue.textContent = formattedValue;
} }
}; };
@ -47,6 +66,7 @@ export function createSliderControl({
row.appendChild(input); row.appendChild(input);
if (showValue) { if (showValue) {
row.appendChild(valueEl); row.appendChild(valueEl);
row.appendChild(fillText);
} }
row.setValue = (nextValue) => { row.setValue = (nextValue) => {
input.value = nextValue; input.value = nextValue;