packages/storybook/stories/pointer-events.stories.tsx (98 lines of code) (raw):

import { createElement, DebugFlags, RenderObject, RenderShape, Size, SyntheticPointerEvent } from '@canvas-ui/core' import type { StoryObj } from '@storybook/react' import React, { useEffect, useRef } from 'react' export const PointerEventsTest: StoryObj<React.FC> = () => { const canvasElRef = useRef<HTMLCanvasElement | null>(null) useEffect(() => { // 等待布局稳定 setTimeout(() => { if (!canvasElRef.current) { return } DebugFlags.set(DebugFlags.NodeBounds) const canvasRect = canvasElRef.current.getBoundingClientRect() const surfaceSize = Size.fromWH(canvasRect.width, canvasRect.height) const canvas = createElement('Canvas') canvas.prepareInitialFrame() canvas.el = canvasElRef.current canvas.size = surfaceSize canvas.dpr = devicePixelRatio // // 构造如下结构 // r (View) // a (Flex) // / \ \ // b c d // const r = createElement('View') r.style.left = 100 r.style.width = 280 r.style.height = 250 canvas.child = r const a = createElement('Flex') r.appendChild(a) a.style.left = -100 const b = createElement('Rect') b.style.width = 100 b.style.height = 100 b.repaintBoundary = true a.appendChild(b) const c = createElement('Rect') c.style.width = 100 c.style.height = 200 a.appendChild(c) const d = createElement('Rect') d.style.width = 200 d.style.height = 300 a.appendChild(d) b.style.height = 100 b.fill = '#FF0000' c.stroke = '#00FF00' c.strokeWidth = 4 d.fill = '#CCCCCC' d.stroke = '#333333' d.strokeWidth = 2 const originFillMap = new WeakMap<RenderShape, string | undefined>() const aHandleEvent = (event: SyntheticPointerEvent<RenderObject>) => { const { target, type } = event // eslint-disable-next-line @typescript-eslint/no-explicit-any console.info('a', type, (event.target as any).constructor.name) if (target instanceof RenderShape) { if (type === 'pointerover') { originFillMap.set(target, target.fill) target.fill = '#FFFF00' } else if (type === 'pointerout') { target.fill = originFillMap.get(target) } } } a.addEventListener('pointermove', aHandleEvent) a.addEventListener('pointerover', aHandleEvent) a.addEventListener('pointerenter', aHandleEvent) a.addEventListener('pointerdown', aHandleEvent) a.addEventListener('pointerup', aHandleEvent) a.addEventListener('pointerout', aHandleEvent) a.addEventListener('pointerleave', aHandleEvent) return () => { a.removeEventListener('pointermove', aHandleEvent) a.removeEventListener('pointerover', aHandleEvent) a.removeEventListener('pointerenter', aHandleEvent) a.removeEventListener('pointerdown', aHandleEvent) a.removeEventListener('pointerup', aHandleEvent) a.removeEventListener('pointerout', aHandleEvent) a.removeEventListener('pointerleave', aHandleEvent) } }, 100) }, [canvasElRef]) return ( <> <div> See console outputs. </div> <canvas style={{ backgroundColor: '#ffffff', width: '500px', height: '500px' }} ref={canvasElRef}></canvas> </> ) } PointerEventsTest.storyName = 'PointerEvents' export default { title: 'core/events', component: PointerEventsTest, decorators: [(Story: React.ComponentType) => <div style={{ backgroundColor: '#efefef', width: '100%', height: '100vh' }}><Story /></div>], }