From 3fb3da9944f5e7b95bc73b033b1284b28b3096d5 Mon Sep 17 00:00:00 2001 From: Orion Reed Date: Tue, 3 Dec 2024 05:11:57 -0500 Subject: [PATCH] rotate cursor --- src/folk-shape.ts | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/folk-shape.ts b/src/folk-shape.ts index 63104c1..021d76e 100644 --- a/src/folk-shape.ts +++ b/src/folk-shape.ts @@ -9,6 +9,13 @@ export type Shape = 'rectangle' | 'circle' | 'triangle'; type Handle = 'resize-nw' | 'resize-ne' | 'resize-se' | 'resize-sw' | 'rotation' | 'move'; +const resizeCursorUrl = (degrees: number) => + `url("data:image/svg+xml,") 16 16, nwse-resize`; +const rotateCursorUrl = (degrees: number) => + `url("data:image/svg+xml,") 16 16, pointer`; + export type TransformEventDetail = { rotate: number; }; @@ -118,7 +125,7 @@ styles.replaceSync(css` padding: 0; background: hsl(210, 20%, 98%); z-index: calc(infinity); - width: 13px; + width: 9px; aspect-ratio: 1; transform: translate(-50%, -50%); border: 1.5px solid hsl(214, 84%, 56%); @@ -147,12 +154,12 @@ styles.replaceSync(css` [part='resize-nw'], [part='resize-se'] { - cursor: var(--fc-nwse-resize, nwse-resize); + cursor: var(--fc-nwse-resize, url('${resizeCursorUrl(0)}') 16 16, nwse-resize); } [part='resize-ne'], [part='resize-sw'] { - cursor: var(--fc-nesw-resize, nesw-resize); + cursor: var(--fc-nesw-resize, url('${resizeCursorUrl(0)}') 16 16, nesw-resize); } [part='rotation'] { @@ -164,14 +171,16 @@ styles.replaceSync(css` border: 1.5px solid hsl(214, 84%, 56%); border-radius: 50%; background: hsl(210, 20%, 98%); - width: 13px; + width: 11px; aspect-ratio: 1; top: 0; left: 50%; translate: -50% -150%; - cursor: url("data:image/svg+xml,") - 16 16, - pointer; + cursor: var(--fc-rotate, url('${rotateCursorUrl(0)}') 16 16, pointer); + } + + :state(rotate) { + cursor: var(--fc-rotate, url('${rotateCursorUrl(0)}') 16 16, pointer) !important; } :host(:not(:focus-within)) [part^='resize'], @@ -503,6 +512,7 @@ export class FolkShape extends HTMLElement { this.#internals.states.delete(interaction); this.removeEventListener('pointermove', this); this.removeEventListener('lostpointercapture', this); + document.body.style.cursor = 'default'; return; } } @@ -527,12 +537,14 @@ export class FolkShape extends HTMLElement { // Any updates that should be batched should happen here like updating the DOM or emitting events should be executed here. #update(updatedProperties: Set) { - // if (updatedProperties.has('type')) { - // // TODO: Update shape styles. For many shapes, we could just use clip-path to style the shape. - // // If we use relative values in `clip-path: polygon()`, then no JS is needed to style the shape - // // If `clip-path: path()` is used then we need to update the path in JS. - // // See https://www.smashingmagazine.com/2024/05/modern-guide-making-css-shapes/ - // } + if (updatedProperties.has('rotation')) { + const degrees = (this.#rotation * 180) / Math.PI; + + this.style.setProperty('--fc-nwse-resize', resizeCursorUrl(degrees)); + this.style.setProperty('--fc-nesw-resize', resizeCursorUrl(degrees + 90)); + this.style.setProperty('--fc-rotate', rotateCursorUrl(degrees)); + document.body.style.cursor = rotateCursorUrl(degrees); + } this.#dispatchTransformEvent(updatedProperties); }