diff --git a/examples/offscreen-canvas.js b/examples/offscreen-canvas.js index 991b757300..180e5c990e 100644 --- a/examples/offscreen-canvas.js +++ b/examples/offscreen-canvas.js @@ -11,7 +11,7 @@ import Source from '../src/ol/source/Source.js'; const worker = new Worker(); -let container, transformContainer, canvas, workerFrameState, mainThreadFrameState; +let container, transformContainer, canvas, rendering, workerFrameState, mainThreadFrameState; // Transform the container to account for the differnece between the (newer) // main thread frameState and the (older) worker frameState @@ -62,10 +62,15 @@ const map = new Map({ } mainThreadFrameState = frameState; updateContainerTransform(); - worker.postMessage({ - action: 'render', - frameState: JSON.parse(stringify(frameState)) - }); + if (!rendering) { + rendering = true; + worker.postMessage({ + action: 'render', + frameState: JSON.parse(stringify(frameState)) + }); + } else { + frameState.animate = true; + } return container; }, source: new Source({ @@ -101,18 +106,20 @@ worker.addEventListener('message', message => { }); }); image.src = event.data.src; - } else if (message.data.action === 'request-render') { + } else if (message.data.action === 'requestRender') { // Worker requested a new render frame map.render(); } else if (canvas && message.data.action === 'rendered') { // Worker provies a new render frame - transformContainer.style.transform = ''; - const imageData = message.data.imageData; - canvas.width = imageData.width; - canvas.height = imageData.height; - canvas.getContext('2d').drawImage(imageData, 0, 0); - canvas.style.transform = message.data.transform; - workerFrameState = message.data.frameState; - updateContainerTransform(); + requestAnimationFrame(function() { + const imageData = message.data.imageData; + canvas.width = imageData.width; + canvas.height = imageData.height; + canvas.getContext('2d').drawImage(imageData, 0, 0); + canvas.style.transform = message.data.transform; + workerFrameState = message.data.frameState; + updateContainerTransform(); + }); + rendering = false; } }); diff --git a/examples/offscreen-canvas.worker.js b/examples/offscreen-canvas.worker.js index e80187e7af..b03f0be61d 100644 --- a/examples/offscreen-canvas.worker.js +++ b/examples/offscreen-canvas.worker.js @@ -14,6 +14,9 @@ const worker = self; let frameState, pixelRatio, rendererTransform; const canvas = new OffscreenCanvas(1, 1); +// OffscreenCanvas does not have a style, so we mock it +canvas.style = {}; +const context = canvas.getContext('2d'); const sources = { landcover: new VectorTileSource({ @@ -77,18 +80,17 @@ function loadStyles() { }); layer.getRenderer().useContainer = function(target, transform) { this.containerReused = this.getLayer() !== layers[0]; - target.style = {}; - this.canvas = target; - this.context = target.getContext('2d'); + this.canvas = canvas; + this.context = context; this.container = { - firstElementChild: target + firstElementChild: canvas }; rendererTransform = transform; }; styleFunction(layer, styleJson, bucket.layers, undefined, spriteJson, spriteImageUrl, getFont); layers.push(layer); }); - worker.postMessage({action: 'request-render'}); + worker.postMessage({action: 'requestRender'}); }); }); } @@ -97,11 +99,10 @@ function loadStyles() { const tileQueue = new TileQueue( (tile, tileSourceKey, tileCenter, tileResolution) => tilePriorityFunction(frameState, tile, tileSourceKey, tileCenter, tileResolution), - () => worker.postMessage({action: 'request-render'})); + () => worker.postMessage({action: 'requestRender'})); const maxTotalLoading = 8; const maxNewLoads = 2; -let rendering = false; worker.addEventListener('message', event => { if (event.data.action !== 'render') { @@ -114,34 +115,22 @@ worker.addEventListener('message', event => { } frameState.tileQueue = tileQueue; frameState.viewState.projection.__proto__ = Projection.prototype; - if (rendering) { - return; - } - rendering = true; - requestAnimationFrame(() => { - let rendered = false; - layers.forEach(layer => { - if (inView(layer.getLayerState(), frameState.viewState)) { - rendered = true; - const renderer = layer.getRenderer(); - renderer.renderFrame(frameState, canvas); - } - }); - rendering = false; - if (!rendered) { - return; + layers.forEach(layer => { + if (inView(layer.getLayerState(), frameState.viewState)) { + const renderer = layer.getRenderer(); + renderer.renderFrame(frameState, canvas); } - renderDeclutterItems(frameState, null); - if (tileQueue.getTilesLoading() < maxTotalLoading) { - tileQueue.reprioritize(); - tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads); - } - const imageData = canvas.transferToImageBitmap(); - worker.postMessage({ - action: 'rendered', - imageData: imageData, - transform: rendererTransform, - frameState: JSON.parse(stringify(frameState)) - }, [imageData]); }); + renderDeclutterItems(frameState, null); + if (tileQueue.getTilesLoading() < maxTotalLoading) { + tileQueue.reprioritize(); + tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads); + } + const imageData = canvas.transferToImageBitmap(); + worker.postMessage({ + action: 'rendered', + imageData: imageData, + transform: rendererTransform, + frameState: JSON.parse(stringify(frameState)) + }, [imageData]); });