Files @ a4052905ca7d
Branch filter:

Location: light9/web/ascoltami/Light9AscoltamiTimeline.ts - annotation

drewp@bigasterisk.com
notes about how rdfdb syncs, or should sync
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
e7e03c203c99
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
e7e03c203c99
06da5db2fafe
06da5db2fafe
06da5db2fafe
e7e03c203c99
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
e7e03c203c99
e7e03c203c99
e7e03c203c99
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
e7e03c203c99
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
e7e03c203c99
e7e03c203c99
e7e03c203c99
e7e03c203c99
e7e03c203c99
e7e03c203c99
06da5db2fafe
06da5db2fafe
e7e03c203c99
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
06da5db2fafe
import { css, html, LitElement, PropertyValueMap } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import Sylvester from "sylvester";
import { Zoom } from "../light9-timeline-audio";
import { PlainerViewState, PlainViewState } from "../Light9CursorCanvas";
import { getTopGraph } from "../RdfdbSyncedGraph";
import { show } from "../show_specific";
import { SyncedGraph } from "../SyncedGraph";
import { PlayerState } from "./PlayerState";
export { Light9TimelineAudio } from "../light9-timeline-audio";
export { Light9CursorCanvas } from "../Light9CursorCanvas";
export { RdfdbSyncedGraph } from "../RdfdbSyncedGraph";
export { ResourceDisplay } from "../ResourceDisplay";

const $V = Sylvester.Vector.create;

async function postJson(url: string, jsBody: Object) {
  return fetch(url, {
    method: "POST",
    headers: { "Content-Type": "applcation/json" },
    body: JSON.stringify(jsBody),
  });
}

@customElement("light9-ascoltami-timeline")
export class Light9AscoltamiTimeline extends LitElement {
  static styles = [
    css`
      .timeRow {
        margin: 14px;
        position: relative;
      }
      #overview {
        height: 400px;
      }
      #zoomed {
        margin-top: 40px;
        height: 400px;
      }
      #cursor {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
      }
      #timeSlider {
        height: 0;
      }
    `,
  ];
  graph!: SyncedGraph;
  @property() playerState: PlayerState = {
    duration: null,
    endOfSong: null,
    pausedSongTime: null,
    playing: null,
    song: null,
    wallStartTime: null,
  };
  @property() playerTime: number = 0;
  @state() zoom: Zoom;
  @state() overviewZoom: Zoom;
  @state() viewState: PlainerViewState | null = null;
  constructor() {
    super();
    getTopGraph().then((g) => {
      this.graph = g;
    });
    this.zoom = this.overviewZoom = { duration: null, t1: 0, t2: 1 };
  }
  protected willUpdate(_changedProperties: PropertyValueMap<this>): void {
    super.willUpdate(_changedProperties);
    if ((_changedProperties.has("playerState") || _changedProperties.has("playerTime")) && this.playerState !== null) {
      const duration = this.playerState.duration;
      const t = this.playerTime;
      if (duration !== null) {
        const timeRow = this.shadowRoot!.querySelector(".timeRow") as HTMLDivElement;
        if (timeRow != null) {
          this.updateZooms(duration, t, timeRow);
        }
      }
    }
  }

  updateZooms(duration: number, t: number, timeRow: HTMLDivElement) {
    this.overviewZoom = { duration: duration, t1: 0, t2: duration };
    const t1 = t - 2;
    const t2 = t + 20;
    this.zoom = { duration: duration, t1, t2 };
    const w = timeRow.offsetWidth;
    this.viewState = {
      zoomSpec: { t1: t1, t2: t2 },
      cursor: { t: t },
      audioY: 0,
      audioH: 400,
      zoomedTimeY: 400,
      zoomedTimeH: 40,
      fullZoomX: (sec: number) => (sec / duration) * w,
      zoomInX: (sec: number) => ((sec - t1) / (t2 - t1)) * w,
      mouse: { pos: $V([0, 0]) },
    };
  }

  render() {
    const song = this.playerState?.song;
    if (!song) return html`(spectrogram)`;
    return html`
      <div class="timeRow">
        <div id="timeSlider"></div>
        <light9-timeline-audio id="overview" .show=${show} .song=${song} .zoom=${this.overviewZoom}> </light9-timeline-audio>
        <light9-timeline-audio id="zoomed" .show=${show} .song=${song} .zoom=${this.zoom}></light9-timeline-audio>
        <light9-cursor-canvas id="cursor" .viewState=${this.viewState}></light9-cursor-canvas>
      </div>
    `;
  }
}