Files @ e7e03c203c99
Branch filter:

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

drewp@bigasterisk.com
resize cursor canvas for 400px tall spectros. fix canvas resolution code
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>
    `;
  }
}