Mercurial > code > home > repos > light9
changeset 2127:1dc96b97a544
two zoomed spectrogram views in asco
author | drewp@bigasterisk.com |
---|---|
date | Fri, 03 Jun 2022 00:41:13 -0700 |
parents | 58389a24e222 |
children | e2ed5ce36253 |
files | light9/ascoltami/Light9AscoltamiUi.ts light9/ascoltami/index.html light9/ascoltami/webapp.py light9/web/light9-timeline-audio.ts light9/web/style.css |
diffstat | 5 files changed, 95 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/light9/ascoltami/Light9AscoltamiUi.ts Thu Jun 02 23:35:47 2022 -0700 +++ b/light9/ascoltami/Light9AscoltamiUi.ts Fri Jun 03 00:41:13 2022 -0700 @@ -1,5 +1,5 @@ import debug from "debug"; -import { html, LitElement } from "lit"; +import { css, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; import { NamedNode } from "n3"; import { getTopGraph } from "../web/RdfdbSyncedGraph"; @@ -8,6 +8,7 @@ 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"; debug.enable("*"); const log = debug("asco"); @@ -28,9 +29,22 @@ times!: { intro: number; post: number }; @property() nextText: string = ""; @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; + static styles = [ + css` + .timeRow { + margin: 14px; + } + light9-timeline-audio { + height: 80px; + } + `, + ]; render() { return html`<rdfdb-synced-graph></rdfdb-synced-graph> @@ -38,6 +52,12 @@ <h1>ascoltami <a href="metrics">[metrics]</a></h1> + <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> + </div> + <div class="commands"> <button id="cmd-stop" @click=${this.onCmdStop} class="playMode ${classMap({ active: !this.isPlaying })}"> <strong>Stop</strong> @@ -106,13 +126,10 @@ }); } - currentDurationChanged(newDuration: number): void { - this.currentDuration = newDuration; - } - async musicSetup() { // shoveled over from the vanillajs version const config = await (await fetch("api/config")).json(); + this.show = new NamedNode(config.show); this.times = config.times; document.title = document.title.replace("{{host}}", config.host); const h1 = document.querySelector("h1")!; @@ -130,14 +147,16 @@ this.nextText = data.next; this.isPlaying = data.playing; 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 }; }); } constructor() { super(); this.bindKeys(); - // byId("cmd-stop").addEventListener("click", (ev: Event) => - // ); + this.zoom = this.overviewZoom = { duration: null, t1: 0, t2: 1 }; getTopGraph().then((g) => { this.graph = g;
--- a/light9/ascoltami/index.html Thu Jun 02 23:35:47 2022 -0700 +++ b/light9/ascoltami/index.html Fri Jun 03 00:41:13 2022 -0700 @@ -36,9 +36,6 @@ </tr> </table> - <div class="timeRow"> - <div id="timeSlider"></div> - </div> </div> <hr />
--- a/light9/ascoltami/webapp.py Thu Jun 02 23:35:47 2022 -0700 +++ b/light9/ascoltami/webapp.py Fri Jun 03 00:41:13 2022 -0700 @@ -10,7 +10,7 @@ from cycloneerr import PrettyErrorHandler from light9.metrics import metricsRoute from light9.namespaces import L9 -from light9.showconfig import getSongsFromShow, songOnDisk +from light9.showconfig import getSongsFromShow, showUri, songOnDisk from rdflib import URIRef from twisted.internet import reactor from twisted.internet.interfaces import IReactorTime @@ -36,6 +36,7 @@ self.write( json.dumps(dict( host=socket.gethostname(), + show=str(showUri()), times={ # these are just for the web display. True values are on Player.__init__ 'intro': 4,
--- a/light9/web/light9-timeline-audio.ts Thu Jun 02 23:35:47 2022 -0700 +++ b/light9/web/light9-timeline-audio.ts Fri Jun 03 00:41:13 2022 -0700 @@ -1,13 +1,34 @@ import { debug } from "debug"; -import { css, html, LitElement, TemplateResult } from "lit"; -import { customElement, property } from "lit/decorators.js"; +import { css, html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { NamedNode } from "n3"; +import { loadConfigFromFile } from "vite"; +import { getTopGraph } from "./RdfdbSyncedGraph"; +import { SyncedGraph } from "./SyncedGraph"; const log = debug("audio"); +export interface Zoom { + duration: number | null; + t1: number; + t2: number; +} + +function nodeHasChanged(newVal?: NamedNode, oldVal?: NamedNode): boolean { + if (newVal === undefined && oldVal === undefined) { + return false; + } + if (newVal === undefined || oldVal === undefined) { + return true; + } + return !newVal.equals(oldVal); +} + // (potentially-zoomed) spectrogram view @customElement("light9-timeline-audio") export class Light9TimelineAudio extends LitElement { + graph!: SyncedGraph; render() { return html` <style> @@ -25,56 +46,67 @@ img { height: 100%; position: relative; + transition: left .1s linear; + } </style> <div> - <img src="{{imgSrc}}" style="width: {{imgWidth}} ; left: {{imgLeft}}" /> + <img src=${this.imgSrc} style="width: ${this.imgWidth}; left: ${this.imgLeft}" /> </div> `; } - // properties= { - // graph: {type: Object, notify: true}, - // show: {type: String, notify: true}, - // song: {type: String, notify: true}, - // zoom: {type: Object, notify: true}, - // imgSrc: { type: String, notify: true}, - // imgWidth: { computed: '_imgWidth(zoom)' }, - // imgLeft: { computed: '_imgLeft(zoom)' }, - // } - // observers= [ - // 'setImgSrc(graph, show, song)' - // ] - ready() { - this.zoom = { duration: 0 }; + @property({ hasChanged: nodeHasChanged }) show!: NamedNode; + @property({ hasChanged: nodeHasChanged }) song!: NamedNode; + @property() zoom: Zoom = { duration: null, t1: 0, t2: 1 }; + @state() imgSrc: string = "#"; + @state() imgWidth: string = "0"; // css + @state() imgLeft: string = "0"; // css + + constructor() { + super(); + + getTopGraph().then((g) => { + this.graph = g; + }); } + + updated(changedProperties: PropertyValues) { + if (changedProperties.has("song") || changedProperties.has("show")) { + if (this.song && this.show) { + this.graph.runHandler(this.setImgSrc.bind(this), "timeline-audio " + this.song); + } + } + if (changedProperties.has("zoom")) { + this.imgWidth = this._imgWidth(this.zoom); + this.imgLeft = this._imgLeft(this.zoom); + } + } + setImgSrc() { - graph.runHandler( - function () { - try { - var root = this.graph.stringValue(this.graph.Uri(this.show), this.graph.Uri(":spectrogramUrlRoot")); - } catch (e) { - return; - } + try { + var root = this.graph.stringValue(this.show, this.graph.Uri(":spectrogramUrlRoot")); + } catch (e) { + return; + } - try { - var filename = this.graph.stringValue(this.song, this.graph.Uri(":songFilename")); - } catch (e) { - return; - } + try { + var filename = this.graph.stringValue(this.song, this.graph.Uri(":songFilename")); + } catch (e) { + return; + } - this.imgSrc = root + "/" + filename.replace(".wav", ".png").replace(".ogg", ".png"); - }.bind(this), - "timeline-audio " + this.song - ); + this.imgSrc = root + "/" + filename.replace(".wav", ".png").replace(".ogg", ".png"); + log(`imgSrc ${this.imgSrc}`); } - _imgWidth(zoom) { + + _imgWidth(zoom: Zoom): string { if (!zoom.duration) { return "100%"; } return 100 / ((zoom.t2 - zoom.t1) / zoom.duration) + "%"; } - _imgLeft(zoom) { + _imgLeft(zoom: Zoom): string { if (!zoom.duration) { return "0"; }