Rendering onto an OffscreenCanvas using Web Workers
Hi,
I have a number of fairly high refresh rate charts all being rendered at once. To take pressure off the main thread, I was wondering if I could use web workers to offload the rendering.
Below is the code that I've tried so far. As you can see, I had to mock the window object and the getAttribute() calls for height and width. I'm now facing an error: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image source is detached, which I understand to mean that no frame is ready to draw.
Any insights would be greatly appreciated.
<!-- src/components/SmoothieChart.vue -->
<template>
<div>
<canvas ref="onscreenCanvas" :width="width" :height="height"></canvas>
</div>
</template>
<script>
import { onMounted, ref } from 'vue';
import Smoothie from 'smoothie';
export default {
props: {
width: {
type: Number,
required: true,
},
height: {
type: Number,
required: true,
},
},
setup(props) {
const onscreenCanvas = ref(null);
onMounted(() => {
const offscreenCanvas = new OffscreenCanvas(props.width, props.height);
const worker = new Worker(new URL('./smoothieWorker.js', import.meta.url));
worker.postMessage({ offscreenCanvas }, [offscreenCanvas]);
const ctx = onscreenCanvas.value.getContext('2d');
worker.onmessage = (event) => {
if (event.data.type === 'frameReady') {
ctx.drawImage(offscreenCanvas, 0, 0);
}
};
});
return { onscreenCanvas };
},
};
</script>
// src/components/smoothieWorker.js
self.window = self;
importScripts('https://cdn.jsdelivr.net/npm/[email protected]/smoothie.js');
self.addEventListener('message', (event) => {
const { offscreenCanvas } = event.data;
createSmoothieChart(offscreenCanvas);
});
function createSmoothieChart(offscreenCanvas) {
const smoothieChart = new Smoothie.SmoothieChart({
grid: { strokeStyle: 'rgba(255, 255, 255, 0.1)', lineWidth: 1 },
labels: { fillStyle: 'rgba(255, 255, 255, 0.8)' },
millisPerPixel: 20,
responsive: true,
});
const timeSeries = new Smoothie.TimeSeries();
smoothieChart.addTimeSeries(timeSeries, { lineWidth: 2, strokeStyle: 'rgb(0, 255, 0)' });
smoothieChart.streamTo(offscreenCanvas, 1000 / 60);
setInterval(() => {
timeSeries.append(new Date().getTime(), Math.random() * 100);
self.postMessage({ type: 'frameReady' }); // Send a message back when a frame is ready
}, 1000);
}
Have you managed to make it work without smoothie?
Yes I have, I have it working with Chart.js.
On Thu, 6 Apr 2023 at 13:52, WofWca @.***> wrote:
Have you managed to make it work without smoothie?
— Reply to this email directly, view it on GitHub https://github.com/joewalnes/smoothie/issues/153#issuecomment-1498527718, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWDI6IE6RHZFSHL2PRVRBWDW7ZKYVANCNFSM6AAAAAAWU33VVY . You are receiving this because you authored the thread.Message ID: @.***>
-- Isaac Monteath
Nonlinear Solutions 3/63 Knutsford Avenue Rivervale WA 6103 M: (+61) 0479 128 404 www.nonlinear.com.au
I mean try commenting out the smoothie code above and see if the setup works.