diff --git a/examples/node.tsx b/examples/node.tsx index 701ebb3..04175c1 100644 --- a/examples/node.tsx +++ b/examples/node.tsx @@ -1,8 +1,13 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import terminalImage from 'terminal-image'; import config, { Canvas, GlobalFonts } from '@napi-rs/canvas'; import { render } from '../src/render'; import { Group, Text, Rect, Image } from '../src'; +import { + RouterProvider, + createMemoryRouter, + useNavigate, +} from 'react-router-dom'; GlobalFonts.registerFromPath( '/Users/nrajlich/Downloads/NINTENDOSWITCHUI.TTF', @@ -10,6 +15,12 @@ GlobalFonts.registerFromPath( ); function App() { + const [r, setR] = useState(0); + useEffect(() => { + setInterval(() => { + setR((v) => v + 1); + }, 33.3); + }, []); return ( <> {/* @@ -29,28 +40,58 @@ function App() { fill='red' stroke='green' lineWidth={8} + rotate={r} onClick={console.log} /> ); } -const canvas = new Canvas(800, 800); -const root = render(, canvas, config); -const ev = new EventTarget(); -canvas.addEventListener = ev.addEventListener.bind(ev); -canvas.removeEventListener = ev.removeEventListener.bind(ev); -canvas.dispatchEvent = ev.dispatchEvent.bind(ev); -await root; -//await root; -console.log('p'); -root.proxyEvents(); -canvas.dispatchEvent( - Object.assign(new Event('click'), { - layerX: 15, - layerY: 15, - }), -); +function Foo() { + const navigate = useNavigate(); + useEffect(() => { + setTimeout(() => { + navigate('/'); + }, 1000); + }, []); + return ( + + test + + ); +} + +const routes = [ + { + path: '/', + element: , + //loader: () => FAKE_EVENT, + }, + { + path: '/foo', + element: , + //loader: () => FAKE_EVENT, + }, +]; + +const router = createMemoryRouter(routes, { + initialEntries: ['/', '/foo'], + initialIndex: 1, +}); + +const canvas = new Canvas(800, 500); +const root = render(, canvas, config); + +// Hide cursor +process.stdout.write('\x1B[?25l'); + +root.addEventListener('render', async () => { + const buffer = canvas.toBuffer('image/png'); + const i = await terminalImage.buffer(buffer, { height: 30 }); + process.stdout.write(`\x1B[2J\x1B[2;2H${i}`); +}); -const buffer = canvas.toBuffer('image/png'); -console.log(await terminalImage.buffer(buffer, { height: 45 })); +process.on('exit', () => { + // Show cursor + process.stdout.write('\x1B[?25h'); +}); diff --git a/package.json b/package.json index 16f9dcc..8343170 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "jest-image-snapshot": "^6.4.0", "react": "^18.2.0", "react-fps": "^1.0.6", + "react-router-dom": "^6.23.0", "terminal-image": "^2.0.0", "tsx": "^4.7.0", "typescript": "^5.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 59134cd..c7b5cc1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,9 @@ devDependencies: react-fps: specifier: ^1.0.6 version: 1.0.6(react-dom@18.2.0)(react@18.2.0) + react-router-dom: + specifier: ^6.23.0 + version: 6.23.0(react-dom@18.2.0)(react@18.2.0) terminal-image: specifier: ^2.0.0 version: 2.0.0 @@ -1460,6 +1463,11 @@ packages: '@napi-rs/canvas-win32-x64-msvc': 0.1.48 dev: true + /@remix-run/router@1.16.0: + resolution: {integrity: sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==} + engines: {node: '>=14.0.0'} + dev: true + /@rollup/rollup-android-arm-eabi@4.13.0: resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==} cpu: [arm] @@ -2687,6 +2695,29 @@ packages: scheduler: 0.23.0 dev: false + /react-router-dom@6.23.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.16.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.23.0(react@18.2.0) + dev: true + + /react-router@6.23.0(react@18.2.0): + resolution: {integrity: sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.16.0 + react: 18.2.0 + dev: true + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} diff --git a/src/events.ts b/src/events.ts index 36724da..e62c1fd 100644 --- a/src/events.ts +++ b/src/events.ts @@ -171,7 +171,6 @@ export function proxyEvents( } if (mouseCurrentlyOver) { - // do "mouseleave" event mouseCurrentlyOver.dispatchEvent( cloneMouseEvent( diff --git a/src/test.tsx b/src/test.tsx index 058aac1..5eabc20 100644 --- a/src/test.tsx +++ b/src/test.tsx @@ -1,5 +1,10 @@ -import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; -import { render } from './render'; +import React, { useEffect, useRef, useState } from 'react'; +import { render } from './render.js'; +import { + RouterProvider, + createMemoryRouter, + useNavigate, +} from 'react-router-dom'; import { Circle, Group, @@ -11,7 +16,7 @@ import { Path, RoundRectProps, RoundRect, -} from './index'; +} from './index.js'; const canvas = document.getElementById('c') as HTMLCanvasElement; const randomColor = () => @@ -29,6 +34,12 @@ function Button({ children, ...props }: RoundRectProps & { children: string }) { const rectRef = useRef(); const [hover, setHover] = useState(false); const [textPos, setTextPos] = useState({ x: 0, y: 0 }); + useEffect(() => { + return () => { + // @ts-ignore + root.ctx.canvas.style.cursor = 'unset'; + }; + }, []); return ( <> { - console.log('click!'); - }} + //onClick={() => { + // console.log('click!'); + //}} ref={(ref) => { if (!ref || rectRef.current) return; // @ts-ignore @@ -72,7 +83,20 @@ function Button({ children, ...props }: RoundRectProps & { children: string }) { ); } +function Link({ to, children }: React.PropsWithChildren<{ to: string }>) { + const navigate = useNavigate(); + return React.Children.map(children, (child) => { + if (child == null || typeof child !== 'object') return child; + return React.cloneElement(child, { + onClick() { + navigate(to); + }, + }); + }); +} + function App() { + const navigate = useNavigate(); const [r, setR] = useState(0); const [pos, setPos] = useState({ x: 0, y: 0 }); useEffect(() => { @@ -97,16 +121,18 @@ function App() { setPos({ x: touch.clientX - 200, y: touch.clientY - 150 }); }} > - + + + ); } @@ -248,16 +274,57 @@ function App() { // ); //} -document.body.onclick = (e) => { - console.log('body', e.offsetX, e.offsetY); -}; +//document.body.onclick = (e) => { +// console.log('body', e.offsetX, e.offsetY); +//}; +// +//document.body.ontouchmove = (e) => { +// console.log(e.target); +//}; +// +//document.getElementById('parent')!.ontouchstart = (e) => { +// console.log(e); +//}; + +function Page2() { + return ( + <> + + + Page 2 + + + + + + ); +} -document.body.ontouchmove = (e) => { - console.log(e.target); -}; +const routes = [ + { + path: '/', + element: , + //loader: () => FAKE_EVENT, + }, + { + path: '/page2', + element: , + //loader: () => FAKE_EVENT, + }, +]; -document.getElementById('parent')!.ontouchstart = (e) => { - console.log(e); -}; +const router = createMemoryRouter(routes, { + //initialEntries: ['/', '/foo'], + //initialIndex: 0, +}); -render(, canvas); +render(, canvas);