/
versus2
/
Versus
Обзор
Документация
Войти
/
versus2
/
Versus
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/css/app.css
618 строк
17 KB
Alexander Starov
Add Web GL
07 сен 2025, 16:07
07 сен 2025, 16:07
9890ddc
Код
Авторство
О чём код?
/* Основной контейнер вьюпорта — растянуть и запретить текстовый выбор/скролл по умолчанию */ #viewport-container { position: relative; /* важно для абсолютного позиционирования canvas/ui */ width: 100%; height: 100%; /* или конкретная высота, например 600px */ overflow: hidden; touch-action: none; /* отключает системную обработку жестов (потр./пан/зум) */ -webkit-user-select: none; -moz-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; } /* Canvas renderer'а — растянуть на весь контейнер и принимать указатели */ #viewport-container canvas, #viewport-container > canvas { position: absolute; inset: 0; /* top:0; right:0; bottom:0; left:0; */ width: 100% !important; height: 100% !important; display: block; /* избавляет от лишних gap при inline */ pointer-events: auto; /* гарантируем, что canvas принимает события */ touch-action: none; /* еще раз — важно для сенсорных устройств */ cursor: grab; /* визуальная подсказка, что можно перетаскивать */ } /* Курсор при перетягивании (добавляем/убираем класс 'grabbing' из JS при drag) */ #viewport-container.grabbing canvas, #viewport-container canvas:active { cursor: grabbing; } /* Если у вас есть overlay/popup который должен НЕ мешать кликам в canvas, например превью-изображение, поставьте ему pointer-events:none. Если overlay должен принимать клики — наоборот pointer-events:auto. */ .viewport-overlay { position: absolute; inset: 0; pointer-events: none; /* пропускает клики к canvas снизу */ } /* Убедимся, что HTML/Body позволяют 100% высоту (если контейнер 100%): */ html, body { height: 100%; margin: 0; } body { -webkit-user-select: none; } .enable { -webkit-user-select: text; } input { -webkit-user-select: text !important; } :root { --bg: #0f1113; --panel: #151618; --muted: #9aa0a6; --soft: #2b2d30; --accent: #8b8f94; --glass: rgba(255,255,255,0.03); --radius: 14px; --radius-sm: 8px; --shadow: 0 6px 20px rgba(2,6,10,0.6); --glass-border: rgba(255,255,255,0.03); } * { user-select: none; } body { background: linear-gradient(180deg, #0b0c0d 0%, #0f1113 100%); color: #d7d9db; height: 100vh; overflow: hidden; font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; } body, * { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } .vs-container { display: flex; flex-direction: column; height: 100vh; padding: 20px; gap: 18px; box-sizing: border-box; } .vs-topbar { height: 64px; background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); border-radius: var(--radius); padding: 12px 20px; box-shadow: var(--shadow); border: 1px solid var(--glass-border); backdrop-filter: blur(6px) saturate(1.1); display: flex; align-items: center; position: relative; z-index: 100; } .vs-logo { width: 40px; height: 40px; border-radius: 10px; background: linear-gradient(135deg,#2a2c2f,#3b3e42); display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--muted); font-size: 14px; flex-shrink: 0; margin-right: 10px; } .vs-app-title { font-size: 15px; line-height: 1; } .vs-app-sub { font-size: 12px; color: var(--muted); } .vs-btn { background: transparent; border: 1px solid rgba(255,255,255,0.04); padding: 8px 12px; border-radius: 10px; color: var(--muted); font-size: 13px; cursor: pointer; transition: all .18s; display: flex; align-items: center; gap: 6px; } .vs-btn svg { flex-shrink: 0; } .vs-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0,0,0,0.6); border-color: rgba(255,255,255,0.06); color: #fff; } .vs-btn:active { transform: translateY(0); box-shadow: none; background: rgba(255,255,255,0.05); } .vs-btn.primary { background: linear-gradient(180deg,#2b2d30,#1f2022); border: 1px solid rgba(255,255,255,0.06); color: #e6e8e9; } .vs-sidebar { background: linear-gradient(180deg, var(--panel), rgba(255,255,255,0.01)); border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow); border: 1px solid var(--glass-border); display: flex; flex-direction: column; gap: 12px; height: 100%; } .vs-tree { overflow: auto; padding-right: 6px; flex-grow: 1; } .vs-tree-item { padding: 10px; border-radius: 8px; margin: 6px 0; display: flex; align-items: center; gap: 16px; cursor: pointer; transition: background .15s; } .vs-tree-item:hover { background: rgba(255,255,255,0.02); } .vs-tree-item:active { background: rgba(255,255,255,0.04); } .vs-icon { width: 36px; height: 36px; border-radius: 8px; background: linear-gradient(180deg,#171819,#1f2123); display: flex; align-items: center; justify-content: center; color: var(--muted); font-weight: 700; flex-shrink: 0; } .vs-tree-divider { height: 1px; background: linear-gradient(90deg,transparent,rgba(255,255,255,0.02),transparent); margin: 8px 0; border-radius: 999px; } .vs-viewport-panel { background: linear-gradient(180deg,#0e1012,#16171a); border-radius: var(--radius); padding: 14px; display: flex; flex-direction: column; gap: 12px; box-shadow: var(--shadow); border: 1px solid var(--glass-border); height: 100%; } .vs-viewport-canvas { flex: 1; border-radius: 10px; background: transparent; display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; border: 1px solid rgba(255,255,255,0.02); } .vs-gizmo { width: 220px; height: 160px; border-radius: 12px; background: linear-gradient(180deg,#1a1c1e,#141516); box-shadow: inset 0 1px 0 rgba(255,255,255,0.02); display: flex; align-items: center; justify-content: center; color: var(--muted); font-weight: 600; } .vs-viewport-grid { position: absolute; inset: 0; background-image: linear-gradient(rgba(255,255,255,0.02) 1px, transparent 1px); background-size: 60px 60px; opacity: 0.7; } .vs-inspector { background: linear-gradient(180deg,var(--panel), rgba(255,255,255,0.01)); border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow); border: 1px solid var(--glass-border); display: flex; flex-direction: column; height: 100%; } .vs-bottom-panel { height: 120px; display: flex; gap: 12px; } .vs-assets { flex: 1; background: linear-gradient(180deg,var(--soft), rgba(255,255,255,0.01)); border-radius: var(--radius-sm); padding: 10px; display: flex; gap: 10px; align-items: center; } .vs-asset-item { width: 84px; height: 84px; border-radius: 10px; background: linear-gradient(180deg,#161718,#121314); display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 12px; color: var(--muted); cursor: pointer; border: 1px solid rgba(255,255,255,0.02); transition: all .15s; } .vs-asset-item:hover { border-color: rgba(255,255,255,0.06); color: #fff; } .vs-asset-item:active { background: rgba(255,255,255,0.04); } .vs-timeline { width: 520px; background: linear-gradient(180deg,#111213,#0d0e10); padding: 10px; border-radius: var(--radius-sm); display: flex; flex-direction: column; } .vs-timeline-bar { height: 42px; background: linear-gradient(90deg,rgba(255,255,255,0.02),transparent); border-radius: 8px; margin-top: 8px; } .vs-input { background: transparent; border: 1px solid rgba(255,255,255,0.03); padding: 8px 10px; border-radius: 8px; color: inherit; width: 100%; } .vs-input:focus { outline: none; border-color: rgba(255,255,255,0.06); } .vs-section-title { font-size: 12px; color: var(--muted); margin-bottom: 8px; } .vs-muted { color: var(--muted); } .vs-prop { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; } .vs-control-hint { position: absolute; left: 14px; bottom: 14px; background: rgba(255,255,255,0.02); padding: 8px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.02); font-size: 12px; color: var(--muted); } .vs-play-toggle { background-color: var(--soft); border-radius: 12px; padding: 4px; margin-bottom: 10px; display: flex; align-items: center; border: 1px solid var(--glass-border); } .vs-play-toggle .vs-btn { border: none; background: transparent; box-shadow: none; } .vs-play-toggle .vs-btn.active { background: rgba(255,255,255,0.05); color: #fff; } .vs-fade-up { transform: translateY(8px); opacity: 0; animation: vs-fadeUp .6s ease forwards; } @keyframes vs-fadeUp { to { transform: none; opacity: 1; } } /* Адаптивность */ @media (max-width: 1199.98px) { .vs-inspector-col { display: none; } } @media (max-width: 767.98px) { .vs-sidebar-col { display: none; } .vs-bottom-panel { flex-direction: column; height: auto; } .vs-timeline { width: 100%; } } /* BOOTSTRAP OVERRIDE STYLES */ .nav-tabs { border-bottom: 1px solid var(--glass-border); } .nav-tabs .nav-link { background: transparent; border: 1px solid transparent; color: var(--muted); border-top-left-radius: var(--radius-sm); border-top-right-radius: var(--radius-sm); } .nav-tabs .nav-link.active { background: var(--glass); border-color: var(--glass-border); border-bottom-color: transparent; color: #fff; } .nav-tabs .nav-link:hover { border-color: var(--glass-border); } .tab-content { overflow: auto; } .accordion, .accordion-item { --bs-accordion-border-width: 0; --bs-accordion-border-radius: var(--radius-sm); } .accordion-item { background-color: transparent; border: 1px solid var(--glass-border) !important; margin-bottom: 8px; border-radius: var(--radius-sm) !important; } .accordion-header { border-radius: var(--radius-sm); } .accordion-button { background-color: var(--soft); color: #d7d9db; font-size: 13px; padding: 10px 14px; border-radius: var(--radius-sm); } .accordion-button:not(.collapsed) { background-color: var(--soft); box-shadow: none; } .accordion-button:focus { box-shadow: none; } .accordion-button::after { --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%239aa0a6'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); } .accordion-body { padding: 14px; } .modal-content { background: linear-gradient(180deg, var(--panel), #0f1113); border: 1px solid var(--glass-border); border-radius: var(--radius); box-shadow: var(--shadow); } .modal-header { border-bottom: 1px solid var(--glass-border); } .modal-footer { border-top: 1px solid var(--glass-border); } .btn-close { filter: invert(1) grayscale(1) brightness(1.5); } .dropdown-menu { background-color: #1f2123; border: 1px solid var(--glass-border); box-shadow: var(--shadow); --bs-dropdown-link-color: #d7d9db; --bs-dropdown-link-hover-color: #fff; --bs-dropdown-link-hover-bg: rgba(255,255,255,0.05); --bs-dropdown-divider-bg: var(--glass-border); } .tooltip { --bs-tooltip-bg: #1f2123; --bs-tooltip-opacity: 1; --bs-tooltip-border-radius: var(--radius-sm); } /* ДОБАВЬТЕ ЭТОТ КОД В ВАШ CSS ФАЙЛ */ .vs-viewport-tools { position: absolute; top: 40%; left: 14px; z-index: 10; display: flex; flex-direction: column; gap: 8px; } .accordion-button { background-color: var(--soft); color: #d7d9db; font-size: 13px; padding: 10px 14px; border-radius: var(--radius-sm); } .accordion-button:not(.collapsed) { background-color: var(--soft); box-shadow: none; /* Вот добавленное правило */ border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .accordion-button:focus { box-shadow: none; } /* Добавьте это правило, чтобы сохранить стили для активной кнопки аккордеона */ .accordion-button:not(.collapsed) { background-color: var(--soft); color: #d7d9db; box-shadow: none; /* Убираем скругление у нижней части кнопки, когда аккордеон открыт */ border-bottom-left-radius: 0; border-bottom-right-radius: 0; } /* Убираем скругление у нижней части кнопки, когда аккордеон открыт */ .accordion-button:not(.collapsed) { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } /* Чтобы кнопки не содержали текст, а только иконки */ .vs-viewport-tools .vs-btn { padding: 8px; } .accordion-body .vs-input { color: #fff; } .vs-assets { flex: 1; background: linear-gradient(180deg,var(--soft), rgba(255,255,255,0.01)); border-radius: var(--radius-sm); padding: 10px; display: flex; gap: 10px; align-items: center; } .vs-asset-item { width: 84px; height: 84px; border-radius: 10px; background: linear-gradient(180deg,#161718,#121314); display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 12px; color: var(--muted); cursor: pointer; border: 1px solid rgba(255,255,255,0.02); transition: all .15s; } .vs-asset-item:hover { border-color: rgba(255,255,255,0.06); color: #fff; } .vs-asset-item:active { background: rgba(255,255,255,0.04); }