diff --git a/css/apple2.css b/css/apple2.css
index 916ef7f..a60881c 100644
--- a/css/apple2.css
+++ b/css/apple2.css
@@ -217,6 +217,8 @@ canvas {
image-rendering: optimizeSpeed;
width: 592px;
height: 416px;
+ touch-action: manipulation;
+ user-select: none;
}
#screen.mouseMode {
diff --git a/index.html b/index.html
index 37fa90a..cf1a2aa 100644
--- a/index.html
+++ b/index.html
@@ -1,6 +1,9 @@
PreApple II
+
+
+
diff --git a/js/ui/mouse.ts b/js/ui/mouse.ts
index c16b255..fdcc3ef 100644
--- a/js/ui/mouse.ts
+++ b/js/ui/mouse.ts
@@ -1,30 +1,87 @@
import type Mouse from '../cards/mouse';
import { enableMouseMode } from './joystick';
+type TouchEventWithTarget = TouchEvent & { target: HTMLCanvasElement };
+
export class MouseUI {
private mouse: Mouse;
constructor(private canvas: HTMLCanvasElement) {
- this.canvas.addEventListener(
- 'mousemove',
- (event: MouseEvent & { target: HTMLCanvasElement} ) => {
- const { offsetX, offsetY, target } = event;
- this.mouse.setMouseXY(
- offsetX,
- offsetY,
- target.clientWidth,
- target.clientHeight
- );
+ const updateTouchXY = (event: TouchEventWithTarget) => {
+ const { targetTouches, target } = event;
+ if (targetTouches.length < 1) {
+ return;
}
- );
+ const rect = target.getBoundingClientRect();
+ const leftPad = (rect.width - 560) / 2 + rect.left;
+ const topPad = (rect.height - 384) / 2 + rect.top;
+ const { clientX, clientY } = targetTouches[0];
+ const xPos = clientX - leftPad;
+ const yPos = clientY - topPad;
+ this.mouse.setMouseXY(
+ Math.max(Math.min(xPos, 559), 0),
+ Math.max(Math.min(yPos, 383), 0),
+ 560,
+ 384,
+ );
+ };
- this.canvas.addEventListener('mousedown', () => {
- this.mouse.setMouseDown(true);
- });
+ if ('ontouchstart' in window) {
+ this.canvas.addEventListener(
+ 'touchmove',
+ (event: TouchEventWithTarget) => {
+ updateTouchXY(event);
+ }
+ );
- this.canvas.addEventListener('mouseup', () => {
- this.mouse.setMouseDown(false);
- });
+ this.canvas.addEventListener(
+ 'touchstart',
+ (event: TouchEventWithTarget) => {
+ updateTouchXY(event);
+ // Make sure the mouse down is processed in a different
+ // pass as the move, so that a simple tap isn't treated like
+ // a drag.
+ setTimeout(() => this.mouse.setMouseDown(true), 100);
+ }
+ );
+
+ this.canvas.addEventListener(
+ 'touchend',
+ (event: TouchEventWithTarget) => {
+ updateTouchXY(event);
+ this.mouse.setMouseDown(false);
+ }
+ );
+
+ this.canvas.addEventListener(
+ 'touchcancel',
+ (event: TouchEventWithTarget) => {
+ updateTouchXY(event);
+ this.mouse.setMouseDown(false);
+ }
+ );
+ } else {
+ this.canvas.addEventListener(
+ 'mousemove',
+ (event: MouseEvent & { target: HTMLCanvasElement} ) => {
+ const { offsetX, offsetY, target } = event;
+ this.mouse.setMouseXY(
+ offsetX,
+ offsetY,
+ target.clientWidth,
+ target.clientHeight
+ );
+ }
+ );
+
+ this.canvas.addEventListener('mousedown', () => {
+ this.mouse.setMouseDown(true);
+ });
+
+ this.canvas.addEventListener('mouseup', () => {
+ this.mouse.setMouseDown(false);
+ });
+ }
}
setMouse = (mouse: Mouse) => {