diff --git a/light9/fade/Light9FadeUi.ts b/light9/fade/Light9FadeUi.ts
--- a/light9/fade/Light9FadeUi.ts
+++ b/light9/fade/Light9FadeUi.ts
@@ -1,13 +1,12 @@
-import { fastSlider, fastSliderLabel, provideFASTDesignSystem } from "@microsoft/fast-components";
import debug from "debug";
import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { NamedNode } from "n3";
import { getTopGraph } from "../web/RdfdbSyncedGraph";
+import { shortShow, showRoot } from "../web/show_specific";
import { SyncedGraph } from "../web/SyncedGraph";
-import { shortShow, showRoot } from "../web/show_specific";
export { EditChoice } from "../web/EditChoice";
-provideFASTDesignSystem().register(fastSlider(), fastSliderLabel());
+export { Light9Fader } from "./Light9Fader";
debug.enable("*");
const log = debug("fade");
@@ -19,6 +18,7 @@ export class Light9FadeUi extends LitEle
css`
:host {
display: block;
+ user-select: none; /* really this is only desirable during slider drag events */
}
`,
];
@@ -30,7 +30,7 @@ export class Light9FadeUi extends LitEle
- ${this.faders.map((fd) => html` `)}
+ ${this.faders.map((fd) => html` `)}
`;
}
@@ -62,8 +62,8 @@ export class Light9FadeUi extends LitEle
}
}
-@customElement("light9-fader")
-export class Light9Fader extends LitElement {
+@customElement("light9-effect-fader")
+export class Light9EffectFader extends LitElement {
static styles = [
css`
:host {
@@ -71,24 +71,15 @@ export class Light9Fader extends LitElem
border: 2px gray outset;
background: #272727;
}
- fast-slider {
- height: 256px;
- }
- fast-slider > .track {
- background: #e3bbc0;
- box-shadow: 0 0 8px;
- }
- fast-slider {
- --accent-foreground-rest: #0a0a0c;
+ light9-fader {
+ margin: 4px;
+ width: 100%;
}
`,
];
render() {
return html`
-
-
-
-
+
${this.value.toPrecision(3)}
eff:
attr:
@@ -153,7 +144,7 @@ export class Light9Fader extends LitElem
}
const U = this.graph.U();
const prev = this.value;
- const v: number = (ev.target as any).valueAsNumber;
+ const v: number = ev.detail.value;
this.value = parseFloat(v.toPrecision(3)); // rewrite pls
if (this.value == prev) {
return;
diff --git a/light9/fade/Light9Fader.ts b/light9/fade/Light9Fader.ts
new file mode 100644
--- /dev/null
+++ b/light9/fade/Light9Fader.ts
@@ -0,0 +1,139 @@
+import debug from "debug";
+import { css, html, LitElement, PropertyValueMap } from "lit";
+import { customElement, property, query } from "lit/decorators.js";
+
+import { clamp } from "../web/floating_color_picker";
+const log = debug("fade");
+
+class Drag {
+ constructor(public startDragPxY: number, public startDragValue: number) {}
+}
+
+@customElement("light9-fader")
+export class Light9Fader extends LitElement {
+ static styles = [
+ css`
+ :host {
+ display: inline-block;
+ border: 2px gray inset;
+ background: #000;
+ height: 250px;
+ }
+ #handle {
+ background: gray;
+ border: 5px gray outset;
+ position: relative;
+ left: 0;
+ right: -25px;
+ }
+ `,
+ ];
+
+ @property() value: number = 0;
+
+ @query("#handle") handleEl!: HTMLElement;
+
+ troughHeight = 250 - 2 - 2 - 5 - 5;
+ handleHeight = 20;
+
+ drag?: Drag;
+ unmutedValue: number = 1;
+
+ render() {
+ return html`
`;
+ }
+
+ protected update(changedProperties: PropertyValueMap | Map): void {
+ super.update(changedProperties);
+ if (changedProperties.has("value")) {
+ this.value= clamp(this.value, 0, 1)
+ this.dispatchEvent(new CustomEvent("change", { detail: { value: this.value } }));
+ }
+ }
+
+ protected updated(_changedProperties: PropertyValueMap | Map): void {
+ super.updated(_changedProperties);
+ const y = this.sliderTopY(this.value);
+ this.handleEl.style.top = y + "px";
+ }
+
+ protected firstUpdated(_changedProperties: PropertyValueMap | Map): void {
+ super.firstUpdated(_changedProperties);
+ this.handleEl.style.height = this.handleHeight + "px";
+ this.events();
+ }
+
+ events() {
+ const hand = this.handleEl;
+ hand.addEventListener("mousedown", (ev: MouseEvent) => {
+ ev.stopPropagation();
+ if (ev.buttons == 1) {
+ this.drag = new Drag(ev.clientY, this.value);
+ } else if (ev.buttons == 2) {
+ this.onRmb();
+ }
+ });
+ this.addEventListener("mousedown", (ev: MouseEvent) => {
+ ev.stopPropagation();
+ if (ev.buttons == 1) {
+ this.value = this.sliderValue(ev.offsetY);
+ this.drag = new Drag(ev.clientY, this.value);
+ } else if (ev.buttons == 2) {
+ // RMB in trough
+ this.onRmb();
+ }
+ });
+
+ this.addEventListener("contextmenu", (event) => {
+ event.preventDefault();
+ });
+
+ this.addEventListener("wheel", (ev: WheelEvent) => {
+ ev.preventDefault();
+ this.value += ev.deltaY / 120 * -.05;
+ });
+
+ const maybeDrag = (ev: MouseEvent) => {
+ if (ev.buttons != 1) return;
+ if (this.drag === undefined) return;
+ ev.stopPropagation();
+ this.onMouseDrag(ev.clientY - this.drag.startDragPxY!);
+ };
+ hand.addEventListener("mousemove", maybeDrag);
+ this.addEventListener("mousemove", maybeDrag);
+ window.addEventListener("mousemove", maybeDrag);
+
+ hand.addEventListener("mouseup", this.onMouseUpAnywhere.bind(this));
+ this.addEventListener("mouseup", this.onMouseUpAnywhere.bind(this));
+ window.addEventListener("mouseup", this.onMouseUpAnywhere.bind(this));
+ }
+ onRmb() {
+ if (this.value > 0.1) {
+ // mute
+ this.unmutedValue = this.value;
+ this.value = 0;
+ } else {
+ // unmute
+ this.value = this.unmutedValue;
+ }
+ }
+ onMouseDrag(dy: number) {
+ if (this.drag === undefined) throw "unexpected";
+ this.value = this.drag.startDragValue - dy / this.troughHeight;
+ }
+
+ onMouseUpAnywhere() {
+ this.drag = undefined;
+ }
+
+ sliderTopY(value: number): number {
+ const usableY = this.troughHeight - this.handleHeight;
+ const yAdj = this.handleHeight / 2 - 5 - 2;
+ return (1 - value) * usableY + yAdj;
+ }
+ sliderValue(offsetY: number): number {
+ const usableY = this.troughHeight - this.handleHeight;
+ const yAdj = this.handleHeight / 2 - 5 - 2;
+ return clamp(1 - (offsetY - yAdj) / usableY, 0, 1);
+ }
+}