import { useQuickReactor } from '@tldraw/state-react'
import { TLCursorType } from '@tldraw/tlschema'
import { PI, radiansToDegrees } from '../primitives/utils'
import { useContainer } from './useContainer'
import { useEditor } from './useEditor'
import { useIsDarkMode } from './useIsDarkMode'
const CORNER_SVG = ``
const EDGE_SVG = ``
const ROTATE_CORNER_SVG = ``
function getCursorCss(
svg: string,
r: number,
tr: number,
f: boolean,
color: string,
hotspotX = 16,
hotspotY = 16
) {
const a = (-tr - r) * (PI / 180)
const s = Math.sin(a)
const c = Math.cos(a)
const dx = 1 * c - 1 * s
const dy = 1 * s + 1 * c
return (
`url("data:image/svg+xml,") ${hotspotX} ${hotspotY}, pointer`
)
}
const STATIC_CURSORS = [
'default',
'pointer',
'cross',
'move',
'grab',
'grabbing',
'text',
'zoom-in',
'zoom-out',
]
type CursorFunction = (rotation: number, flip: boolean, color: string) => string
const CURSORS: Record = {
none: () => 'none',
'ew-resize': (r, f, c) => getCursorCss(EDGE_SVG, r, 0, f, c),
'ns-resize': (r, f, c) => getCursorCss(EDGE_SVG, r, 90, f, c),
'nesw-resize': (r, f, c) => getCursorCss(CORNER_SVG, r, 0, f, c),
'nwse-resize': (r, f, c) => getCursorCss(CORNER_SVG, r, 90, f, c),
'nwse-rotate': (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 0, f, c),
'nesw-rotate': (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 90, f, c),
'senw-rotate': (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 180, f, c),
'swne-rotate': (r, f, c) => getCursorCss(ROTATE_CORNER_SVG, r, 270, f, c),
}
/** @public */
export function getCursor(cursor: TLCursorType, rotation = 0, color = 'black') {
return CURSORS[cursor](radiansToDegrees(rotation), false, color)
}
export function useCursor() {
const editor = useEditor()
const container = useContainer()
const isDarkMode = useIsDarkMode()
useQuickReactor(
'useCursor',
() => {
const { type, rotation } = editor.getInstanceState().cursor
if (STATIC_CURSORS.includes(type)) {
container.style.setProperty('--tl-cursor', `var(--tl-cursor-${type})`)
return
}
container.style.setProperty(
'--tl-cursor',
getCursor(type, rotation, isDarkMode ? 'white' : 'black')
)
},
[editor, container, isDarkMode]
)
}