feat: standardize Beam viewer environment settings
This commit is contained in:
@@ -2,7 +2,7 @@ import { createSliderControl } from "./controls/slider.js";
|
||||
import { createColorControl } from "./controls/color.js";
|
||||
|
||||
const defaultSettings = {
|
||||
themeVersion: "v4-beam-lime",
|
||||
themeVersion: "v5-drone-lime",
|
||||
bgOuter: "#0f0f0f",
|
||||
canvasTop: "#1c1c1c",
|
||||
canvasBottom: "#1c1c1c",
|
||||
@@ -10,27 +10,27 @@ const defaultSettings = {
|
||||
loadingBottom: "#1c1c1c",
|
||||
accent: "#ffea00",
|
||||
accent2: "#ffea00",
|
||||
templateFill: "#1c1c1c",
|
||||
templateOutline: "#233044",
|
||||
templateOutlineHover: "rgba(255,234,0,0.7)",
|
||||
projectBtnFill: "#1c1c1c",
|
||||
projectBtnBorder: "#233044",
|
||||
projectBtnHover: "rgba(255,234,0,0.7)",
|
||||
templateFill: "#292929",
|
||||
templateOutline: "#292929",
|
||||
templateOutlineHover: "#1c1c1c",
|
||||
projectBtnFill: "#292929",
|
||||
projectBtnBorder: "#292929",
|
||||
projectBtnHover: "#1c1c1c",
|
||||
modalBtnPrimary: "#c4ff67",
|
||||
modalBtnSecondary: "#292929",
|
||||
loaderColor: "#c4ff67",
|
||||
templateGlow: 80,
|
||||
toolbarBg: "#1c1c1c",
|
||||
toolbarBg: "#292929",
|
||||
toolbarBgActive: "#c4ff67",
|
||||
toolbarBorder: "#233044",
|
||||
toolbarOutline: "#c4ff67",
|
||||
toolbarBorder: "#292929",
|
||||
toolbarOutline: "#292929",
|
||||
modalBg: "#1c1c1c",
|
||||
modalBgAlpha: 1,
|
||||
modalFocus: "#292929",
|
||||
modalFocusAlpha: 1,
|
||||
modalBorder: "#292929",
|
||||
modalElement: "#292929",
|
||||
modalElementOutline: "#2b2b2b",
|
||||
modalFocusAlpha: 0.35,
|
||||
modalBorder: "#1c1c1c",
|
||||
modalElement: "#262626",
|
||||
modalElementOutline: "#262626",
|
||||
modalRadius: "14px",
|
||||
border: "#233044",
|
||||
text: "#e6edf3",
|
||||
@@ -255,6 +255,40 @@ export function createSettingsMenu({ panel, controls = {}, onChange = null, onSh
|
||||
return slider;
|
||||
};
|
||||
|
||||
const addNumber = ({
|
||||
parent,
|
||||
label,
|
||||
value,
|
||||
min = 0,
|
||||
max,
|
||||
step = 1,
|
||||
onChange,
|
||||
}) => {
|
||||
const row = document.createElement("div");
|
||||
row.className = "color-row";
|
||||
const lbl = document.createElement("div");
|
||||
lbl.textContent = label;
|
||||
const input = document.createElement("input");
|
||||
input.className = "env-number-field";
|
||||
input.type = "number";
|
||||
input.value = value;
|
||||
input.min = min;
|
||||
input.step = step;
|
||||
if (max !== undefined) {
|
||||
input.max = max;
|
||||
}
|
||||
input.addEventListener("input", () => {
|
||||
const nextValue = Number(input.value);
|
||||
if (Number.isFinite(nextValue)) {
|
||||
onChange?.(nextValue);
|
||||
}
|
||||
});
|
||||
row.appendChild(lbl);
|
||||
row.appendChild(input);
|
||||
parent.appendChild(row);
|
||||
return input;
|
||||
};
|
||||
|
||||
const font = section("Фон");
|
||||
addColor(font, "Фон внешний", "bgOuter");
|
||||
addColor(font, "Фон холста верх", "canvasTop");
|
||||
@@ -327,16 +361,17 @@ export function createSettingsMenu({ panel, controls = {}, onChange = null, onSh
|
||||
|
||||
const viewport = section("Viewport");
|
||||
const addCheck = (label, checked, handler) => {
|
||||
const row = document.createElement("div");
|
||||
const row = document.createElement("label");
|
||||
row.className = "checkbox-row";
|
||||
const text = document.createElement("span");
|
||||
text.className = "checkbox-row__label";
|
||||
text.textContent = label;
|
||||
const chk = document.createElement("input");
|
||||
chk.type = "checkbox";
|
||||
chk.checked = checked;
|
||||
chk.addEventListener("change", () => handler(chk.checked));
|
||||
const lbl = document.createElement("label");
|
||||
lbl.textContent = label;
|
||||
row.appendChild(text);
|
||||
row.appendChild(chk);
|
||||
row.appendChild(lbl);
|
||||
viewport.appendChild(row);
|
||||
};
|
||||
if (controls.toggleEdges) addCheck("Рёбра", controls.toggleEdges.checked, (v) => { controls.toggleEdges.checked = v; controls.toggleEdges.dispatchEvent(new Event("change")); });
|
||||
@@ -378,29 +413,25 @@ export function createSettingsMenu({ panel, controls = {}, onChange = null, onSh
|
||||
});
|
||||
|
||||
addColor(modals, "Аутлайн", "modalBorder");
|
||||
addColor(modals, "Фон элемента", "modalElement");
|
||||
addColor(modals, "Контролы", "modalElement");
|
||||
addColor(modals, "Аутлайн элемента", "modalElementOutline");
|
||||
const radiusRow = document.createElement("div");
|
||||
radiusRow.className = "color-row";
|
||||
const radiusLbl = document.createElement("label");
|
||||
radiusLbl.textContent = "Радиус";
|
||||
const radiusInput = document.createElement("input");
|
||||
radiusInput.type = "number";
|
||||
radiusInput.value = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--modal-radius")) || 14;
|
||||
radiusInput.addEventListener("change", () => {
|
||||
const val = `${radiusInput.value}px`;
|
||||
document.documentElement.style.setProperty("--modal-radius", val);
|
||||
setVal("modalRadius", val);
|
||||
addNumber({
|
||||
parent: modals,
|
||||
label: "Радиус",
|
||||
value: parseInt(getComputedStyle(document.documentElement).getPropertyValue("--modal-radius")) || 14,
|
||||
min: 0,
|
||||
max: 48,
|
||||
step: 1,
|
||||
onChange: (nextValue) => {
|
||||
const val = `${Math.max(0, Math.min(48, Math.round(nextValue)))}px`;
|
||||
setVal("modalRadius", val);
|
||||
},
|
||||
});
|
||||
radiusRow.appendChild(radiusLbl);
|
||||
radiusRow.appendChild(radiusInput);
|
||||
radiusRow.appendChild(document.createElement("div"));
|
||||
modals.appendChild(radiusRow);
|
||||
panel.appendChild(modals);
|
||||
|
||||
const cube = section("Выделение объектов");
|
||||
addColor(cube, "Подсветка объектов", "highlight");
|
||||
panel.appendChild(cube);
|
||||
const cube = section("Выделение объектов");
|
||||
addColor(cube, "Подсветка объектов", "highlight");
|
||||
panel.appendChild(cube);
|
||||
};
|
||||
|
||||
const show = () => {
|
||||
|
||||
@@ -62,16 +62,27 @@ export function createTemplatesMenu({ panel, fetchProjects, openProject, onShow,
|
||||
header.className = "templates-header";
|
||||
header.innerHTML = `<span class="templates-title">Проекты и шаблоны</span>`;
|
||||
const actions = document.createElement("div");
|
||||
actions.style.display = "flex";
|
||||
actions.style.gap = "6px";
|
||||
actions.className = "templates-actions";
|
||||
const refresh = document.createElement("button");
|
||||
refresh.className = "templates-close";
|
||||
refresh.type = "button";
|
||||
refresh.title = "Обновить список";
|
||||
refresh.textContent = "↻";
|
||||
refresh.setAttribute("aria-label", "Обновить список");
|
||||
refresh.innerHTML = `
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
|
||||
<path d="M12.2 5.3A4.4 4.4 0 0 0 4.7 3.4L3.6 4.5M3.7 2.1v2.4h2.4M3.8 10.7a4.4 4.4 0 0 0 7.5 1.9l1.1-1.1M12.3 13.9v-2.4H9.9" fill="none" stroke="currentColor" stroke-width="1.35" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
</svg>
|
||||
`;
|
||||
refresh.addEventListener("click", () => load());
|
||||
const closeBtn = document.createElement("button");
|
||||
closeBtn.className = "templates-close";
|
||||
closeBtn.textContent = "×";
|
||||
closeBtn.type = "button";
|
||||
closeBtn.setAttribute("aria-label", "Закрыть проекты и шаблоны");
|
||||
closeBtn.innerHTML = `
|
||||
<svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
|
||||
<path d="M4.25 4.25 11.75 11.75M11.75 4.25 4.25 11.75" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path>
|
||||
</svg>
|
||||
`;
|
||||
closeBtn.addEventListener("click", hide);
|
||||
actions.appendChild(refresh);
|
||||
actions.appendChild(closeBtn);
|
||||
|
||||
Reference in New Issue
Block a user