UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

97 lines (84 loc) 3.1 kB
import EventLoopItem from "../api/core/EventLoopItem" import nipplejs from "nipplejs" import { container } from "../engine/renderLoop/renderSetup" import IJoystick, { joystickDefaults, joystickSchema } from "../interface/IJoystick" import { Point } from "@lincode/math" import Nullable from "../interface/utils/Nullable" import createElement from "../utils/createElement" import { Cancellable } from "@lincode/promiselikes" import store, { Reactive } from "@lincode/reactivity" import { onBeforeRender } from "../events/onBeforeRender" export default class Joystick extends EventLoopItem implements IJoystick { public static componentName = "joystick" public static defaults = joystickDefaults public static schema = joystickSchema public onMove: Nullable<(e: Point) => void> public onMoveStart: Nullable<(e: Point) => void> public onMoveEnd: Nullable<(e: Point) => void> private onPressState = new Reactive<((e: Point) => void) | undefined>( undefined ) public get onPress() { return this.onPressState.get() } public set onPress(cb) { this.onPressState.set(cb) } public constructor() { super() let pt = new Point(0, 0) const [setDown, getDown] = store(false) this.createEffect(() => { const cb = this.onPressState.get() if (!cb || !getDown()) return const handle = onBeforeRender(() => { cb(pt) }) return () => { return handle.cancel() } }, [this.onPressState.get, getDown]) this.createEffect(() => { const zone = createElement<HTMLDivElement>(` <div style="width: 150px; height: 150px; position: absolute; bottom: 25px; left: 25px;"></div> `) container.appendChild(zone) const prevent = (e: Event) => { e.preventDefault() e.stopPropagation() } zone.onmousedown = prevent zone.ontouchstart = prevent zone.onpointerdown = prevent const handle = new Cancellable() setTimeout(() => { const manager = nipplejs.create({ zone, mode: "static", position: { left: "75px", bottom: "75px" }, color: "white" }) handle.then(() => manager.destroy()) manager.on("start", () => { this.onMoveStart?.(new Point(0, 0)) setDown(true) }) manager.on("move", (_, nipple) => { this.onMove?.(nipple.vector) pt = nipple.vector }) manager.on("end", () => { this.onMoveEnd?.(new Point(0, 0)) pt = new Point(0, 0) setDown(false) }) }) return () => { handle.cancel() } }, []) } }