diff light9/ascoltami/Light9AscoltamiUi.ts @ 2128:e2ed5ce36253

double spectrum views have a connected cursor
author drewp@bigasterisk.com
date Fri, 03 Jun 2022 02:19:47 -0700
parents 1dc96b97a544
children 1dbbf0db3036
line wrap: on
line diff
--- a/light9/ascoltami/Light9AscoltamiUi.ts	Fri Jun 03 00:41:13 2022 -0700
+++ b/light9/ascoltami/Light9AscoltamiUi.ts	Fri Jun 03 02:19:47 2022 -0700
@@ -1,14 +1,19 @@
 import debug from "debug";
 import { css, html, LitElement } from "lit";
 import { customElement, property } from "lit/decorators.js";
+import { classMap } from "lit/directives/class-map.js";
 import { NamedNode } from "n3";
+import Sylvester from "sylvester";
+import { Zoom } from "../web/light9-timeline-audio";
+import { PlainViewState } from "../web/Light9CursorCanvas";
 import { getTopGraph } from "../web/RdfdbSyncedGraph";
 import { SyncedGraph } from "../web/SyncedGraph";
-export { RdfdbSyncedGraph } from "../web/RdfdbSyncedGraph";
+import { TimingUpdate } from "./main";
 export { Light9TimelineAudio } from "../web/light9-timeline-audio";
-import { classMap } from "lit/directives/class-map.js";
-import { TimingUpdate } from "./main";
-import { Zoom } from "../web/light9-timeline-audio";
+export { Light9CursorCanvas } from "../web/Light9CursorCanvas";
+export { RdfdbSyncedGraph } from "../web/RdfdbSyncedGraph";
+
+const $V = Sylvester.Vector.create;
 
 debug.enable("*");
 const log = debug("asco");
@@ -31,18 +36,30 @@
   @property() isPlaying: boolean = false;
   @property() show: NamedNode | null = null;
   @property() song: NamedNode | null = null;
-  @property() t: number = 0;
   @property() currentDuration: number = 0;
   @property() zoom: Zoom;
   @property() overviewZoom: Zoom;
+  @property() viewState: PlainViewState | null = null;
   static styles = [
     css`
       .timeRow {
         margin: 14px;
+        position: relative;
       }
-      light9-timeline-audio {
+      #overview {
+        height: 60px;
+      }
+      #zoomed {
+        margin-top: 40px;
         height: 80px;
       }
+      #cursor {
+        position: absolute;
+        left: 0;
+        top: 0;
+        width: 100%;
+        height: 100%;
+      }
     `,
   ];
   render() {
@@ -54,8 +71,9 @@
 
       <div class="timeRow">
         <div id="timeSlider"></div>
-        <light9-timeline-audio .show=${this.show} .song=${this.song} .zoom=${this.overviewZoom}></light9-timeline-audio>
-        <light9-timeline-audio .show=${this.show} .song=${this.song} .zoom=${this.zoom}></light9-timeline-audio>
+        <light9-timeline-audio id="overview" .show=${this.show} .song=${this.song} .zoom=${this.overviewZoom}></light9-timeline-audio>
+        <light9-timeline-audio id="zoomed" .show=${this.show} .song=${this.song} .zoom=${this.zoom}></light9-timeline-audio>
+        <light9-cursor-canvas id="cursor" .viewState=${this.viewState}></light9-cursor-canvas>
       </div>
 
       <div class="commands">
@@ -149,7 +167,22 @@
       this.currentDuration = data.duration;
       this.song = new NamedNode(data.song);
       this.overviewZoom = { duration: data.duration, t1: 0, t2: data.duration };
-      this.zoom = { duration: data.duration, t1: data.t - 2, t2: data.t + 20 };
+      const t1 = data.t - 2,
+        t2 = data.t + 20;
+      this.zoom = { duration: data.duration, t1, t2 };
+      const timeRow = this.shadowRoot!.querySelector(".timeRow") as HTMLDivElement;
+      const w = timeRow.offsetWidth;
+      this.viewState = {
+        zoomSpec: { t1: () => t1, t2: () => t2 },
+        cursor: { t: () => data.t },
+        audioY: () => 0,
+        audioH: () => 60,
+        zoomedTimeY: () => 60,
+        zoomedTimeH: () => 40,
+        fullZoomX: (sec: number) => (sec / data.duration) * w,
+        zoomInX: (sec: number) => ((sec - t1) / (t2 - t1)) * w,
+        mouse: { pos: () => $V([0, 0]) },
+      };
     });
   }