mirror of
https://github.com/nesbox/TIC-80.git
synced 2026-04-18 22:42:27 +00:00
* web: Fix Safari Arrow keys in HTML export and webapp\n\n- Remap Arrow key events with KeyboardEvent.location === 3 (numpad) to location: 0 on WebKit in capture phase\n- Prevent page scrolling on Arrow keys while canvas is focused\n- Ensure canvas is focusable (tabindex=0) and focused on start\n\nThis addresses Safari/WebKit misclassification of physical Arrow keys so games receive directional input correctly. * Add missing semicolon * Update index.html * Update index.html
142 lines
5.4 KiB
HTML
142 lines
5.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#f4f4f4"/>
|
|
|
|
<link rel="manifest" href="tic80.webmanifest">
|
|
<link rel="apple-touch-icon" sizes="180x180" href="tic80-180.png">
|
|
<link rel="apple-touch-icon" sizes="192x192" href="tic80-192.png">
|
|
<link rel="apple-touch-icon" sizes="512x512" href="tic80-512.png">
|
|
<title>TIC-80</title>
|
|
<style>
|
|
body {
|
|
margin:0; padding:0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh;
|
|
}
|
|
|
|
.tic80-container {
|
|
width: 100%; padding-top: 56.66%; position: relative;
|
|
}
|
|
|
|
.tic80-canvas {
|
|
position: absolute; top: 0; left:0; width: 100%; height: 100%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="tic80-container">
|
|
<canvas class="tic80-canvas" id="canvas" oncontextmenu="event.preventDefault()" tabindex="1"></canvas>
|
|
</div>
|
|
|
|
<script type="module">
|
|
import startTic80 from './tic80.js'
|
|
|
|
navigator.serviceWorker.register('serviceworker.js');
|
|
|
|
// Safari/WebKit-only: remap Arrow keys with location 3 (numpad) to location 0.
|
|
(function(){
|
|
const ua = navigator.userAgent || '';
|
|
const isWebKit = /AppleWebKit/i.test(ua);
|
|
if (!isWebKit) return;
|
|
|
|
const synthesizeArrowWithLocation0 = (orig) => {
|
|
try {
|
|
const ev = new KeyboardEvent(orig.type, {
|
|
key: orig.key,
|
|
code: orig.code,
|
|
location: 0,
|
|
repeat: orig.repeat,
|
|
ctrlKey: orig.ctrlKey,
|
|
shiftKey: orig.shiftKey,
|
|
altKey: orig.altKey,
|
|
metaKey: orig.metaKey,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
});
|
|
Object.defineProperty(ev, 'which', { get: () => orig.which });
|
|
Object.defineProperty(ev, 'keyCode', { get: () => orig.keyCode });
|
|
return ev;
|
|
} catch { return null; }
|
|
};
|
|
|
|
const remapArrowLocationCapture = (e) => {
|
|
const isArrow = (e.key && e.key.startsWith('Arrow')) || (e.code && e.code.startsWith('Arrow'));
|
|
if (!isArrow) return;
|
|
if (e.location === 3) {
|
|
const syn = synthesizeArrowWithLocation0(e);
|
|
if (syn) {
|
|
e.stopImmediatePropagation();
|
|
e.preventDefault();
|
|
(e.target || document.getElementById('canvas')).dispatchEvent(syn);
|
|
}
|
|
}
|
|
};
|
|
|
|
['keydown','keyup'].forEach(t => document.addEventListener(t, remapArrowLocationCapture, true));
|
|
})();
|
|
|
|
// Prevent page scrolling while the canvas is focused
|
|
(function(){
|
|
const canvasEl = document.getElementById('canvas');
|
|
const preventArrowDefault = (e) => {
|
|
const key = e.key || e.code;
|
|
const kc = e.keyCode || e.which;
|
|
const isArrow = (key && ['ArrowUp','ArrowDown','ArrowLeft','ArrowRight'].includes(key)) || (kc >= 37 && kc <= 40);
|
|
if (isArrow && document.activeElement === canvasEl) e.preventDefault();
|
|
};
|
|
document.addEventListener('keydown', preventArrowDefault, { passive: false });
|
|
canvasEl.addEventListener('keydown', preventArrowDefault, { passive: false });
|
|
})();
|
|
|
|
const initialize = () => {
|
|
const canvasSelector = '#canvas'
|
|
const canvasElement = document.querySelector(canvasSelector)
|
|
|
|
const options = {
|
|
canvas: document.getElementById('canvas'),
|
|
|
|
saveAs (blob, filename) {
|
|
const url = URL.createObjectURL(blob)
|
|
|
|
const link = document.createElement('a')
|
|
link.href = url
|
|
link.download = filename
|
|
|
|
link.click()
|
|
},
|
|
|
|
showAddPopup (callback) {
|
|
callback(null, null)
|
|
var input = document.createElement('input')
|
|
input.type = 'file'
|
|
input.click()
|
|
input.addEventListener('change', (event) => {
|
|
const file = event.target.files[0]
|
|
if (file) {
|
|
var reader = new FileReader
|
|
reader.onload = function(event) {
|
|
var rom = new Uint8Array(event.target.result)
|
|
callback(file.name, rom)
|
|
}
|
|
reader.readAsArrayBuffer(file)
|
|
}
|
|
})
|
|
},
|
|
|
|
preRun: [
|
|
function (module) {
|
|
module.ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = canvasSelector
|
|
}
|
|
]
|
|
}
|
|
|
|
canvasElement.focus()
|
|
startTic80(options)
|
|
}
|
|
|
|
window.addEventListener('DOMContentLoaded', initialize)
|
|
</script>
|
|
</body>
|
|
</html>
|