Загрузка...

Sci-Fi DMX интерфейс управления: 3D визуализация сигнала, фейдеры каналов, XY-пад. UI для дашбордов и панелей управления.
<html lang="en" vid="0">
<head vid="1">
<meta charset="UTF-8" vid="2">
<meta name="viewport" content="width=device-width, initial-scale=1.0" vid="3">
<title vid="4">TE-DMX Field Controller</title>
<style vid="5">
:root {
--void-dark: #050505;
--void-depth: #0a0c10;
--text-primary: #C0B283;
--text-dim: rgba(192, 178, 131, 0.4);
--accent-flare: #ff5533;
--accent-cold: #2a4d4d;
--border-hairline: rgba(192, 178, 131, 0.15);
--grid-line: rgba(192, 178, 131, 0.08);
--font-stack: 'Courier Prime', 'Space Mono', monospace;
--tracking-wide: 0.3em;
--tracking-tight: 0.05em;
}
@import url('https://fonts.googleapis.com/css2?family=Space+Mono:ital,wght@0,400;0,700;1,400&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
user-select: none;
}
body {
background-color: var(--void-dark);
color: var(--text-primary);
font-family: var(--font-stack);
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.04'/%3E%3C/svg%3E");
}
.interface-wrapper {
width: 1200px;
height: 800px;
background: linear-gradient(135deg, rgba(10, 12, 16, 0.95), rgba(5, 5, 5, 1));
border: 1px solid var(--border-hairline);
display: grid;
grid-template-columns: 320px 1fr 320px;
grid-template-rows: 60px 1fr 200px;
position: relative;
box-shadow: 0 0 80px rgba(0, 0, 0, 0.8);
}
.deco-line {
position: absolute;
background: var(--border-hairline);
z-index: 0;
pointer-events: none;
}
.dl-1 {
width: 1px;
height: 100%;
left: 320px;
top: 0;
}
.dl-2 {
width: 1px;
height: 100%;
right: 320px;
top: 0;
}
.dl-3 {
height: 1px;
width: 100%;
top: 60px;
left: 0;
}
.dl-4 {
height: 1px;
width: 100%;
bottom: 200px;
left: 0;
}
.dl-cross {
width: 100%;
height: 1px;
background: linear-gradient(90deg, transparent, var(--border-hairline), transparent);
top: 50%;
transform: rotate(-45deg);
opacity: 0.3;
}
h1,
h2,
h3,
.label {
text-transform: uppercase;
letter-spacing: var(--tracking-wide);
font-weight: 400;
font-size: 0.7rem;
}
.header-bar {
grid-column: 1 / -1;
grid-row: 1;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 2rem;
border-bottom: 1px solid var(--border-hairline);
z-index: 10;
}
.header-meta {
display: flex;
gap: 2rem;
font-size: 0.6rem;
color: var(--text-dim);
}
.panel-left {
grid-column: 1;
grid-row: 2 / -1;
border-right: 1px solid var(--border-hairline);
padding: 2rem;
display: flex;
flex-direction: column;
gap: 4rem;
z-index: 10;
}
.fader-group {
display: flex;
justify-content: space-between;
height: 300px;
}
.fader-track {
width: 40px;
height: 100%;
position: relative;
border-left: 1px solid var(--grid-line);
border-right: 1px solid var(--grid-line);
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
padding-bottom: 1rem;
}
.fader-handle {
width: 30px;
height: 10px;
background: var(--text-primary);
position: absolute;
bottom: 20%;
cursor: ns-resize;
transition: background 0.2s, box-shadow 0.2s;
}
.fader-handle:hover {
background: var(--accent-flare);
box-shadow: 0 0 10px var(--accent-flare);
}
.fader-val {
font-size: 0.6rem;
margin-top: 1rem;
opacity: 0.7;
}
.fader-label {
position: absolute;
top: -2rem;
font-size: 0.5rem;
letter-spacing: 0.1em;
text-align: center;
width: 100%;
}
.viz-stage {
grid-column: 2;
grid-row: 2;
position: relative;
overflow: hidden;
background: radial-gradient(circle at center, rgba(42, 77, 77, 0.1) 0%, rgba(5, 5, 5, 0) 70%);
}
#three-canvas {
width: 100%;
height: 100%;
display: block;
opacity: 0.8;
mix-blend-mode: screen;
}
.overlay-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
pointer-events: none;
mix-blend-mode: overlay;
z-index: 5;
width: 100%;
}
.main-title {
font-size: 2.5rem;
letter-spacing: 0.5em;
margin-bottom: 2rem;
opacity: 0.8;
color: var(--text-primary);
}
.sub-title {
font-size: 0.8rem;
letter-spacing: 0.8em;
color: var(--accent-flare);
}
.panel-right {
grid-column: 3;
grid-row: 2 / -1;
border-left: 1px solid var(--border-hairline);
padding: 2rem;
display: flex;
flex-direction: column;
gap: 2rem;
z-index: 10;
}
.matrix-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.btn-matrix {
aspect-ratio: 1;
background: transparent;
border: 1px solid var(--text-dim);
color: var(--text-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.btn-matrix:hover {
border-color: var(--accent-flare);
color: var(--accent-flare);
box-shadow: 0 0 15px rgba(255, 85, 51, 0.2);
}
.btn-matrix.active {
background: var(--accent-flare);
color: var(--void-dark);
border-color: var(--accent-flare);
box-shadow: 0 0 20px rgba(255, 85, 51, 0.6);
}
.xy-container {
width: 100%;
aspect-ratio: 1;
border: 1px solid var(--text-dim);
position: relative;
background: radial-gradient(circle at center, rgba(192, 178, 131, 0.05), transparent 60%);
cursor: crosshair;
}
.xy-cursor {
width: 10px;
height: 10px;
border: 1px solid var(--accent-flare);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
box-shadow: 0 0 10px var(--accent-flare);
}
.xy-grid-lines {
position: absolute;
inset: 0;
pointer-events: none;
background-image:
linear-gradient(var(--grid-line) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
background-size: 20px 20px;
opacity: 0.3;
}
.panel-bottom {
grid-column: 2;
grid-row: 3;
border-top: 1px solid var(--border-hairline);
padding: 2rem;
display: flex;
justify-content: space-between;
align-items: flex-end;
z-index: 10;
}
.data-block {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.data-row {
display: flex;
gap: 1rem;
font-size: 0.6rem;
letter-spacing: 0.1em;
color: var(--text-dim);
}
.data-val {
color: var(--text-primary);
}
.barcode {
height: 20px;
display: flex;
align-items: flex-end;
gap: 2px;
opacity: 0.6;
}
.bar {
width: 2px;
background: var(--text-primary);
}
@keyframes pulse {
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 0.8;
}
}
.status-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent-cold);
box-shadow: 0 0 5px var(--accent-cold);
}
.status-dot.active {
background: var(--accent-flare);
box-shadow: 0 0 8px var(--accent-flare);
animation: pulse 2s infinite;
}
.corner-deco {
position: absolute;
width: 10px;
height: 10px;
border: 1px solid var(--text-primary);
}
.tl {
top: -1px;
left: -1px;
border-right: none;
border-bottom: none;
}
.tr {
top: -1px;
right: -1px;
border-left: none;
border-bottom: none;
}
.bl {
bottom: -1px;
left: -1px;
border-right: none;
border-top: none;
}
.br {
bottom: -1px;
right: -1px;
border-left: none;
border-top: none;
}
.planet-glow-overlay {
position: absolute;
top: -20%;
left: -20%;
width: 60%;
height: 60%;
background: radial-gradient(circle, rgba(255, 85, 51, 0.15), transparent 70%);
filter: blur(80px);
pointer-events: none;
z-index: 1;
}
svg.icon {
width: 1.2em;
height: 1.2em;
fill: currentColor;
}
</style>
</head>
<body vid="6">
<div class="interface-wrapper" vid="7">
<div class="deco-line dl-1" vid="8"></div>
<div class="deco-line dl-2" vid="9"></div>
<div class="deco-line dl-3" vid="10"></div>
<div class="deco-line dl-4" vid="11"></div>
<div class="deco-line dl-cross" vid="12"></div>
<div class="planet-glow-overlay" vid="13"></div>
<header class="header-bar" vid="14">
<div style="display: flex; align-items: center; gap: 1rem;" vid="15">
<div class="status-dot active" vid="16"></div>
<h2 vid="17">TE-DMX // SYS.01</h2>
</div>
<div class="header-meta" vid="18">
<span vid="19">LAT 12.334 N</span>
<span vid="20">LON 45.992 E</span>
<span vid="21">SIGNAL: STRONG</span>
</div>
<div style="display: flex; gap: 0.5rem; align-items: center;" vid="22">
<span class="label" vid="23">NET STATUS</span>
<div class="status-dot" vid="24"></div>
<div class="status-dot" vid="25"></div>
<div class="status-dot" vid="26"></div>
</div>
</header>
<aside class="panel-left" vid="27">
<div style="display:flex; justify-content:space-between; align-items:center;" vid="28">
<span class="label" vid="29">CHANNEL GAIN</span>
<span class="label" style="font-size:0.5rem; opacity:0.5;" vid="30">[A-01]</span>
</div>
<div class="fader-group" vid="31">
<div class="fader-track" id="fader1" vid="32">
<span class="fader-label" vid="33">CH.1</span>
<div class="fader-handle" style="bottom: 70%;" vid="34"></div>
</div>
<div class="fader-track" id="fader2" vid="35">
<span class="fader-label" vid="36">CH.2</span>
<div class="fader-handle" style="bottom: 40%;" vid="37"></div>
</div>
<div class="fader-track" id="fader3" vid="38">
<span class="fader-label" vid="39">CH.3</span>
<div class="fader-handle" style="bottom: 25%;" vid="40"></div>
</div>
<div class="fader-track" id="fader4" vid="41">
<span class="fader-label" vid="42">MST</span>
<div class="fader-handle" style="bottom: 90%; background: var(--accent-flare);" vid="43"></div>
</div>
</div>
<div class="data-block" vid="44">
<span class="label" vid="45">THERMAL STATUS</span>
<div class="data-row" vid="46">
<span vid="47">CORE</span>
<span class="data-val" vid="48">45°C</span>
</div>
<div class="data-row" vid="49">
<span vid="50">AUX</span>
<span class="data-val" vid="51">32°C</span>
</div>
</div>
</aside>
<main class="viz-stage" vid="52">
<div class="corner-deco tl" vid="53"></div>
<div class="corner-deco tr" vid="54"></div>
<div class="corner-deco bl" vid="55"></div>
<div class="corner-deco br" vid="56"></div>
<canvas id="three-canvas" vid="57"></canvas>
<div class="overlay-text" vid="58">
<h1 class="main-title" vid="59">SIGNAL<br vid="60">DETECTED</h1>
<div class="sub-title" vid="61">A N A L Y Z I N G W A V E F O R M</div>
</div>
</main>
<aside class="panel-right" vid="62">
<span class="label" vid="63">MODULATION MATRIX</span>
<div class="matrix-grid" vid="64">
<button class="btn-matrix active" vid="65">
<svg class="icon" viewBox="0 0 24 24" vid="66"><path d="M12 2L2 19h20L12 2zm0 3.8l6.3 11.2H5.7L12 5.8zM11 15v2h2v-2h-2zm0-6v4h2V9h-2z" vid="67"></path></svg>
</button>
<button class="btn-matrix" vid="68">
<svg class="icon" viewBox="0 0 24 24" vid="69"><circle cx="12" cy="12" r="8" fill="none" stroke="currentColor" stroke-width="2" vid="70"></circle></svg>
</button>
<button class="btn-matrix" vid="71">
<svg class="icon" viewBox="0 0 24 24" vid="72"><rect x="4" y="4" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" vid="73"></rect></svg>
</button>
<button class="btn-matrix" vid="74">
<svg class="icon" viewBox="0 0 24 24" vid="75"><path d="M11 2v20h2V2h-2zM2 11v2h20v-2H2z" vid="76"></path></svg>
</button>
<button class="btn-matrix active" vid="77">
<svg class="icon" viewBox="0 0 24 24" vid="78"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9v-2h2v2zm0-4H9V7h2v5z" vid="79"></path></svg>
</button>
<button class="btn-matrix" vid="80">
<svg class="icon" viewBox="0 0 24 24" vid="81"><path d="M7 11h10v2H7z" vid="82"></path></svg>
</button>
</div>
<div style="height: 1px; background: var(--border-hairline); width: 100%;" vid="83"></div>
<span class="label" vid="84">VECTOR CONTROL</span>
<div class="xy-container" id="xyPad" vid="85">
<div class="xy-grid-lines" vid="86"></div>
<div class="xy-cursor" id="xyCursor" vid="87"></div>
<div style="position:absolute; bottom:5px; left:5px; font-size:0.5rem; opacity:0.5;" vid="88">X: 0.50
</div>
<div style="position:absolute; top:5px; right:5px; font-size:0.5rem; opacity:0.5;" vid="89">Y: 0.50
</div>
</div>
</aside>
<footer class="panel-bottom" vid="90">
<div class="data-block" vid="91">
<span class="label" vid="92">SEQUENCE DATA</span>
<div style="margin-top:0.5rem; font-family: monospace; font-size: 0.6rem; color: var(--text-dim); line-height: 1.5;"
vid="93">
TX_099238...OK<br vid="94">
RX_110293...WAIT<br vid="95">
BUF_SIZE....512KB
</div>
</div>
<div style="text-align: right;" vid="96">
<div class="barcode" vid="97">
<div class="bar" style="height: 40%" vid="98"></div>
<div class="bar" style="height: 80%" vid="99"></div>
<div class="bar" style="height: 60%" vid="100"></div>
<div class="bar" style="height: 100%" vid="101"></div>
<div class="bar" style="height: 30%" vid="102"></div>
<div class="bar" style="height: 50%" vid="103"></div>
<div class="bar" style="height: 90%" vid="104"></div>
<div class="bar" style="height: 20%" vid="105"></div>
<div class="bar" style="height: 70%" vid="106"></div>
<div class="bar" style="height: 40%" vid="107"></div>
<div class="bar" style="height: 60%" vid="108"></div>
<div class="bar" style="height: 100%" vid="109"></div>
<div class="bar" style="height: 40%" vid="110"></div>
<div class="bar" style="height: 80%" vid="111"></div>
<div class="bar" style="height: 60%" vid="112"></div>
<div class="bar" style="height: 100%" vid="113"></div>
<div class="bar" style="height: 30%" vid="114"></div>
<div class="bar" style="height: 50%" vid="115"></div>
</div>
<div style="margin-top: 5px; font-size: 0.5rem; letter-spacing: 0.5em;" vid="116">ID: 994-X-TE</div>
</div>
</footer>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js" vid="117"></script>
<script vid="118">
const initThreeJS = () => {
const canvas = document.getElementById('three-canvas');
const scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x0a0c10, 0.05);
const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight, 0.1, 1000);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: true, antialias: true });
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
const geometry = new THREE.IcosahedronGeometry(2, 4);
const material = new THREE.MeshBasicMaterial({
color: 0xC0B283,
wireframe: true,
transparent: true,
opacity: 0.15
});
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
const particlesGeom = new THREE.BufferGeometry();
const particlesCount = 500;
const posArray = new Float32Array(particlesCount * 3);
for(let i = 0; i < particlesCount * 3; i++) {
posArray[i] = (Math.random() - 0.5) * 10;
}
particlesGeom.setAttribute('position', new THREE.BufferAttribute(posArray, 3));
const particlesMat = new THREE.PointsMaterial({
size: 0.02,
color: 0xff5533,
transparent: true,
opacity: 0.8
});
const particleMesh = new THREE.Points(particlesGeom, particlesMat);
scene.add(particleMesh);
const animate = () => {
requestAnimationFrame(animate);
sphere.rotation.x += 0.001;
sphere.rotation.y += 0.002;
particleMesh.rotation.y -= 0.001;
const time = Date.now() * 0.001;
sphere.scale.setScalar(1 + Math.sin(time) * 0.02);
renderer.render(scene, camera);
};
animate();
window.addEventListener('resize', () => {
});
};
const initFaders = () => {
const tracks = document.querySelectorAll('.fader-track');
tracks.forEach(track => {
track.addEventListener('mousedown', (e) => {
const handle = track.querySelector('.fader-handle');
const updatePos = (mouseY) => {
const rect = track.getBoundingClientRect();
let percent = 1 - ((mouseY - rect.top) / rect.height);
percent = Math.max(0, Math.min(1, percent));
handle.style.bottom = `${percent * 100}%`;
};
updatePos(e.clientY);
const onMove = (moveEvent) => updatePos(moveEvent.clientY);
const onUp = () => {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
};
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
});
});
};
const initMatrix = () => {
const btns = document.querySelectorAll('.btn-matrix');
btns.forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('active');
});
});
};
const initXYPad = () => {
const pad = document.getElementById('xyPad');
const cursor = document.getElementById('xyCursor');
let isDragging = false;
pad.addEventListener('mousedown', (e) => {
isDragging = true;
updateCursor(e);
});
document.addEventListener('mousemove', (e) => {
if(!isDragging) return;
updateCursor(e);
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
function updateCursor(e) {
const rect = pad.getBoundingClientRect();
let x = e.clientX - rect.left;
let y = e.clientY - rect.top;
x = Math.max(0, Math.min(rect.width, x));
y = Math.max(0, Math.min(rect.height, y));
cursor.style.left = `${x}px`;
cursor.style.top = `${y}px`;
}
};
document.addEventListener('DOMContentLoaded', () => {
initThreeJS();
initFaders();
initMatrix();
initXYPad();
});
</script>
</body>
</html>