From 298ac74d3266debfae0da48651c815a5ba6ab0eb Mon Sep 17 00:00:00 2001 From: behoney Date: Tue, 21 Feb 2023 23:00:28 +0900 Subject: [PATCH 1/3] feat: custom event type --- src/components/Keyboard/Key/index.tsx | 21 +++++++++++++++++---- src/types/ThreeEvent.d.ts | 24 ++++++++++++++++++++++++ tsconfig.json | 3 ++- 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 src/types/ThreeEvent.d.ts diff --git a/src/components/Keyboard/Key/index.tsx b/src/components/Keyboard/Key/index.tsx index 7f262e4..788f727 100644 --- a/src/components/Keyboard/Key/index.tsx +++ b/src/components/Keyboard/Key/index.tsx @@ -1,10 +1,11 @@ import { ThreeEvent, useFrame } from '@react-three/fiber' -import React, { useRef, useState } from 'react' +import React, { useEffect, useRef, useState } from 'react' import KeyCap from './KeyCap' import KeyLegend from './KeyLegend' import { IkeyConfig } from '../../../types/KeyboardType' import { KEY_DOWN_DURATION, KEY_DOWN_POSITION } from './consts' import { Howl } from 'howler' +import { ThreeEventType } from '../../../types/ThreeEvent' type KeyProps = { keyConfig: IkeyConfig } @@ -13,19 +14,31 @@ export default (props: KeyProps) => { const [keyDownPosition, setKeyDownPosition] = useState(0) const howl = useRef(new Howl({ src: 'sample_audio.ogg' })) + useEffect(() => { + document.addEventListener('threekeyboardevent', keyboardEventHander) + + return () => { + document.removeEventListener('threekeyboardevent', keyboardEventHander) + } + }, []) + useFrame(() => { keyDownPosition < 0 && setKeyDownPosition((prev) => prev + KEY_DOWN_DURATION) }) - const onKeyClick = (evt: ThreeEvent) => { - evt.stopPropagation() + const onKeyClick = (evt?: ThreeEvent) => { + evt?.stopPropagation() setKeyDownPosition(KEY_DOWN_POSITION) howl.current?.play() } + const keyboardEventHander = (evt: CustomEvent) => { + if (evt.detail?.keyId === keyConfig.legend?.text.toLowerCase()) onKeyClick() + } + return ( - + +} +declare global { + interface Document { + //adds definition to Document, but you can do the same with HTMLElement + addEventListener( + type: K, + listener: (this: Document, ev: ThreeCustomEvent[K]) => void, + ): void + removeEventListener( + type: K, + listener: (this: Document, ev: ThreeCustomEvent[K]) => void, + ): void + dispatchEvent( + ev: ThreeCustomEvent[K], + ): void + } +} +export {} diff --git a/tsconfig.json b/tsconfig.json index a273b0c..6491b32 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,7 +18,8 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "typeRoots": ["src/types/ThreeEvent"] }, "include": [ "src" From acccb9ae7a35a47fb62864bc350271da11d9e834 Mon Sep 17 00:00:00 2001 From: behoney Date: Tue, 21 Feb 2023 23:01:23 +0900 Subject: [PATCH 2/3] chore: lint --- src/index.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 86931fa..6ad9479 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,7 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import "./index.css"; -import App from "./App"; +import React from 'react' +import ReactDOM from 'react-dom/client' +import './index.css' +import App from './App' -const root = ReactDOM.createRoot( - document.getElementById("root") as HTMLElement -); -root.render(); +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) +root.render() From 38c90ac9a28c455589d0002d095af06f0ec8c02d Mon Sep 17 00:00:00 2001 From: behoney Date: Tue, 21 Feb 2023 23:08:59 +0900 Subject: [PATCH 3/3] feat: add helper function to generate custom event. --- src/components/Keyboard/Key/index.tsx | 14 ++++++++++++++ src/index.tsx | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/src/components/Keyboard/Key/index.tsx b/src/components/Keyboard/Key/index.tsx index 788f727..98f882c 100644 --- a/src/components/Keyboard/Key/index.tsx +++ b/src/components/Keyboard/Key/index.tsx @@ -50,3 +50,17 @@ export default (props: KeyProps) => { ) } + +export const genCustomKeyEventFromCharacter = ( + char: string, +): CustomEvent => { + if (char.length !== 1) { + throw new Error( + `Invalid input for custom key event. Input should be single charater. Input is ${char}, though.`, + ) + } + + return new CustomEvent('threekeyboardevent', { + detail: { keyId: char.toLowerCase() }, + }) +} diff --git a/src/index.tsx b/src/index.tsx index 6ad9479..1ff3466 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,6 +2,12 @@ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import App from './App' +import { genCustomKeyEventFromCharacter } from './components/Keyboard/Key' const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) root.render() + +document.addEventListener('keydown', (evt) => { + const event = genCustomKeyEventFromCharacter(evt.key) + document.dispatchEvent(event) +})