You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
earthquake_3d_viewer_front/three/manual/examples/offscreencanvas-w-orbitcont...

239 lines
4.5 KiB
HTML

<!-- Licensed under a BSD license. See license.html for license -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Three.js - Offscreen Canvas</title>
<style>
html, body {
height: 100%;
margin: 0;
}
#c {
width: 100%;
height: 100%;
display: block;
}
#c:focus {
outline: none;
}
</style>
</head>
<body>
<canvas id="c" tabindex="1"></canvas>
</body>
<script type="module">
import { init } from './shared-orbitcontrols.js';
const mouseEventHandler = makeSendPropertiesHandler( [
'ctrlKey',
'metaKey',
'shiftKey',
'button',
'pointerType',
'clientX',
'clientY',
'pointerId',
'pageX',
'pageY',
] );
const wheelEventHandlerImpl = makeSendPropertiesHandler( [
'deltaX',
'deltaY',
] );
const keydownEventHandler = makeSendPropertiesHandler( [
'ctrlKey',
'metaKey',
'shiftKey',
'keyCode',
] );
function wheelEventHandler( event, sendFn ) {
event.preventDefault();
wheelEventHandlerImpl( event, sendFn );
}
function preventDefaultHandler( event ) {
event.preventDefault();
}
function copyProperties( src, properties, dst ) {
for ( const name of properties ) {
dst[ name ] = src[ name ];
}
}
function makeSendPropertiesHandler( properties ) {
return function sendProperties( event, sendFn ) {
const data = { type: event.type };
copyProperties( event, properties, data );
sendFn( data );
};
}
function touchEventHandler( event, sendFn ) {
// preventDefault() fixes mousemove, mouseup and mousedown
// firing at touch events when doing a simple touchup touchdown
// Happens only at offscreen canvas
event.preventDefault();
const touches = [];
const data = { type: event.type, touches };
for ( let i = 0; i < event.touches.length; ++ i ) {
const touch = event.touches[ i ];
touches.push( {
pageX: touch.pageX,
pageY: touch.pageY,
clientX: touch.clientX,
clientY: touch.clientY,
} );
}
sendFn( data );
}
// The four arrow keys
const orbitKeys = {
'37': true, // left
'38': true, // up
'39': true, // right
'40': true, // down
};
function filteredKeydownEventHandler( event, sendFn ) {
const { keyCode } = event;
if ( orbitKeys[ keyCode ] ) {
event.preventDefault();
keydownEventHandler( event, sendFn );
}
}
let nextProxyId = 0;
class ElementProxy {
constructor( element, worker, eventHandlers ) {
this.id = nextProxyId ++;
this.worker = worker;
const sendEvent = ( data ) => {
this.worker.postMessage( {
type: 'event',
id: this.id,
data,
} );
};
// register an id
worker.postMessage( {
type: 'makeProxy',
id: this.id,
} );
sendSize();
for ( const [ eventName, handler ] of Object.entries( eventHandlers ) ) {
element.addEventListener( eventName, function ( event ) {
handler( event, sendEvent );
} );
}
function sendSize() {
const rect = element.getBoundingClientRect();
sendEvent( {
type: 'size',
left: rect.left,
top: rect.top,
width: element.clientWidth,
height: element.clientHeight,
} );
}
// really need to use ResizeObserver
window.addEventListener( 'resize', sendSize );
}
}
function startWorker( canvas ) {
canvas.focus();
const offscreen = canvas.transferControlToOffscreen();
const worker = new Worker( 'offscreencanvas-worker-orbitcontrols.js', { type: 'module' } );
const eventHandlers = {
contextmenu: preventDefaultHandler,
mousedown: mouseEventHandler,
mousemove: mouseEventHandler,
mouseup: mouseEventHandler,
pointerdown: mouseEventHandler,
pointermove: mouseEventHandler,
pointerup: mouseEventHandler,
touchstart: touchEventHandler,
touchmove: touchEventHandler,
touchend: touchEventHandler,
wheel: wheelEventHandler,
keydown: filteredKeydownEventHandler,
};
const proxy = new ElementProxy( canvas, worker, eventHandlers );
worker.postMessage( {
type: 'start',
canvas: offscreen,
canvasId: proxy.id,
}, [ offscreen ] );
console.log( 'using OffscreenCanvas' ); /* eslint-disable-line no-console */
}
function startMainPage( canvas ) {
init( { canvas, inputElement: canvas } );
console.log( 'using regular canvas' ); /* eslint-disable-line no-console */
}
function main() { /* eslint consistent-return: 0 */
const canvas = document.querySelector( '#c' );
if ( canvas.transferControlToOffscreen ) {
startWorker( canvas );
} else {
startMainPage( canvas );
}
}
main();
</script>
</html>