From fcab9b3e92a1a7f152dcf6b3c551afb9de2cb243 Mon Sep 17 00:00:00 2001 From: Tim Harding Date: Sat, 5 Oct 2024 21:09:49 -0700 Subject: [PATCH] Added drag area component --- demo/assets/css/style.scss | 35 ++++++++------- demo/assets/js/demo.js | 7 +-- demo/assets/js/tester.js | 91 ++++++++++++++++++++++++++++++++------ demo/index.html | 44 +++++++----------- 4 files changed, 118 insertions(+), 59 deletions(-) diff --git a/demo/assets/css/style.scss b/demo/assets/css/style.scss index 255947d..6158b2e 100644 --- a/demo/assets/css/style.scss +++ b/demo/assets/css/style.scss @@ -28,27 +28,30 @@ body { align-items: stretch; } -.th-squircle { +th-squircle { contain: strict; } -.tester { -} - -.tester__squircle { -} - -.tester__controls { -} - -.tester-corner { -} - -.tester-control { +th-tester { + background-color: lightgray; + display: grid; + grid-template-rows: 1fr min-content; + grid-template-areas: "drag-area" "controls"; } -.tester-control__label { +th-drag-area { + position: relative; + grid-area: "drag-area"; + background-color: gray; } -.tester-control__input { +th-corner { + position: absolute; + display: grid; + width: 1.5rem; + height: 1.5rem; + background-color: blue; + opacity: 20%; + border-radius: 50%; + transform: translateX(-50%) translateY(-50%); } diff --git a/demo/assets/js/demo.js b/demo/assets/js/demo.js index 9455f17..581800c 100644 --- a/demo/assets/js/demo.js +++ b/demo/assets/js/demo.js @@ -1,4 +1,4 @@ -import { Tester, Corner, Control } from "./tester.js"; +import { Tester, Corner, Control, DragArea } from "./tester.js"; const IS_PAINT_SUPPORTED = CSS.supports("background", "paint(id)"); @@ -6,8 +6,9 @@ function main() { loadSquircleComponent(); loadPaintWorklet(); customElements.define("th-tester", Tester); - customElements.define("th-tester-corner", Corner); - customElements.define("th-tester-control", Control); + customElements.define("th-drag-area", DragArea); + customElements.define("th-corner", Corner); + customElements.define("th-control", Control); } async function loadPaintWorklet() { diff --git a/demo/assets/js/tester.js b/demo/assets/js/tester.js index b96d8ad..3eb96aa 100644 --- a/demo/assets/js/tester.js +++ b/demo/assets/js/tester.js @@ -1,6 +1,6 @@ /** - * @typedef {"top-left" | "bottom-right"} Position - * @typedef {{ x: number, y: number, position: Position }} CornerEventProps + * @typedef {"top-left" | "bottom-right"} Side + * @typedef {{ x: number, y: number, side: Side }} CornerEventProps * @typedef {CustomEvent} CornerEvent * * @typedef {{ value: string, aspect: string }} ControlEventProps @@ -11,38 +11,91 @@ export class Tester extends HTMLElement { /** @type {HTMLElement?} */ _squircle = null; + constructor() { + super(); + } + + connectedCallback() { + this._squircle = this.querySelector("th-squircle"); + } +} + +const SIDE_OFFSET = 32; + +export class DragArea extends HTMLElement { + _l = SIDE_OFFSET; + _r = 0; + _t = SIDE_OFFSET; + _b = 0; + /** @type {HTMLElement?} */ + _squircle = null; + constructor() { super(); const listen = listenPassive.bind(this); - listen("th-tester-corner", this._handleCorner); - listen("th-tester-control", this._handleControl); + listen("th-corner__update", this._handleCornerUpdate); + listen("th-corner__register", this._handleCornerRegister); + listen("th-control__change", this._handleControlChange); } connectedCallback() { this._squircle = this.querySelector("th-squircle"); } + /** + * @param {CustomEvent} event + */ + _handleCornerRegister(event) { + const corner = event.target; + if (!(corner instanceof Corner)) { + console.warn("Expected a corner element"); + return; + } + + switch (corner._side) { + case "top-left": { + corner.setAttribute("y", `${this._t}px`); + corner.setAttribute("x", `${this._l}px`); + break; + } + + case "bottom-right": { + const { clientWidth: w, clientHeight: h } = this; + this._r = w - SIDE_OFFSET; + this._b = h - SIDE_OFFSET; + corner.setAttribute("y", `${this._b}px`); + corner.setAttribute("x", `${this._r}px`); + break; + } + + default: { + console.warn(`Unexpected corner side: ${corner._side}`); + break; + } + } + } + /** * @param {CornerEvent} event */ - _handleCorner(event) { + _handleCornerUpdate(event) { console.log(event); } /** * @param {ControlEvent} event */ - _handleControl(event) { + _handleControlChange(event) { console.log(event); } } export class Corner extends HTMLElement { _isPressed = false; - _position = ""; + _side = ""; static get observedAttributes() { - return ["position"]; + return ["side", "x", "y"]; } constructor() { @@ -60,8 +113,20 @@ export class Corner extends HTMLElement { */ attributeChangedCallback(name, _, newValue) { switch (name) { - case "position": { - this._position = newValue; + case "side": { + this._side = newValue; + const event = new CustomEvent("th-corner__register", { bubbles: true }); + this.dispatchEvent(event); + break; + } + + case "x": { + this.style.left = newValue; + break; + } + + case "y": { + this.style.top = newValue; break; } } @@ -81,8 +146,8 @@ export class Corner extends HTMLElement { _handleMouseMove(mouseEvent) { if (!this._isPressed) return; const { movementX: x, movementY: y } = mouseEvent; - const event = new CustomEvent("th-tester-corner", { - detail: { x, y, position: this._position }, + const event = new CustomEvent("th-corner__update", { + detail: { x, y, side: this._side }, bubbles: true, }); this.dispatchEvent(event); @@ -132,7 +197,7 @@ export class Control extends HTMLElement { const target = inputEvent.target; if (!(target instanceof HTMLInputElement)) return; const value = target.value; - const event = new CustomEvent("th-tester-control", { + const event = new CustomEvent("th-control__change", { detail: { value, aspect: this._aspect }, bubbles: true, }); diff --git a/demo/index.html b/demo/index.html index 6780166..d329229 100644 --- a/demo/index.html +++ b/demo/index.html @@ -33,33 +33,23 @@ - - - - - -
- - - - - - - - - + + + + + + + + + + + + + + + + +