aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-09-03 19:10:42 +0200
committeruser <user@clank>2026-09-03 19:10:42 +0200
commitc7c1a8a8973ab6596d9eecafc9411fbfd519a803 (patch)
treea238d24d24074ac4c6f73f0205d01355e1435c71
parentpane: drop the render snapshot of panes on hidden tabs -- 154K -> 66K each (diff)
downloadslosh-c7c1a8a8973ab6596d9eecafc9411fbfd519a803.tar.gz
slosh-c7c1a8a8973ab6596d9eecafc9411fbfd519a803.tar.xz
slosh-c7c1a8a8973ab6596d9eecafc9411fbfd519a803.zip
web/recordings: a move cursor while the pointer drags
The cast already marks the button in the ptr track ([x, y, 1]); the player now remembers the cell where it went down and, the moment the pointer leaves it, swaps the arrow for a four-way move cursor (a clip-path, like the arrow) centred on the old tip. A still click never triggers it, so the border-click split keeps its arrow while the gap drag and both pane-carries in the panes demo read as carrying. Player-side only: every existing cast gets it without re-rendering.
-rw-r--r--web/recordings/player.css17
-rw-r--r--web/recordings/player.js28
2 files changed, 43 insertions, 2 deletions
diff --git a/web/recordings/player.css b/web/recordings/player.css
index cbeb052..140bcf8 100644
--- a/web/recordings/player.css
+++ b/web/recordings/player.css
@@ -89,6 +89,23 @@
background: #ff5fd7;
}
+/* Dragging: the button is down and the pointer has left the cell it went
+ * down in (the player works this out from the ptr track; a still click
+ * never triggers it). The arrow gives way to a four-way move cursor,
+ * centred on the old tip so the grip point does not jump -- a pane carried
+ * by its title, or a gap in tow, reads as "dragging" at a glance. */
+.sloshcast .sc-pointer.sc-dragging {
+ width: 1.35em;
+ height: 1.35em;
+ transform: translate(-50%, -50%);
+ clip-path: polygon(
+ 50% 0%, 66% 18%, 56% 18%, 56% 44%, 82% 44%, 82% 34%, 100% 50%,
+ 82% 66%, 82% 56%, 56% 56%, 56% 82%, 66% 82%, 50% 100%, 34% 82%,
+ 44% 82%, 44% 56%, 18% 56%, 18% 66%, 0% 50%, 18% 34%, 18% 44%,
+ 44% 44%, 44% 18%, 34% 18%
+ );
+}
+
/* The big play glyph over the poster; gone while playing. */
.sloshcast .sc-play {
position: absolute;
diff --git a/web/recordings/player.js b/web/recordings/player.js
index 2480eb5..28efb2f 100644
--- a/web/recordings/player.js
+++ b/web/recordings/player.js
@@ -241,6 +241,8 @@ function mountSloshcast(el, data, opts = {}) {
let rowEls = [];
let rowsData = []; // retained [text, runs] per row: the canvas reads it
+ let ptrDown = null; // cell where the button went down, while it is down
+ let ptrDrag = false; // it went down and then moved: a drag, not a click
let gcols = data.cols, grows = data.rows;
let cellW = 8, cellH = 17, dpr = 1;
let canvasDirty = false;
@@ -285,8 +287,27 @@ function mountSloshcast(el, data, opts = {}) {
pointer.style.top = rowEls[ev.ptr[1]]
? rowEls[ev.ptr[1]].offsetTop + "px"
: "0";
- pointer.classList.toggle("sc-pressed", !!ev.ptr[2]);
- } else pointer.style.display = "none";
+ // A drag is a press that has moved: the cast marks the button
+ // ([x, y, 1]), and the cell where it went down is remembered, so
+ // the moment the pointer leaves it the cursor can say "carrying"
+ // -- a pane re-order or a gap drag -- instead of a stuck click.
+ const down = !!ev.ptr[2];
+ if (down) {
+ if (!ptrDown) ptrDown = [ev.ptr[0], ev.ptr[1]];
+ else if (ev.ptr[0] !== ptrDown[0] || ev.ptr[1] !== ptrDown[1])
+ ptrDrag = true;
+ } else {
+ ptrDown = null;
+ ptrDrag = false;
+ }
+ pointer.classList.toggle("sc-pressed", down);
+ pointer.classList.toggle("sc-dragging", ptrDrag);
+ } else {
+ pointer.style.display = "none";
+ ptrDown = null;
+ ptrDrag = false;
+ pointer.classList.remove("sc-pressed", "sc-dragging");
+ }
}
canvasDirty = true;
}
@@ -400,6 +421,9 @@ function mountSloshcast(el, data, opts = {}) {
idx = 0;
t = to;
pointer.style.display = "none";
+ ptrDown = null;
+ ptrDrag = false;
+ pointer.classList.remove("sc-pressed", "sc-dragging");
grid(data.cols, data.rows);
while (idx < data.events.length && data.events[idx].t <= to)
apply(data.events[idx++]);