refactor shape cursors

This commit is contained in:
“chrisshank” 2024-12-07 14:23:29 -08:00
parent db61b02fe8
commit 0508622a9a
1 changed files with 20 additions and 36 deletions

View File

@ -192,7 +192,6 @@ export class FolkShape extends HTMLElement {
#shadow = this.attachShadow({ mode: 'open' }); #shadow = this.attachShadow({ mode: 'open' });
#internals = this.attachInternals(); #internals = this.attachInternals();
#dynamicStyles = css``;
#attrWidth: Dimension = 0; #attrWidth: Dimension = 0;
#attrHeight: Dimension = 0; #attrHeight: Dimension = 0;
@ -200,6 +199,8 @@ export class FolkShape extends HTMLElement {
#rect = new DOMRectTransform(); #rect = new DOMRectTransform();
#previousRect = new DOMRectTransform(); #previousRect = new DOMRectTransform();
#handles: Record<ResizeHandle | RotateHandle, HTMLElement>;
// Used for rotation handling, would love a better way to do this that avoids this clutter. // Used for rotation handling, would love a better way to do this that avoids this clutter.
#initialRotation = 0; #initialRotation = 0;
#startAngle = 0; #startAngle = 0;
@ -277,7 +278,7 @@ export class FolkShape extends HTMLElement {
this.addEventListener('pointerdown', this); this.addEventListener('pointerdown', this);
this.addEventListener('keydown', this); this.addEventListener('keydown', this);
this.#shadow.adoptedStyleSheets = [styles, this.#dynamicStyles]; this.#shadow.adoptedStyleSheets.push(styles);
// Ideally we would creating these lazily on first focus, but the resize handlers need to be around for delegate focus to work. // Ideally we would creating these lazily on first focus, but the resize handlers need to be around for delegate focus to work.
// Maybe can add the first resize handler here, and lazily instantiate the rest when needed? // Maybe can add the first resize handler here, and lazily instantiate the rest when needed?
// I can see it becoming important at scale // I can see it becoming important at scale
@ -291,6 +292,13 @@ export class FolkShape extends HTMLElement {
<button part="resize-bottom-left" aria-label="Resize shape from bottom left"></button> <button part="resize-bottom-left" aria-label="Resize shape from bottom left"></button>
<div><slot></slot></div>`; <div><slot></slot></div>`;
this.#handles = Object.fromEntries(
Array.from(this.#shadow.querySelectorAll('[part]')).map((el) => [
el.getAttribute('part') as ResizeHandle | RotateHandle,
el as HTMLElement,
])
) as Record<ResizeHandle | RotateHandle, HTMLElement>;
this.x = Number(this.getAttribute('x')) || 0; this.x = Number(this.getAttribute('x')) || 0;
this.y = Number(this.getAttribute('y')) || 0; this.y = Number(this.getAttribute('y')) || 0;
this.width = Number(this.getAttribute('width')) || 'auto'; this.width = Number(this.getAttribute('width')) || 'auto';
@ -499,11 +507,12 @@ export class FolkShape extends HTMLElement {
target.removeEventListener('pointermove', this); target.removeEventListener('pointermove', this);
target.removeEventListener('lostpointercapture', this); target.removeEventListener('lostpointercapture', this);
this.#updateCursors();
if (target.getAttribute('part')?.startsWith('rotation')) { if (target.getAttribute('part')?.startsWith('rotation')) {
target.style.removeProperty('cursor'); target.style.removeProperty('cursor');
} }
this.#updateCursors();
return; return;
} }
} }
@ -566,41 +575,16 @@ export class FolkShape extends HTMLElement {
const resizeCursor0 = getResizeCursorUrl(degrees); const resizeCursor0 = getResizeCursorUrl(degrees);
const resizeCursor90 = getResizeCursorUrl((degrees + 90) % 360); const resizeCursor90 = getResizeCursorUrl((degrees + 90) % 360);
const rotateCursor0 = getRotateCursorUrl(degrees);
const rotateCursor90 = getRotateCursorUrl((degrees + 90) % 360);
const rotateCursor180 = getRotateCursorUrl((degrees + 180) % 360);
const rotateCursor270 = getRotateCursorUrl((degrees + 270) % 360);
// TODO use css variables this.#handles['resize-top-left'].style.setProperty('cursor', resizeCursor0);
const dynamicStyles = ` this.#handles['resize-bottom-right'].style.setProperty('cursor', resizeCursor0);
[part='resize-top-left'], this.#handles['resize-top-right'].style.setProperty('cursor', resizeCursor90);
[part='resize-bottom-right'] { this.#handles['resize-bottom-left'].style.setProperty('cursor', resizeCursor90);
cursor: ${resizeCursor0};
}
[part='resize-top-right'], this.#handles['rotation-top-left'].style.setProperty('cursor', getRotateCursorUrl(degrees));
[part='resize-bottom-left'] { this.#handles['rotation-top-right'].style.setProperty('cursor', getRotateCursorUrl((degrees + 90) % 360));
cursor: ${resizeCursor90}; this.#handles['rotation-bottom-right'].style.setProperty('cursor', getRotateCursorUrl((degrees + 180) % 360));
} this.#handles['rotation-bottom-left'].style.setProperty('cursor', getRotateCursorUrl((degrees + 270) % 360));
[part='rotation-top-left'] {
cursor: ${rotateCursor0};
}
[part='rotation-top-right'] {
cursor: ${rotateCursor90};
}
[part='rotation-bottom-right'] {
cursor: ${rotateCursor180};
}
[part='rotation-bottom-left'] {
cursor: ${rotateCursor270};
}
`;
this.#dynamicStyles.replaceSync(dynamicStyles);
} }
#handleResize(handle: ResizeHandle, pointerPos: Point, target: HTMLElement, event?: PointerEvent) { #handleResize(handle: ResizeHandle, pointerPos: Point, target: HTMLElement, event?: PointerEvent) {