Spaces:
Running
Running
UI improvements: official icon, bigger joystick, simplified controls
Browse files- Replace custom SVG with official Reachy Mini icon from desktop app
- Remove Motors panel and Animations panel
- Make joystick and roll slider larger (200px/180px)
- Cleaner sidebar with only essential controls
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- index.html +35 -71
index.html
CHANGED
|
@@ -54,9 +54,10 @@
|
|
| 54 |
gap: 12px;
|
| 55 |
}
|
| 56 |
|
| 57 |
-
.logo
|
| 58 |
width: 36px;
|
| 59 |
height: 36px;
|
|
|
|
| 60 |
}
|
| 61 |
|
| 62 |
.logo-text {
|
|
@@ -332,18 +333,19 @@
|
|
| 332 |
/* Joystick */
|
| 333 |
.joystick-container {
|
| 334 |
display: flex;
|
| 335 |
-
gap:
|
| 336 |
align-items: center;
|
| 337 |
justify-content: center;
|
|
|
|
| 338 |
}
|
| 339 |
|
| 340 |
.joystick-area {
|
| 341 |
-
width:
|
| 342 |
-
height:
|
| 343 |
background: radial-gradient(circle at center, var(--pollen-card-light) 0%, var(--pollen-darker) 100%);
|
| 344 |
border-radius: 50%;
|
| 345 |
position: relative;
|
| 346 |
-
border:
|
| 347 |
touch-action: none;
|
| 348 |
cursor: grab;
|
| 349 |
}
|
|
@@ -353,64 +355,67 @@
|
|
| 353 |
}
|
| 354 |
|
| 355 |
.joystick-knob {
|
| 356 |
-
width:
|
| 357 |
-
height:
|
| 358 |
background: var(--pollen-coral);
|
| 359 |
border-radius: 50%;
|
| 360 |
position: absolute;
|
| 361 |
top: 50%;
|
| 362 |
left: 50%;
|
| 363 |
transform: translate(-50%, -50%);
|
| 364 |
-
box-shadow: 0 4px
|
| 365 |
pointer-events: none;
|
| 366 |
transition: box-shadow 0.2s;
|
| 367 |
}
|
| 368 |
|
| 369 |
.joystick-area:active .joystick-knob {
|
| 370 |
-
box-shadow: 0 6px
|
| 371 |
}
|
| 372 |
|
| 373 |
.joystick-labels {
|
| 374 |
position: absolute;
|
| 375 |
-
font-size: 0.
|
| 376 |
color: var(--text-muted);
|
|
|
|
| 377 |
}
|
| 378 |
|
| 379 |
-
.joystick-labels.top { top:
|
| 380 |
-
.joystick-labels.bottom { bottom:
|
| 381 |
-
.joystick-labels.left { left:
|
| 382 |
-
.joystick-labels.right { right:
|
| 383 |
|
| 384 |
.z-slider-container {
|
| 385 |
display: flex;
|
| 386 |
flex-direction: column;
|
| 387 |
align-items: center;
|
| 388 |
-
gap:
|
| 389 |
}
|
| 390 |
|
| 391 |
.z-slider {
|
| 392 |
writing-mode: vertical-lr;
|
| 393 |
direction: rtl;
|
| 394 |
-
height:
|
| 395 |
-
width:
|
| 396 |
-webkit-appearance: none;
|
| 397 |
background: var(--pollen-darker);
|
| 398 |
-
border-radius:
|
|
|
|
| 399 |
}
|
| 400 |
|
| 401 |
.z-slider::-webkit-slider-thumb {
|
| 402 |
-webkit-appearance: none;
|
| 403 |
-
width:
|
| 404 |
-
height:
|
| 405 |
background: var(--pollen-coral);
|
| 406 |
border-radius: 50%;
|
| 407 |
cursor: pointer;
|
| 408 |
-
box-shadow: 0 2px
|
| 409 |
}
|
| 410 |
|
| 411 |
.z-label {
|
| 412 |
-
font-size: 0.
|
| 413 |
color: var(--text-muted);
|
|
|
|
| 414 |
}
|
| 415 |
|
| 416 |
/* Sliders */
|
|
@@ -758,7 +763,11 @@
|
|
| 758 |
}
|
| 759 |
|
| 760 |
.joystick-area {
|
| 761 |
-
width:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 762 |
height: 140px;
|
| 763 |
}
|
| 764 |
|
|
@@ -781,14 +790,7 @@
|
|
| 781 |
<!-- Login View -->
|
| 782 |
<div id="loginView" class="login-view">
|
| 783 |
<div class="login-card">
|
| 784 |
-
<
|
| 785 |
-
<circle cx="50" cy="50" r="45" stroke="#FF6B35" stroke-width="4"/>
|
| 786 |
-
<circle cx="35" cy="40" r="8" fill="#FF6B35"/>
|
| 787 |
-
<circle cx="65" cy="40" r="8" fill="#FF6B35"/>
|
| 788 |
-
<path d="M30 60 Q50 80 70 60" stroke="#FF6B35" stroke-width="4" fill="none" stroke-linecap="round"/>
|
| 789 |
-
<path d="M25 20 L35 35" stroke="#FF6B35" stroke-width="3" stroke-linecap="round"/>
|
| 790 |
-
<path d="M75 20 L65 35" stroke="#FF6B35" stroke-width="3" stroke-linecap="round"/>
|
| 791 |
-
</svg>
|
| 792 |
<h2>Reachy Mini</h2>
|
| 793 |
<p>Sign in with your HuggingFace account to connect and control your robot remotely.</p>
|
| 794 |
<button class="btn-hf" onclick="loginToHuggingFace()">
|
|
@@ -804,14 +806,7 @@
|
|
| 804 |
<div id="mainApp" class="hidden">
|
| 805 |
<header class="header">
|
| 806 |
<div class="logo">
|
| 807 |
-
<
|
| 808 |
-
<circle cx="50" cy="50" r="45" stroke="#FF6B35" stroke-width="4"/>
|
| 809 |
-
<circle cx="35" cy="40" r="8" fill="#FF6B35"/>
|
| 810 |
-
<circle cx="65" cy="40" r="8" fill="#FF6B35"/>
|
| 811 |
-
<path d="M30 60 Q50 80 70 60" stroke="#FF6B35" stroke-width="4" fill="none" stroke-linecap="round"/>
|
| 812 |
-
<path d="M25 20 L35 35" stroke="#FF6B35" stroke-width="3" stroke-linecap="round"/>
|
| 813 |
-
<path d="M75 20 L65 35" stroke="#FF6B35" stroke-width="3" stroke-linecap="round"/>
|
| 814 |
-
</svg>
|
| 815 |
<div class="logo-text">Reachy Mini <span>by Pollen Robotics</span></div>
|
| 816 |
</div>
|
| 817 |
<div class="user-section">
|
|
@@ -890,18 +885,6 @@
|
|
| 890 |
|
| 891 |
<!-- Control Sidebar -->
|
| 892 |
<div class="control-sidebar">
|
| 893 |
-
<!-- Motors -->
|
| 894 |
-
<div class="panel">
|
| 895 |
-
<div class="panel-header">Motors</div>
|
| 896 |
-
<div class="panel-content">
|
| 897 |
-
<div class="motor-grid">
|
| 898 |
-
<button class="motor-btn on" id="btnMotorOn" onclick="setMotorMode('enabled')" disabled>ON</button>
|
| 899 |
-
<button class="motor-btn off" id="btnMotorOff" onclick="setMotorMode('disabled')" disabled>OFF</button>
|
| 900 |
-
<button class="motor-btn gravity" id="btnMotorGrav" onclick="setMotorMode('gravity_compensation')" disabled>Gravity</button>
|
| 901 |
-
</div>
|
| 902 |
-
</div>
|
| 903 |
-
</div>
|
| 904 |
-
|
| 905 |
<!-- Joystick Control -->
|
| 906 |
<div class="panel">
|
| 907 |
<div class="panel-header">Position Control (Relative)</div>
|
|
@@ -982,17 +965,6 @@
|
|
| 982 |
</div>
|
| 983 |
</div>
|
| 984 |
|
| 985 |
-
<!-- Animations -->
|
| 986 |
-
<div class="panel">
|
| 987 |
-
<div class="panel-header">Animations</div>
|
| 988 |
-
<div class="panel-content">
|
| 989 |
-
<div class="action-grid">
|
| 990 |
-
<button class="action-btn" id="btnWakeUp" onclick="wakeUp()" disabled>Wake Up</button>
|
| 991 |
-
<button class="action-btn" id="btnSleep" onclick="goToSleep()" disabled>Sleep</button>
|
| 992 |
-
</div>
|
| 993 |
-
</div>
|
| 994 |
-
</div>
|
| 995 |
-
|
| 996 |
<!-- Sound & Speak -->
|
| 997 |
<div class="panel">
|
| 998 |
<div class="panel-header">Sound & Speak</div>
|
|
@@ -1413,7 +1385,7 @@
|
|
| 1413 |
}
|
| 1414 |
|
| 1415 |
function enableControls(enabled) {
|
| 1416 |
-
const btns = ['
|
| 1417 |
btns.forEach(id => document.getElementById(id).disabled = !enabled);
|
| 1418 |
}
|
| 1419 |
|
|
@@ -1423,7 +1395,6 @@
|
|
| 1423 |
updateRobotState(data.state);
|
| 1424 |
} else if (data.motor_mode) {
|
| 1425 |
robotState.motorMode = data.motor_mode;
|
| 1426 |
-
updateMotorButtons(data.motor_mode);
|
| 1427 |
document.getElementById('stateMotors').textContent = data.motor_mode;
|
| 1428 |
} else if (data.error) {
|
| 1429 |
console.error('Robot error:', data.error);
|
|
@@ -1434,7 +1405,6 @@
|
|
| 1434 |
if (state.motor_mode) {
|
| 1435 |
robotState.motorMode = state.motor_mode;
|
| 1436 |
document.getElementById('stateMotors').textContent = state.motor_mode;
|
| 1437 |
-
updateMotorButtons(state.motor_mode);
|
| 1438 |
}
|
| 1439 |
|
| 1440 |
if (state.head_pose) {
|
|
@@ -1503,12 +1473,6 @@
|
|
| 1503 |
}
|
| 1504 |
}
|
| 1505 |
|
| 1506 |
-
function updateMotorButtons(mode) {
|
| 1507 |
-
document.getElementById('btnMotorOn').classList.toggle('active', mode === 'enabled');
|
| 1508 |
-
document.getElementById('btnMotorOff').classList.toggle('active', mode === 'disabled');
|
| 1509 |
-
document.getElementById('btnMotorGrav').classList.toggle('active', mode === 'gravity_compensation');
|
| 1510 |
-
}
|
| 1511 |
-
|
| 1512 |
// ===================== Joystick =====================
|
| 1513 |
function initJoystick() {
|
| 1514 |
const joystick = document.getElementById('joystick');
|
|
|
|
| 54 |
gap: 12px;
|
| 55 |
}
|
| 56 |
|
| 57 |
+
.logo img {
|
| 58 |
width: 36px;
|
| 59 |
height: 36px;
|
| 60 |
+
border-radius: 8px;
|
| 61 |
}
|
| 62 |
|
| 63 |
.logo-text {
|
|
|
|
| 333 |
/* Joystick */
|
| 334 |
.joystick-container {
|
| 335 |
display: flex;
|
| 336 |
+
gap: 24px;
|
| 337 |
align-items: center;
|
| 338 |
justify-content: center;
|
| 339 |
+
padding: 10px 0;
|
| 340 |
}
|
| 341 |
|
| 342 |
.joystick-area {
|
| 343 |
+
width: 200px;
|
| 344 |
+
height: 200px;
|
| 345 |
background: radial-gradient(circle at center, var(--pollen-card-light) 0%, var(--pollen-darker) 100%);
|
| 346 |
border-radius: 50%;
|
| 347 |
position: relative;
|
| 348 |
+
border: 3px solid var(--pollen-coral);
|
| 349 |
touch-action: none;
|
| 350 |
cursor: grab;
|
| 351 |
}
|
|
|
|
| 355 |
}
|
| 356 |
|
| 357 |
.joystick-knob {
|
| 358 |
+
width: 60px;
|
| 359 |
+
height: 60px;
|
| 360 |
background: var(--pollen-coral);
|
| 361 |
border-radius: 50%;
|
| 362 |
position: absolute;
|
| 363 |
top: 50%;
|
| 364 |
left: 50%;
|
| 365 |
transform: translate(-50%, -50%);
|
| 366 |
+
box-shadow: 0 4px 16px rgba(255,107,53,0.5);
|
| 367 |
pointer-events: none;
|
| 368 |
transition: box-shadow 0.2s;
|
| 369 |
}
|
| 370 |
|
| 371 |
.joystick-area:active .joystick-knob {
|
| 372 |
+
box-shadow: 0 6px 24px rgba(255,107,53,0.7);
|
| 373 |
}
|
| 374 |
|
| 375 |
.joystick-labels {
|
| 376 |
position: absolute;
|
| 377 |
+
font-size: 0.75em;
|
| 378 |
color: var(--text-muted);
|
| 379 |
+
font-weight: 500;
|
| 380 |
}
|
| 381 |
|
| 382 |
+
.joystick-labels.top { top: 12px; left: 50%; transform: translateX(-50%); }
|
| 383 |
+
.joystick-labels.bottom { bottom: 12px; left: 50%; transform: translateX(-50%); }
|
| 384 |
+
.joystick-labels.left { left: 10px; top: 50%; transform: translateY(-50%); }
|
| 385 |
+
.joystick-labels.right { right: 10px; top: 50%; transform: translateY(-50%); }
|
| 386 |
|
| 387 |
.z-slider-container {
|
| 388 |
display: flex;
|
| 389 |
flex-direction: column;
|
| 390 |
align-items: center;
|
| 391 |
+
gap: 10px;
|
| 392 |
}
|
| 393 |
|
| 394 |
.z-slider {
|
| 395 |
writing-mode: vertical-lr;
|
| 396 |
direction: rtl;
|
| 397 |
+
height: 180px;
|
| 398 |
+
width: 12px;
|
| 399 |
-webkit-appearance: none;
|
| 400 |
background: var(--pollen-darker);
|
| 401 |
+
border-radius: 6px;
|
| 402 |
+
border: 2px solid var(--pollen-card-light);
|
| 403 |
}
|
| 404 |
|
| 405 |
.z-slider::-webkit-slider-thumb {
|
| 406 |
-webkit-appearance: none;
|
| 407 |
+
width: 32px;
|
| 408 |
+
height: 32px;
|
| 409 |
background: var(--pollen-coral);
|
| 410 |
border-radius: 50%;
|
| 411 |
cursor: pointer;
|
| 412 |
+
box-shadow: 0 2px 10px rgba(255,107,53,0.5);
|
| 413 |
}
|
| 414 |
|
| 415 |
.z-label {
|
| 416 |
+
font-size: 0.8em;
|
| 417 |
color: var(--text-muted);
|
| 418 |
+
font-weight: 500;
|
| 419 |
}
|
| 420 |
|
| 421 |
/* Sliders */
|
|
|
|
| 763 |
}
|
| 764 |
|
| 765 |
.joystick-area {
|
| 766 |
+
width: 160px;
|
| 767 |
+
height: 160px;
|
| 768 |
+
}
|
| 769 |
+
|
| 770 |
+
.z-slider {
|
| 771 |
height: 140px;
|
| 772 |
}
|
| 773 |
|
|
|
|
| 790 |
<!-- Login View -->
|
| 791 |
<div id="loginView" class="login-view">
|
| 792 |
<div class="login-card">
|
| 793 |
+
<img class="login-logo" src="https://raw.githubusercontent.com/pollen-robotics/reachy-mini-desktop-app/develop/src-tauri/icons/128x128.png" alt="Reachy Mini">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 794 |
<h2>Reachy Mini</h2>
|
| 795 |
<p>Sign in with your HuggingFace account to connect and control your robot remotely.</p>
|
| 796 |
<button class="btn-hf" onclick="loginToHuggingFace()">
|
|
|
|
| 806 |
<div id="mainApp" class="hidden">
|
| 807 |
<header class="header">
|
| 808 |
<div class="logo">
|
| 809 |
+
<img src="https://raw.githubusercontent.com/pollen-robotics/reachy-mini-desktop-app/develop/src-tauri/icons/128x128.png" alt="Reachy Mini">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 810 |
<div class="logo-text">Reachy Mini <span>by Pollen Robotics</span></div>
|
| 811 |
</div>
|
| 812 |
<div class="user-section">
|
|
|
|
| 885 |
|
| 886 |
<!-- Control Sidebar -->
|
| 887 |
<div class="control-sidebar">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 888 |
<!-- Joystick Control -->
|
| 889 |
<div class="panel">
|
| 890 |
<div class="panel-header">Position Control (Relative)</div>
|
|
|
|
| 965 |
</div>
|
| 966 |
</div>
|
| 967 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 968 |
<!-- Sound & Speak -->
|
| 969 |
<div class="panel">
|
| 970 |
<div class="panel-header">Sound & Speak</div>
|
|
|
|
| 1385 |
}
|
| 1386 |
|
| 1387 |
function enableControls(enabled) {
|
| 1388 |
+
const btns = ['btnPlaySound', 'btnStartRec', 'btnStopRec'];
|
| 1389 |
btns.forEach(id => document.getElementById(id).disabled = !enabled);
|
| 1390 |
}
|
| 1391 |
|
|
|
|
| 1395 |
updateRobotState(data.state);
|
| 1396 |
} else if (data.motor_mode) {
|
| 1397 |
robotState.motorMode = data.motor_mode;
|
|
|
|
| 1398 |
document.getElementById('stateMotors').textContent = data.motor_mode;
|
| 1399 |
} else if (data.error) {
|
| 1400 |
console.error('Robot error:', data.error);
|
|
|
|
| 1405 |
if (state.motor_mode) {
|
| 1406 |
robotState.motorMode = state.motor_mode;
|
| 1407 |
document.getElementById('stateMotors').textContent = state.motor_mode;
|
|
|
|
| 1408 |
}
|
| 1409 |
|
| 1410 |
if (state.head_pose) {
|
|
|
|
| 1473 |
}
|
| 1474 |
}
|
| 1475 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1476 |
// ===================== Joystick =====================
|
| 1477 |
function initJoystick() {
|
| 1478 |
const joystick = document.getElementById('joystick');
|