'use strict'; /* global importScripts, init, THREE */ importScripts('resources/threejs/r114/build/three.min.js'); importScripts('resources/threejs/r114/examples/js/controls/OrbitControls.js'); importScripts('shared-orbitcontrols.js'); function noop() { } class ElementProxyReceiver extends THREE.EventDispatcher { constructor() { super(); } get clientWidth() { return this.width; } get clientHeight() { return this.height; } getBoundingClientRect() { return { left: this.left, top: this.top, width: this.width, height: this.height, right: this.left + this.width, bottom: this.top + this.height, }; } handleEvent(data) { if (data.type === 'size') { this.left = data.left; this.top = data.top; this.width = data.width; this.height = data.height; return; } data.preventDefault = noop; data.stopPropagation = noop; this.dispatchEvent(data); } focus() { // no-op } } class ProxyManager { constructor() { this.targets = {}; this.handleEvent = this.handleEvent.bind(this); } makeProxy(data) { const {id} = data; const proxy = new ElementProxyReceiver(); this.targets[id] = proxy; } getProxy(id) { return this.targets[id]; } handleEvent(data) { this.targets[data.id].handleEvent(data.data); } } const proxyManager = new ProxyManager(); function start(data) { const proxy = proxyManager.getProxy(data.canvasId); proxy.body = proxy; // HACK! self.window = proxy; self.document = { addEventListener: proxy.addEventListener.bind(proxy), removeEventListener: proxy.removeEventListener.bind(proxy), }; init({ canvas: data.canvas, inputElement: proxy, }); } function makeProxy(data) { proxyManager.makeProxy(data); } const handlers = { start, makeProxy, event: proxyManager.handleEvent, }; self.onmessage = function(e) { const fn = handlers[e.data.type]; if (!fn) { throw new Error('no handler for type: ' + e.data.type); } fn(e.data); };