Pause linked playback while hovering
Browse files- assets/dataset_link.js +35 -16
assets/dataset_link.js
CHANGED
|
@@ -50,7 +50,7 @@
|
|
| 50 |
makeElement(
|
| 51 |
"span",
|
| 52 |
"dataset-link-hint",
|
| 53 |
-
"Playback loops automatically.
|
| 54 |
)
|
| 55 |
);
|
| 56 |
|
|
@@ -207,38 +207,56 @@
|
|
| 207 |
|
| 208 |
function bindInteractions(state) {
|
| 209 |
const abort = state.abortController;
|
| 210 |
-
const
|
|
|
|
|
|
|
| 211 |
const index = eventIndex(state, event);
|
| 212 |
if (index === null) return;
|
| 213 |
-
|
|
|
|
| 214 |
renderIndex(state, index);
|
| 215 |
-
if (keepPlaying) play(state);
|
| 216 |
};
|
| 217 |
-
|
|
|
|
| 218 |
const point = event && event.points && event.points[0];
|
| 219 |
-
if (!point || point.curveNumber !== state.exampleTrace) return;
|
| 220 |
const index = eventIndex(state, event);
|
| 221 |
if (index === null) return;
|
| 222 |
-
|
|
|
|
| 223 |
renderIndex(state, index);
|
| 224 |
-
if (keepPlaying) play(state);
|
| 225 |
};
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
state.plotlyListeners = [
|
| 231 |
-
[state.neural, "plotly_hover",
|
| 232 |
-
[state.neural, "plotly_click",
|
| 233 |
-
[state.target, "plotly_hover",
|
| 234 |
-
[state.target, "plotly_click",
|
| 235 |
];
|
|
|
|
|
|
|
| 236 |
|
| 237 |
state.button.addEventListener("click", () => {
|
|
|
|
| 238 |
if (state.playing) pause(state);
|
| 239 |
else play(state);
|
| 240 |
}, { signal: abort.signal });
|
| 241 |
state.slider.addEventListener("input", () => {
|
|
|
|
| 242 |
pause(state);
|
| 243 |
renderIndex(state, Number(state.slider.value));
|
| 244 |
}, { signal: abort.signal });
|
|
@@ -297,6 +315,7 @@
|
|
| 297 |
cursorTrace,
|
| 298 |
index: payload.initial_index || 0,
|
| 299 |
playing: false,
|
|
|
|
| 300 |
animationFrame: null,
|
| 301 |
renderFrame: null,
|
| 302 |
autoplayTimer: null,
|
|
|
|
| 50 |
makeElement(
|
| 51 |
"span",
|
| 52 |
"dataset-link-hint",
|
| 53 |
+
"Playback loops automatically. Hover to pause; scrub to inspect."
|
| 54 |
)
|
| 55 |
);
|
| 56 |
|
|
|
|
| 207 |
|
| 208 |
function bindInteractions(state) {
|
| 209 |
const abort = state.abortController;
|
| 210 |
+
const pauseForHover = (event, fromTarget) => {
|
| 211 |
+
const point = event && event.points && event.points[0];
|
| 212 |
+
if (fromTarget && (!point || point.curveNumber !== state.exampleTrace)) return;
|
| 213 |
const index = eventIndex(state, event);
|
| 214 |
if (index === null) return;
|
| 215 |
+
if (state.playing) state.resumeAfterHover = true;
|
| 216 |
+
pause(state);
|
| 217 |
renderIndex(state, index);
|
|
|
|
| 218 |
};
|
| 219 |
+
|
| 220 |
+
const holdSelection = (event, fromTarget) => {
|
| 221 |
const point = event && event.points && event.points[0];
|
| 222 |
+
if (fromTarget && (!point || point.curveNumber !== state.exampleTrace)) return;
|
| 223 |
const index = eventIndex(state, event);
|
| 224 |
if (index === null) return;
|
| 225 |
+
state.resumeAfterHover = false;
|
| 226 |
+
pause(state);
|
| 227 |
renderIndex(state, index);
|
|
|
|
| 228 |
};
|
| 229 |
+
|
| 230 |
+
const neuralHover = (event) => pauseForHover(event, false);
|
| 231 |
+
const neuralClick = (event) => holdSelection(event, false);
|
| 232 |
+
const targetHover = (event) => pauseForHover(event, true);
|
| 233 |
+
const targetClick = (event) => holdSelection(event, true);
|
| 234 |
+
const resumeAfterHover = () => {
|
| 235 |
+
if (!state.resumeAfterHover || activeState !== state) return;
|
| 236 |
+
state.resumeAfterHover = false;
|
| 237 |
+
play(state);
|
| 238 |
+
};
|
| 239 |
+
|
| 240 |
+
state.neural.on("plotly_hover", neuralHover);
|
| 241 |
+
state.neural.on("plotly_click", neuralClick);
|
| 242 |
+
state.target.on("plotly_hover", targetHover);
|
| 243 |
+
state.target.on("plotly_click", targetClick);
|
| 244 |
state.plotlyListeners = [
|
| 245 |
+
[state.neural, "plotly_hover", neuralHover],
|
| 246 |
+
[state.neural, "plotly_click", neuralClick],
|
| 247 |
+
[state.target, "plotly_hover", targetHover],
|
| 248 |
+
[state.target, "plotly_click", targetClick],
|
| 249 |
];
|
| 250 |
+
state.neural.addEventListener("mouseleave", resumeAfterHover, { signal: abort.signal });
|
| 251 |
+
state.target.addEventListener("mouseleave", resumeAfterHover, { signal: abort.signal });
|
| 252 |
|
| 253 |
state.button.addEventListener("click", () => {
|
| 254 |
+
state.resumeAfterHover = false;
|
| 255 |
if (state.playing) pause(state);
|
| 256 |
else play(state);
|
| 257 |
}, { signal: abort.signal });
|
| 258 |
state.slider.addEventListener("input", () => {
|
| 259 |
+
state.resumeAfterHover = false;
|
| 260 |
pause(state);
|
| 261 |
renderIndex(state, Number(state.slider.value));
|
| 262 |
}, { signal: abort.signal });
|
|
|
|
| 315 |
cursorTrace,
|
| 316 |
index: payload.initial_index || 0,
|
| 317 |
playing: false,
|
| 318 |
+
resumeAfterHover: false,
|
| 319 |
animationFrame: null,
|
| 320 |
renderFrame: null,
|
| 321 |
autoplayTimer: null,
|