pantdipendra commited on
Commit
865f462
·
verified ·
1 Parent(s): 0198822

arrow and highlight timeline step

Browse files
Files changed (1) hide show
  1. app.js +62 -0
app.js CHANGED
@@ -721,6 +721,8 @@ function renderTimeline() {
721
  const v = state.visible || 1;
722
  for (let i = 0; i < v; i++) addStep(host, STEPS[i], i + 1);
723
  expandDetailsForStep(state.step);
 
 
724
  }
725
 
726
  function addStep(host, step, idx) {
@@ -890,6 +892,11 @@ function expandDetailsForStep(stepNum) {
890
  const btn = document.querySelector(`button.toggle[data-fold="${current.key}"]`);
891
  if (btn) btn.setAttribute("aria-expanded", "true");
892
  }
 
 
 
 
 
893
  }
894
 
895
  /* ------------ Dots / progress ------------ */
@@ -915,6 +922,7 @@ function renderDots(visible) {
915
  askCurrent();
916
  scrollToStep(i);
917
  highlightDot();
 
918
  });
919
  }
920
  d.appendChild(dot);
@@ -959,6 +967,8 @@ function askCurrent() {
959
  }
960
 
961
  expandDetailsForStep(state.step);
 
 
962
 
963
  if (state.step === 7) {
964
  const seq = FLOW[7];
@@ -1014,6 +1024,7 @@ function goto(dest) {
1014
  askCurrent();
1015
  scrollToStep(state.step);
1016
  save(true);
 
1017
  }
1018
 
1019
  /* Called when step 1 completes to auto reveal step 2 */
@@ -1175,7 +1186,58 @@ function clearAll() {
1175
  updateProgress();
1176
  }
1177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1178
  /* ------------ Boot ------------ */
 
 
 
1179
  load();
1180
  renderPurposes();
1181
  if (state.purpose && state.purpose !== "anon") {
 
721
  const v = state.visible || 1;
722
  for (let i = 0; i < v; i++) addStep(host, STEPS[i], i + 1);
723
  expandDetailsForStep(state.step);
724
+ markCurrentStep(state.step);
725
+ requestAnimationFrame(drawLinkToFlow);
726
  }
727
 
728
  function addStep(host, step, idx) {
 
892
  const btn = document.querySelector(`button.toggle[data-fold="${current.key}"]`);
893
  if (btn) btn.setAttribute("aria-expanded", "true");
894
  }
895
+ // highlight and link
896
+ markCurrentStep(stepNum);
897
+ // Wait for layout to settle then draw the link
898
+ requestAnimationFrame(drawLinkToFlow);
899
+
900
  }
901
 
902
  /* ------------ Dots / progress ------------ */
 
922
  askCurrent();
923
  scrollToStep(i);
924
  highlightDot();
925
+ requestAnimationFrame(drawLinkToFlow);
926
  });
927
  }
928
  d.appendChild(dot);
 
967
  }
968
 
969
  expandDetailsForStep(state.step);
970
+ markCurrentStep(state.step);
971
+ requestAnimationFrame(drawLinkToFlow);
972
 
973
  if (state.step === 7) {
974
  const seq = FLOW[7];
 
1024
  askCurrent();
1025
  scrollToStep(state.step);
1026
  save(true);
1027
+ requestAnimationFrame(drawLinkToFlow);
1028
  }
1029
 
1030
  /* Called when step 1 completes to auto reveal step 2 */
 
1186
  updateProgress();
1187
  }
1188
 
1189
+ /* ------------ (a) mark the current step and (b) draw the arrow ------------ */
1190
+ function markCurrentStep(stepNum) {
1191
+ // Clear old
1192
+ $$("#timeline .step").forEach(el => el.classList.remove("current"));
1193
+ const current = document.querySelector(`.step:nth-of-type(${stepNum})`);
1194
+ if (current) current.classList.add("current");
1195
+ }
1196
+
1197
+ function drawLinkToFlow() {
1198
+ const flowEl = $("#flow");
1199
+ const svg = $("#linkSvg");
1200
+ const path = $("#linkPath");
1201
+
1202
+ // Hide arrow if flow is hidden or no current step
1203
+ const current = document.querySelector(`.step:nth-of-type(${state.step})`);
1204
+ const flowHidden = flowEl.classList.contains("hidden");
1205
+ if (!current || flowHidden) {
1206
+ if (path) path.setAttribute("d", "");
1207
+ return;
1208
+ }
1209
+
1210
+ // Dimensions
1211
+ const sRect = current.getBoundingClientRect();
1212
+ const fRect = flowEl.getBoundingClientRect();
1213
+
1214
+ // Start: bottom-center of current step card
1215
+ const x1 = sRect.left + sRect.width / 2;
1216
+ const y1 = sRect.bottom + 4; // a tiny gap below the step
1217
+
1218
+ // End: top-center of the flow bar
1219
+ const x2 = fRect.left + fRect.width / 2;
1220
+ const y2 = fRect.top - 6; // a tiny gap above the bar
1221
+
1222
+ // Control points for a smooth bent curve
1223
+ const midY = (y1 + y2) / 2;
1224
+ const c1x = x1;
1225
+ const c1y = midY;
1226
+ const c2x = x2;
1227
+ const c2y = midY;
1228
+
1229
+ // Resize SVG viewBox to viewport and draw
1230
+ svg.setAttribute("viewBox", `0 0 ${window.innerWidth} ${window.innerHeight}`);
1231
+ path.setAttribute("d", `M ${x1} ${y1} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`);
1232
+
1233
+ // Optional: animate the path slightly on change (simple stroke-dash trick)
1234
+ path.style.transition = "d 0.2s ease";
1235
+ }
1236
+
1237
  /* ------------ Boot ------------ */
1238
+ // Keep arrow aligned on resize/scroll
1239
+ window.addEventListener("resize", drawLinkToFlow, { passive: true });
1240
+ window.addEventListener("scroll", drawLinkToFlow, { passive: true });
1241
  load();
1242
  renderPurposes();
1243
  if (state.purpose && state.purpose !== "anon") {