diff --git a/web/src/coaster/AccelerationStripsPanel.module.css b/web/src/coaster/AccelerationStripsPanel.module.css index 3c03966..c9dd9f4 100644 --- a/web/src/coaster/AccelerationStripsPanel.module.css +++ b/web/src/coaster/AccelerationStripsPanel.module.css @@ -1,9 +1,5 @@ .panel { - position: fixed; - right: 16px; - top: 60px; - z-index: 600; - width: 280px; + width: 340px; background: rgba(8, 8, 12, 0.84); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); @@ -57,7 +53,7 @@ .stripRow { display: flex; align-items: center; - gap: 6px; + gap: 5px; margin-bottom: 6px; font-size: 12px; } @@ -66,37 +62,17 @@ color: rgba(245, 158, 11, 0.9); font-weight: 600; min-width: 44px; + flex-shrink: 0; } -.stripRange { - color: rgba(255, 255, 255, 0.38); - font-size: 11px; - min-width: 56px; -} - -.accelInput { - width: 50px; - background: rgba(255, 255, 255, 0.07); - border: 1px solid rgba(255, 255, 255, 0.14); - border-radius: 6px; - color: #fff; - font-size: 13px; - font-weight: 600; - padding: 2px 5px; - text-align: right; -} -.accelInput:focus { - outline: none; - border-color: rgba(245, 158, 11, 0.5); -} - -.stripUnit { +.rangeSep { color: rgba(255, 255, 255, 0.28); font-size: 11px; } .stripDelete { margin-left: auto; + flex-shrink: 0; width: 20px; height: 20px; border-radius: 4px; diff --git a/web/src/coaster/AccelerationStripsPanel.tsx b/web/src/coaster/AccelerationStripsPanel.tsx index ef695f8..28e6a00 100644 --- a/web/src/coaster/AccelerationStripsPanel.tsx +++ b/web/src/coaster/AccelerationStripsPanel.tsx @@ -1,16 +1,16 @@ import { useState, useEffect } from 'react' import type { AccelerationStrip } from '../types/api' +import { BlenderInput } from '../ui/BlenderInput' import styles from './AccelerationStripsPanel.module.css' interface Props { strips: AccelerationStrip[] onRemoveStrip: (id: string) => void onUpdateStrip: (id: string, accel_ms2: number) => void + onUpdateStripFrac: (id: string, startFrac: number, endFrac: number) => void } -function pct(v: number) { return `${(v * 100).toFixed(0)}%` } - -export function AccelerationStripsPanel({ strips, onRemoveStrip, onUpdateStrip }: Props) { +export function AccelerationStripsPanel({ strips, onRemoveStrip, onUpdateStrip, onUpdateStripFrac }: Props) { const [open, setOpen] = useState(true) // Auto-open when a strip is added @@ -31,19 +31,45 @@ export function AccelerationStripsPanel({ strips, onRemoveStrip, onUpdateStrip } : strips.map((s, i) => (
Strip {i + 1} - - {pct(s.startFrac)}–{pct(s.endFrac)} - - { + const sf = Math.max(0, Math.min(v / 100, s.endFrac - 0.001)) + onUpdateStripFrac(s.id, sf, s.endFrac) + }} + min={0} + max={s.endFrac * 100 - 0.1} + step={0.2} + decimals={1} + suffix="%" + /> + + + + { + const ef = Math.min(100, Math.max(v / 100, s.startFrac + 0.001)) + onUpdateStripFrac(s.id, s.startFrac, ef) + }} + min={s.startFrac * 100 + 0.1} + max={100} + step={0.2} + decimals={1} + suffix="%" + /> + + onUpdateStrip(s.id, v)} min={-50} max={50} - value={s.accel_ms2} - onChange={e => onUpdateStrip(s.id, Number(e.target.value))} - className={styles.accelInput} + step={0.1} + decimals={1} + suffix="m/s²" /> - m/s² +