fix(camera-toggle): toolbar-wide ant line gone; ants only while running

The toggle's attention border reused the .velxio-ants class name, which
is ALSO the canvas selection outline whose ::after is position:absolute
- on the non-positioned button it anchored to the toolbar and drew a
marching-ant line across its full width. Renamed the button variant to
.velxio-btn-ants. The ants also showed while the simulation was stopped;
now they only run when the sketch is running and the camera is off (the
only moment the button is actually asking for a click).
This commit is contained in:
David Montero Crespo 2026-08-04 16:12:50 +02:00
parent e96dae794a
commit 5a71023ac9
2 changed files with 16 additions and 9 deletions

View File

@ -457,11 +457,15 @@ body {
four thin repeating-gradient strips, one per edge, sliding one dash
period per cycle. Drawn as backgrounds rather than a border because a
CSS border cannot animate its dash offset. Uses currentColor so the
ants inherit the button's state colour (grey idle, red on error). */
ants inherit the button's state colour (grey idle, red on error).
NOT named .velxio-ants: that class is the canvas selection outline
(SimulatorCanvas.css) whose ::after is position:absolute — on a
non-positioned button it anchored to the toolbar and drew a
toolbar-wide ant line. */
@keyframes velxio-marching-ants {
to { background-position: 12px 0, -12px 100%, 0 -12px, 100% 12px; }
}
.velxio-ants {
.velxio-btn-ants {
background-image:
repeating-linear-gradient(90deg, currentColor 0 6px, transparent 6px 12px),
repeating-linear-gradient(90deg, currentColor 0 6px, transparent 6px 12px),
@ -473,7 +477,7 @@ body {
animation: velxio-marching-ants 0.7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.velxio-ants { animation: none; }
.velxio-btn-ants { animation: none; }
}
/* ── Editor: toolbar riding inside the header ─────────────────────────────

View File

@ -103,11 +103,14 @@ export const CameraToggle: React.FC<CameraToggleProps> = ({ boardId }) => {
onClick={handleClick}
disabled={!boardId || status === 'requesting'}
title={tooltip}
// Ants while the button wants a click (idle after a failed/stopped
// auto-start, denied, error). Solid border once streaming or asking.
// Ants while the button wants a click DURING a run (idle after a
// failed/stopped auto-start, denied, error): a camera sketch is
// starving without frames. Never while the sim is stopped — the
// button is not asking for anything then. Solid border once
// streaming or asking.
className={
boardId && status !== 'streaming' && status !== 'requesting'
? 'velxio-ants'
running && boardId && status !== 'streaming' && status !== 'requesting'
? 'velxio-btn-ants'
: undefined
}
style={{
@ -126,8 +129,8 @@ export const CameraToggle: React.FC<CameraToggleProps> = ({ boardId }) => {
fontSize: 13,
cursor: boardId ? 'pointer' : 'not-allowed',
// Inline only while requesting. 'none' here would OVERRIDE the
// .velxio-ants class animation (inline beats class), which is exactly
// how the ants shipped dead the first time.
// .velxio-btn-ants class animation (inline beats class), which is
// exactly how the ants shipped dead the first time.
animation:
status === 'requesting'
? 'velxio-pulse 1s ease-in-out infinite'