Files @ f3b8dfcf8463
Branch filter:

Location: light9/web/fade/Light9Fader.ts - annotation

drewp@bigasterisk.com
reorder
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
4556eebe5d73
import debug from "debug";
import { css, html, LitElement, PropertyValueMap } from "lit";
import { customElement, property, query } from "lit/decorators.js";

import { clamp } from "../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: 80px;
      }
      #handle {
        background: gray;
        border: 5px gray outset;
        position: relative;
        left: 0;
        right: -25px;
      }
    `,
  ];

  @property() value: number = 0;

  @query("#handle") handleEl!: HTMLElement;

  troughHeight = 80 - 2 - 2 - 5 - 5;
  handleHeight = 10;

  drag?: Drag;
  unmutedValue: number = 1;

  render() {
    return html` <div id="handle"><hr /></div> `;
  }

  protected update(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
    super.update(changedProperties);
    if (changedProperties.has("value")) {
      
    }
  }
  valueChangedFromUi() {
    this.value= clamp(this.value, 0, 1)
    this.dispatchEvent(new CustomEvent("change", { detail: { value: this.value } }));
  }

  protected updated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
    super.updated(_changedProperties);
    const y = this.sliderTopY(this.value);
    this.handleEl.style.top = y + "px";
  }

  protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): 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.valueChangedFromUi()
        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 / this.troughHeight * -.05;
      this.valueChangedFromUi()
    });

    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;
    }
    this.valueChangedFromUi()
  }
  onMouseDrag(dy: number) {
    if (this.drag === undefined) throw "unexpected";
    this.value = this.drag.startDragValue - dy / this.troughHeight;
    this.valueChangedFromUi()
  }

  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);
  }
}