555 lines
13 KiB
HTML
555 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Re-Commander — Animator</title>
|
|
<link rel="stylesheet" href="style.css">
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin: 0;
|
|
padding: 0;
|
|
overflow: hidden;
|
|
height: 100vh;
|
|
}
|
|
|
|
/* ── Header ── */
|
|
header {
|
|
flex-shrink: 0;
|
|
background: var(--surface);
|
|
border-bottom: 1px solid var(--border);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.header-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 8px 16px;
|
|
gap: 12px;
|
|
border-bottom: 1px solid var(--border);
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
.header-bar h1 {
|
|
margin: 0;
|
|
font-size: 16px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.header-status {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
flex-shrink: 0;
|
|
margin-left: auto;
|
|
}
|
|
|
|
.header-status span {
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* ── Toolbar ── */
|
|
.toolbar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 8px 16px;
|
|
flex-wrap: nowrap;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.toolbar-group {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.toolbar-group button {
|
|
padding: 6px 12px;
|
|
font-size: 11px;
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
background: var(--surface2);
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
color: var(--text);
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.toolbar-group button:hover {
|
|
background: var(--accent);
|
|
color: #000;
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
/* Top toolbar buttons - File, Edit, Playback, etc */
|
|
.toolbar-group:nth-child(1) button,
|
|
.toolbar-group:nth-child(2) button,
|
|
.toolbar-group:nth-child(3) button,
|
|
.toolbar-group:nth-child(5) button {
|
|
padding: 10px 16px;
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
border: 2px solid var(--accent);
|
|
background: linear-gradient(135deg, var(--accent)20, var(--accent)5);
|
|
color: var(--accent);
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.toolbar-group:nth-child(1) button:hover,
|
|
.toolbar-group:nth-child(2) button:hover,
|
|
.toolbar-group:nth-child(3) button:hover,
|
|
.toolbar-group:nth-child(5) button:hover {
|
|
background: var(--accent);
|
|
color: #000;
|
|
border-color: var(--accent);
|
|
transform: scale(1.05);
|
|
box-shadow: 0 2px 8px rgba(255,255,0,0.3);
|
|
}
|
|
|
|
.toolbar-sep {
|
|
width: 1px;
|
|
height: 18px;
|
|
background: var(--border);
|
|
margin: 0 4px;
|
|
}
|
|
|
|
.toolbar-spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
/* ── Main Container ── */
|
|
.main-container {
|
|
flex: 1;
|
|
display: grid;
|
|
grid-template-columns: 250px 1fr 300px;
|
|
gap: 1px;
|
|
background: var(--border);
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.panel {
|
|
background: var(--bg);
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ── Left Sidebar ── */
|
|
.left-panel {
|
|
background: var(--surface);
|
|
border-right: 1px solid var(--border);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.panel-header {
|
|
padding: 12px;
|
|
background: var(--surface2);
|
|
border-bottom: 1px solid var(--border);
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.panel-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 12px;
|
|
}
|
|
|
|
.library-item {
|
|
padding: 10px;
|
|
margin-bottom: 6px;
|
|
background: var(--surface2);
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
user-select: none;
|
|
}
|
|
|
|
.library-item:hover {
|
|
background: var(--accent);
|
|
color: #000;
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.library-item.selected {
|
|
background: var(--accent);
|
|
color: #000;
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
/* ── Center Area ── */
|
|
.center-panel {
|
|
background: #000;
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-right: 1px solid var(--border);
|
|
}
|
|
|
|
.center-tabs {
|
|
display: flex;
|
|
background: var(--surface);
|
|
border-bottom: 1px solid var(--border);
|
|
flex-shrink: 0;
|
|
overflow-x: auto;
|
|
gap: 2px;
|
|
padding: 4px;
|
|
}
|
|
|
|
.center-tab {
|
|
padding: 10px 16px;
|
|
background: var(--surface2);
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
white-space: nowrap;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.center-tab.active {
|
|
background: var(--accent);
|
|
color: #000;
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.center-tab:hover {
|
|
background: var(--accent);
|
|
color: #000;
|
|
}
|
|
|
|
.center-content {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--muted);
|
|
font-size: 28px;
|
|
}
|
|
|
|
/* ── Right Sidebar ── */
|
|
.right-panel {
|
|
background: var(--surface);
|
|
border-left: 1px solid var(--border);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.right-tabs {
|
|
display: flex;
|
|
border-bottom: 1px solid var(--border);
|
|
background: var(--surface2);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.right-tab {
|
|
flex: 1;
|
|
padding: 10px;
|
|
background: transparent;
|
|
border: none;
|
|
border-bottom: 2px solid transparent;
|
|
color: var(--muted);
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
text-align: center;
|
|
}
|
|
|
|
.right-tab.active {
|
|
color: var(--accent);
|
|
border-bottom-color: var(--accent);
|
|
}
|
|
|
|
.right-tab:hover {
|
|
color: var(--text);
|
|
}
|
|
|
|
.right-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 12px;
|
|
display: none;
|
|
}
|
|
|
|
.right-content.active {
|
|
display: block;
|
|
}
|
|
|
|
.inspector-field {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.inspector-field label {
|
|
display: block;
|
|
font-size: 11px;
|
|
color: var(--muted);
|
|
margin-bottom: 4px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.inspector-field input,
|
|
.inspector-field select,
|
|
.inspector-field textarea {
|
|
width: 100%;
|
|
padding: 6px;
|
|
background: var(--surface2);
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
color: var(--text);
|
|
font-size: 11px;
|
|
font-family: inherit;
|
|
}
|
|
|
|
.inspector-field input:focus,
|
|
.inspector-field select:focus,
|
|
.inspector-field textarea:focus {
|
|
outline: none;
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.log-entry {
|
|
padding: 6px;
|
|
margin-bottom: 4px;
|
|
background: var(--surface2);
|
|
border-left: 2px solid var(--accent);
|
|
font-size: 11px;
|
|
font-family: monospace;
|
|
color: var(--muted);
|
|
}
|
|
|
|
/* ── Bottom Status Bar ── */
|
|
.status-bar {
|
|
flex-shrink: 0;
|
|
background: var(--surface2);
|
|
border-top: 1px solid var(--border);
|
|
padding: 8px 16px;
|
|
font-size: 11px;
|
|
color: var(--muted);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 24px;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.status-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.status-value {
|
|
color: var(--text);
|
|
font-weight: 600;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ── Header ── -->
|
|
<header>
|
|
<div class="header-bar">
|
|
<div id="status-dot"></div>
|
|
<h1>Re<span>-Commander</span> — Animator</h1>
|
|
<div class="header-status">
|
|
<span id="status-label">Connecting…</span>
|
|
<span id="hotword-indicator"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="toolbar">
|
|
<!-- File Operations -->
|
|
<div class="toolbar-group">
|
|
<button id="btn-new">📄 New</button>
|
|
<button id="btn-open">📂 Open</button>
|
|
<button id="btn-save">💾 Save</button>
|
|
</div>
|
|
|
|
<div class="toolbar-sep"></div>
|
|
|
|
<!-- Edit -->
|
|
<div class="toolbar-group">
|
|
<button id="btn-undo">↶ Undo</button>
|
|
<button id="btn-redo">↷ Redo</button>
|
|
</div>
|
|
|
|
<div class="toolbar-sep"></div>
|
|
|
|
<!-- Animation Control -->
|
|
<div class="toolbar-group">
|
|
<button id="btn-play" style="background:var(--success);border-color:var(--success);">Play</button>
|
|
<button id="btn-pause">Pause</button>
|
|
<button id="btn-stop" class="danger">Stop</button>
|
|
</div>
|
|
|
|
<div class="toolbar-sep"></div>
|
|
|
|
<!-- Timeline -->
|
|
<div class="toolbar-group">
|
|
<button id="btn-timeline">Timeline</button>
|
|
<button id="btn-preview">Preview</button>
|
|
</div>
|
|
|
|
<div class="toolbar-spacer"></div>
|
|
|
|
<!-- Right Side -->
|
|
<div class="toolbar-group">
|
|
<button id="btn-settings">Settings</button>
|
|
<button id="btn-back-home">← Home</button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- ── Main Content ── -->
|
|
<div class="main-container">
|
|
|
|
<!-- Left Sidebar - Library -->
|
|
<div class="left-panel">
|
|
<div class="panel-header">Animation Library</div>
|
|
<div class="panel-content">
|
|
<div class="library-item">Eye_Blink_01</div>
|
|
<div class="library-item">Eye_Blink_02</div>
|
|
<div class="library-item">Eye_Double_Blink</div>
|
|
<div class="library-item">eye_happy_01</div>
|
|
<div class="library-item">eye_happy_02</div>
|
|
<div class="library-item">eye_sad_01</div>
|
|
<div class="library-item">eye_scared_00</div>
|
|
<div class="library-item">Eye_Curious_01</div>
|
|
<div class="library-item">Eye_Look_Center</div>
|
|
<div class="library-item">Eye_Look_Left</div>
|
|
<div class="library-item">Eye_Look_Right</div>
|
|
<div class="library-item">Eye_Look_Up</div>
|
|
<div class="library-item">Eye_Look_Down</div>
|
|
<div class="library-item">Gesture_Wave</div>
|
|
<div class="library-item">Gesture_Nod</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Center - Canvas/Preview Area -->
|
|
<div class="center-panel">
|
|
<div class="center-tabs">
|
|
<div class="center-tab active" data-tab="canvas">Canvas</div>
|
|
<div class="center-tab" data-tab="preview">🎬 Preview</div>
|
|
</div>
|
|
<div class="center-content">
|
|
Imagine a 3d jibo model in a theater kinda thing
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Sidebar - Properties & Log -->
|
|
<div class="right-panel">
|
|
<div class="right-tabs">
|
|
<button class="right-tab active" data-panel="inspector">Inspector</button>
|
|
<button class="right-tab" data-panel="properties">Properties</button>
|
|
<button class="right-tab" data-panel="log">Log</button>
|
|
</div>
|
|
|
|
<!-- Inspector Panel -->
|
|
<div class="right-content active" id="inspector-panel">
|
|
<div class="inspector-field">
|
|
<label>Animation Name</label>
|
|
<input type="text" placeholder="Select animation...">
|
|
</div>
|
|
<div class="inspector-field">
|
|
<label>Duration (ms)</label>
|
|
<input type="number" value="500" min="0">
|
|
</div>
|
|
<div class="inspector-field">
|
|
<label>Repeat Count</label>
|
|
<input type="number" value="1" min="1">
|
|
</div>
|
|
<div class="inspector-field">
|
|
<label>Delay (ms)</label>
|
|
<input type="number" value="0" min="0" step="100">
|
|
</div>
|
|
<div class="inspector-field">
|
|
<label>Easing</label>
|
|
<select>
|
|
<option>Linear</option>
|
|
<option>Ease In</option>
|
|
<option>Ease Out</option>
|
|
<option>Ease In Out</option>
|
|
</select>
|
|
</div>
|
|
<button style="width:100%; padding:10px; margin-top:12px; background:var(--accent); color:#000; border:none; border-radius:4px; font-weight:600; cursor:pointer;">✨ Apply Animation</button>
|
|
</div>
|
|
|
|
<!-- Properties Panel -->
|
|
<div class="right-content" id="properties-panel">
|
|
<div class="inspector-field">
|
|
<label>Preview Mode</label>
|
|
<select>
|
|
<option>Normal</option>
|
|
<option>Loop</option>
|
|
<option>Once</option>
|
|
</select>
|
|
</div>
|
|
<div class="inspector-field">
|
|
<label>Resolution</label>
|
|
<select>
|
|
<option>High</option>
|
|
<option>Medium</option>
|
|
<option>Low</option>
|
|
</select>
|
|
</div>
|
|
<div class="inspector-field">
|
|
<label>Camera Angle</label>
|
|
<input type="range" min="0" max="360" value="0">
|
|
</div>
|
|
<div class="inspector-field">
|
|
<label>Playback Speed</label>
|
|
<input type="range" min="0.5" max="2" step="0.1" value="1">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Log Panel -->
|
|
<div class="right-content" id="log-panel">
|
|
<div id="event-log" style="font-size:11px;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- ── Status Bar ── -->
|
|
<div class="status-bar">
|
|
<div class="status-item">
|
|
<span>Mode:</span>
|
|
<span class="status-value">Virtual Robot</span>
|
|
</div>
|
|
<div class="status-item">
|
|
<span>Animation:</span>
|
|
<span class="status-value" id="status-animation">None</span>
|
|
</div>
|
|
<div class="status-item">
|
|
<span>Status:</span>
|
|
<span class="status-value" id="status-playback">Ready</span>
|
|
</div>
|
|
<div class="status-item" style="margin-left:auto;">
|
|
<span id="status-info">Ready for animation</span>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="animator.js"></script>
|
|
</body>
|
|
</html>
|