How to init Lottie with offscreen canvas?
ilchenkoea opened this issue · 1 comments
ilchenkoea commented
Hi!
We are trying to use Lottie for rendering on offscreen canvas (via Emscripten, not Chromium).
Currently we cannot understand possibility of this...
Now I'm trying to debug this code:
var offscreenCanvas = new OffscreenCanvas(2000, 2000);
var offscreenCtx = offscreenCanvas.getContext('2d');
// Create a bitmap renderer for the off-screen canvas
var bitmapRenderer = {
canvas: offscreenCanvas,
context: offscreenCtx,
clearRect: function(x, y, w, h) {
this.context.clearRect(x, y, w, h);
},
drawImage: function(image, dx, dy, dw, dh) {
this.context.drawImage(image, dx, dy, dw, dh);
},
};
function setupLottieAnimation() {
// Load and render the Lottie animation
var animation = lottie.loadAnimation({
container: bitmapRenderer, // Use the off-screen canvas renderer
offscreen: true,
loop: false,
autoplay: false,
path: 'https://assets4.lottiefiles.com/packages/lf20_zyquagfl.json'// Replace with the path to your Lottie JSON file
});
console.log('not ready');
return new Promise((resolve) => {
animation.addEventListener('data_ready', function () {
console.log('Animation data is ready');
console.log(animation.totalFrames); // Log total frames
console.log(animation.getDuration(false)); // Log total duration (ms
resolve(); // Resolve the promise when animation is ready
});
});
}
It doesn't work, because bitmapRenderer
doesn't have appendChild
method, exception is thrown from this lottie code:
this.animationItem.wrapper.appendChild(this.svgElement);
And same situation if I'll try to pass offscreenCanvas
object instead of bitmapRenderer
.
Could you say, does lottie support offscreen canvas for this moment?
Thank you!
ilchenkoea commented
It works now, here is example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lottie Animation</title>
</head>
<body>
<canvas id="mainCanvas"></canvas>
<div id="lottie-container"></div>
<!-- Load the Lottie library from a CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js"></script>
<script>
// Function to initialize and draw the Lottie animation on the off-screen canvas
function drawLottieOnOffscreenCanvas() {
var mainCanvas = document.getElementById('mainCanvas');
mainCanvas.width = 1000;
mainCanvas.height = 1000;
var mainCtx = mainCanvas.getContext('2d');
// Create an off-screen canvas
var offscreenCanvas = new OffscreenCanvas(1000, 1000);
var offscreenCtx = offscreenCanvas.getContext('2d');
function setupLottieAnimation() {
// Load and render the Lottie animation
animation = lottie.loadAnimation({
renderer: "canvas",
loop: false,
autoplay: false,
rendererSettings: {
context: offscreenCtx,
scaleMode: 'noScale',
clearCanvas: true
},
path: 'https://assets4.lottiefiles.com/packages/lf20_zyquagfl.json'// Replace with the path to your Lottie JSON file
});
return new Promise((resolve) => {
animation.addEventListener('data_ready', function () {
console.log('Animation data is ready');
console.log(animation.totalFrames); // Log total frames
console.log(animation.getDuration(false)); // Log total duration (ms
resolve(); // Resolve the promise when animation is ready
});
});
}
async function manipulate(context) {
if (context.action == "init") {
console.log('Initializing and drawing animation');
await setupLottieAnimation(); // Wait until the setup is complete
} else if (context.action == "seek") {
console.log('Seeking time:', context.time);
animation.goToAndStop(context.time * 1000);
}
}
let context0 = {action:"init"};
manipulate(context0).then(
function(value) {
let context1 = {action:"seek", time:0.7};
manipulate(context1);
},
function(error) {
console.log('Error:', error);
}
);
function transferToMainCanvas() {
mainCtx.clearRect(0, 0, mainCanvas.width, mainCanvas.height);
mainCtx.drawImage(offscreenCanvas, 0, 0);
requestAnimationFrame(transferToMainCanvas);
}
transferToMainCanvas();
}
// Call the function to start the process
drawLottieOnOffscreenCanvas();
</script>
</body>
</html>