From 534fd76d069d7fb1616b484266b3240da4986743 Mon Sep 17 00:00:00 2001 From: Himanshu Jangid <himanshujhar@gmail.com> Date: Sat, 23 Sep 2023 01:17:02 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8feat=20(engine:=20input)=20add=20keybo?= =?UTF-8?q?ard=20input=20support=20and=20examples.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/index.html | 1 + examples/keyboard-inputs/index.html | 82 +++++++++++++++++++++++++++++ examples/keyboard-inputs/script.ts | 39 ++++++++++++++ examples/vite.config.js | 1 + lib/input/input.ts | 47 ++++++++++++++++- lib/render/engine.ts | 5 +- lib/types/canvas.ts | 1 + 7 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 examples/keyboard-inputs/index.html create mode 100644 examples/keyboard-inputs/script.ts diff --git a/examples/index.html b/examples/index.html index 1e0342c..277aa18 100644 --- a/examples/index.html +++ b/examples/index.html @@ -20,6 +20,7 @@ <h2>We got examples for you</h2> <li><a href="/drawing/">Drawing</a></li> <li><a href="/colors/">Colors</a></li> <li><a href="/mouse-inputs/">Mouse Inputs</a></li> + <li><a href="/keyboard-inputs/">Keyboard Inputs</a></li> <li><a href="/update/">Update</a></li> </ul> <script type="module" src="/src/main.ts"></script> diff --git a/examples/keyboard-inputs/index.html b/examples/keyboard-inputs/index.html new file mode 100644 index 0000000..61938ec --- /dev/null +++ b/examples/keyboard-inputs/index.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <link rel="icon" type="image/svg+xml" href="/vite.svg" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <link + rel="stylesheet" + href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/default.min.css" + /> + <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script> + + <!-- and it's easy to individually load additional languages --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/go.min.js"></script> + <script src="https://unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.js"></script> + <link + rel="stylesheet" + href="https://unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.css" + /> + <link rel="stylesheet" href="/styles.css" /> + + <script> + hljs.addPlugin(new CopyButtonPlugin()); + hljs.highlightAll(); + </script> + <title>MiniPoint Colors</title> + </head> + <body> + <div id="app"> + Mouse Click Event Examples (Colorful Bees & Gods painting). Toggle + checkbox to see difference. Press 'J' to put point on the canvas + </div> + <label for="">Clear canvas per frame</label + ><input type="checkbox" name="checkbox" id="checkbox" checked /> + <div class="main-area"> + <canvas id="canvas"></canvas> + <pre><code class="language-javascript"> +import { Engine, Point } from '../../lib'; + +const engine = new Engine( + document.getElementById('canvas') as HTMLCanvasElement, + { + engineOptions: { + width: 600, + height: 400, + }, + }, +); + +const { renderer, input } = engine; + +const random = () => { + return Math.random(); +}; + +document.getElementById('checkbox')?.addEventListener('change', (e) => { + engine.options.engineOptions!.clearEachFrame = (e.target as any).checked; +}); + +engine.update = () => { + if (input.keyboard.currentUpKey?.toLowerCase() === 'j') { + const p1 = new Point({ + x: input.mouse.position.x, + y: input.mouse.position.y, + radius: 6, + color: `rgb(${random() * 255}, ${random() * 255}, ${random() * 255})`, + }); + + p1.update = () => { + p1.options.x += random() > 0.5 ? random() * 2 : -random() * 2; + p1.options.y += random() > 0.5 ? random() * 2 : -random() * 2; + }; + + renderer.addObject(p1); + } +}; + + </code></pre> + </div> + <script type="module" src="./script.ts"></script> + </body> +</html> diff --git a/examples/keyboard-inputs/script.ts b/examples/keyboard-inputs/script.ts new file mode 100644 index 0000000..f92ba4a --- /dev/null +++ b/examples/keyboard-inputs/script.ts @@ -0,0 +1,39 @@ +import { Engine, Point } from '../../lib'; + +const engine = new Engine( + document.getElementById('canvas') as HTMLCanvasElement, + { + engineOptions: { + width: 600, + height: 400, + }, + }, +); + +const { renderer, input } = engine; + +const random = () => { + return Math.random(); +}; + +document.getElementById('checkbox')?.addEventListener('change', (e) => { + engine.options.engineOptions!.clearEachFrame = (e.target as any).checked; +}); + +engine.update = () => { + if (input.keyboard.currentUpKey?.toLowerCase() === 'j') { + const p1 = new Point({ + x: input.mouse.position.x, + y: input.mouse.position.y, + radius: 6, + color: `rgb(${random() * 255}, ${random() * 255}, ${random() * 255})`, + }); + + p1.update = () => { + p1.options.x += random() > 0.5 ? random() * 2 : -random() * 2; + p1.options.y += random() > 0.5 ? random() * 2 : -random() * 2; + }; + + renderer.addObject(p1); + } +}; diff --git a/examples/vite.config.js b/examples/vite.config.js index c445fd8..faf955c 100644 --- a/examples/vite.config.js +++ b/examples/vite.config.js @@ -12,6 +12,7 @@ export default defineConfig({ colors: resolve(__dirname, 'colors/index.html'), mouse_inputs: resolve(__dirname, 'mouse-inputs/index.html'), update: resolve(__dirname, 'update/index.html'), + keyboard_inputs: resolve(__dirname, 'keyboard-inputs/index.html'), }, }, }, diff --git a/lib/input/input.ts b/lib/input/input.ts index d60dd5f..315955f 100644 --- a/lib/input/input.ts +++ b/lib/input/input.ts @@ -71,5 +71,50 @@ export class MouseInput { } export class KeyBoardInput { - constructor(_engine: Engine) {} + currentDownKey: string = ''; + currentUpKey: string = ''; + currentPressedKey: string = ''; + shiftKey?: boolean; + altKey?: boolean; + ctrlKey?: boolean; + + engine: Engine; + + constructor(engine: Engine) { + this.engine = engine; + window.addEventListener('keydown', (event) => { + this.currentDownKey = this.getKey(event.key); + this.currentUpKey = ''; + this.altKey = event.altKey; + this.shiftKey = event.shiftKey; + this.ctrlKey = event.ctrlKey; + }); + + window.addEventListener('keypress', (event) => { + this.currentDownKey = this.getKey(event.key); + this.currentUpKey = ''; + this.altKey = event.altKey; + this.shiftKey = event.shiftKey; + this.ctrlKey = event.ctrlKey; + }); + + window.addEventListener('keyup', (event) => { + this.altKey = event.altKey; + this.shiftKey = event.shiftKey; + this.ctrlKey = event.ctrlKey; + this.currentUpKey = this.getKey(event.key); + this.currentDownKey = ''; + this.currentPressedKey = ''; + }); + } + + getKey(key: string) { + if (!key) return ''; + + if (this.engine.options.engineOptions?.preserveKeyboardInputCase) { + return key; + } + + return key.toLowerCase(); + } } diff --git a/lib/render/engine.ts b/lib/render/engine.ts index 0813190..5b295ba 100644 --- a/lib/render/engine.ts +++ b/lib/render/engine.ts @@ -56,8 +56,8 @@ export class Engine { // the initial position is calculated based on scrolled window. // otherwise, the position may be unexpected this.position = new Vector(x - window.scrollX, y - -window.scrollY); - this.width = this.canvas.width; - this.height = this.canvas.height; + this.width = this.options.engineOptions?.width!; + this.height = this.options.engineOptions?.height!; this.canvas.style.border = options.engineOptions!.border!; this.canvas.style.background = options.engineOptions!.bg!; this.canvas.style.width = options.engineOptions!.width!.toString() + 'px'; @@ -101,5 +101,6 @@ export class Engine { resetEvent() { this.input.mouse.click = false; this.input.mouse.move = false; + this.input.keyboard.currentUpKey = ''; } } diff --git a/lib/types/canvas.ts b/lib/types/canvas.ts index aa3a519..f85a697 100644 --- a/lib/types/canvas.ts +++ b/lib/types/canvas.ts @@ -18,6 +18,7 @@ export type EngineOptions = { // TODO: not yet decided engineOptions?: { clearEachFrame?: boolean; + preserveKeyboardInputCase?: boolean; border?: string; bg?: string; width?: number;