فهرست منبع

add vertical ticks

clovis 1 ماه پیش
والد
کامیت
5030df872c

+ 1 - 1
src/ClockBuilder.tsx

@@ -176,7 +176,7 @@ export default function ClockBuilder() {
       <div className={styles.header}>
         <div className="field">
           <label>Cycle length (ticks)</label>
-          <ExpressionInput className="dark" styles={{ max }} value={duration} min={2} onCommit={setDuration} />
+          <ExpressionInput className="dark" value={duration} min={2} onCommit={setDuration} />
         </div>
 
         <div className="field">

+ 20 - 0
src/assets/ClockTimeline/ClockTimeline.module.css

@@ -82,6 +82,24 @@
   gap: 4px;
   margin-bottom: 8px;
 }
+.gridBackground {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 0;
+  pointer-events: none;
+}
+
+/* The individual vertical lines */
+.gridLine {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  width: 1px;
+  background-color: rgba(255, 255, 255, 0.05); /* Subtle faint white line */
+}
 .rows {
   display: flex;
   flex-direction: column;
@@ -113,6 +131,8 @@
   border-radius: 4px;
   touch-action: none;
   transition: height 0.12s ease;
+  background-image: linear-gradient(90deg, #333 1px, transparent 1px);
+  background-position: 0 0;
 }
 
 .block {

+ 32 - 7
src/assets/ClockTimeline/ClockTimeline.tsx

@@ -15,15 +15,40 @@ export const defaultActivationSignal = {
   order: "a[checked]",
 };
 
+const MIN_TICK_DISTANCE_PX = 100;
+
 export default function ClockTimeline({}: Props) {
   const { duration, pixelsPerTick, rowOrder, alignmentTick, addRow } = useClockStore();
   const timelineWidth = duration * pixelsPerTick;
-  const majorTicks = useMemo(() => {
-    const step = Math.max(1, Math.round(duration / 10));
+  const { majorTicks, step } = useMemo(() => {
+    const rawStep = MIN_TICK_DISTANCE_PX / pixelsPerTick;
+    let step = 1;
+    if (rawStep > 1) {
+      // Find the order of magnitude (e.g., 10, 100, 1000)
+      const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
+
+      // Normalize the step to a number between 1 and 10
+      const normalized = rawStep / magnitude;
+
+      // Snap to 1, 2, 5, or 10 based on proximity
+      if (normalized < 1.5) step = 1 * magnitude;
+      else if (normalized < 3.5) step = 2 * magnitude;
+      else if (normalized < 7.5) step = 5 * magnitude;
+      else step = 10 * magnitude;
+    }
+
+    // Generate the ticks
     const out: number[] = [];
-    for (let t = 0; t <= duration; t += step) out.push(t);
-    return out;
-  }, [duration]);
+    for (let t = step; t <= duration; t += step) out.push(t);
+
+    // Ensure the final duration tick is always drawn (optional but looks nice)
+    if (out[out.length - 1] === duration) {
+      out.pop();
+    }
+
+    return { step: step, majorTicks: out };
+  }, [duration, pixelsPerTick]);
+
   const onPaletteDragStart = (e: React.DragEvent, presetId: string) => {
     e.dataTransfer.setData("text/plain", presetId);
     e.dataTransfer.effectAllowed = "copy";
@@ -53,7 +78,7 @@ export default function ClockTimeline({}: Props) {
       </div>
       <div className={styles.scrollWrapper}>
         <div className={styles.scrollContent}>
-          <div className={styles.ruler} style={{ width: timelineWidth }}>
+          <div className={styles.ruler} style={{ width: timelineWidth, minWidth: "100cqw" }}>
             {majorTicks.map((t) => (
               <div key={t} className={styles.rulerTick} style={{ left: `${(t / duration) * 100}%` }}>
                 <span>{t}</span>
@@ -67,7 +92,7 @@ export default function ClockTimeline({}: Props) {
           )}
 
           {rowOrder.map((rowId) => (
-            <TimelineRow key={rowId} rowId={rowId} />
+            <TimelineRow key={rowId} rowId={rowId} step={step} />
           ))}
         </div>
       </div>

+ 2 - 2
src/assets/ClockTimeline/TimelineRow.tsx

@@ -36,7 +36,7 @@ function packLanes(instances: { id: string; blockId: string; start: number; dura
 }
 const LANE_HEIGHT = 30;
 const GAP = 4;
-export default function TimelineRow({ rowId }: { rowId: string }) {
+export default function TimelineRow({ rowId, step }: { rowId: string; step?: number }) {
   const { updateRow, removeRow, addBlocks, selectBlocks, blocks, rows, duration, selectedBlockIds, alignmentTick } =
     useClockStore();
   const { onPointerDownBlock, onPointerMove, onPointerUp, pxToTick } = useTimelineDrag();
@@ -165,7 +165,7 @@ export default function TimelineRow({ rowId }: { rowId: string }) {
 
       <div
         className={styles.lane}
-        style={{ height: laneAreaHeight }}
+        style={{ height: laneAreaHeight, backgroundSize: `${((step ?? 0) / duration) * 100}% 100%` }}
         ref={laneRef}
         onDragOver={(e) => e.preventDefault()}
         onDrop={handleDrop}