How to animate GIF on Canvas
How to show animated GIF on canvas?
You can't directly insert GIF image into the canvas. But we can use external library to parse the gif and then we can draw it into the layer as Konva.Image shape.
This demo uses gifler to parse and draw the GIF. You can use a different library.
- Vanilla
- React
- Vue
import Konva from 'konva';
// Load gifler library
const script = document.createElement('script');
script.src = 'https://unpkg.com/gifler@0.1.0/gifler.min.js';
document.head.appendChild(script);
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
});
const layer = new Konva.Layer();
stage.add(layer);
const canvas = document.createElement('canvas');
// use external library to parse and draw gif animation
function onDrawFrame(ctx, frame) {
// update canvas size
canvas.width = frame.width;
canvas.height = frame.height;
// update canvas that we are using for Konva.Image
ctx.drawImage(frame.buffer, 0, 0);
// redraw the layer
layer.draw();
}
script.onload = () => {
gifler('https://konvajs.org/assets/yoda.gif').frames(canvas, onDrawFrame);
};
// draw resulted canvas into the stage as Konva.Image
const image = new Konva.Image({
image: canvas,
});
layer.add(image);
import React from 'react';
import { Stage, Layer, Image } from 'react-konva';
const GifImage = () => {
const imageRef = React.useRef(null);
const canvasRef = React.useRef(document.createElement('canvas'));
React.useEffect(() => {
// Load gifler library
const script = document.createElement('script');
script.src = 'https://unpkg.com/gifler@0.1.0/gifler.min.js';
script.onload = () => {
// use external library to parse and draw gif animation
function onDrawFrame(ctx, frame) {
// update canvas size
canvasRef.current.width = frame.width;
canvasRef.current.height = frame.height;
// update canvas that we are using for Konva.Image
ctx.drawImage(frame.buffer, 0, 0);
// update Konva.Image
imageRef.current?.getLayer()?.batchDraw();
}
gifler('https://konvajs.org/assets/yoda.gif').frames(canvasRef.current, onDrawFrame);
};
document.head.appendChild(script);
return () => script.remove();
}, []);
return (
<Image
ref={imageRef}
image={canvasRef.current}
/>
);
};
const App = () => {
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
<GifImage />
</Layer>
</Stage>
);
};
export default App;
<template>
<v-stage :config="stageConfig">
<v-layer>
<v-image
:config="{ image: canvas }"
ref="imageRef"
/>
</v-layer>
</v-stage>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const canvas = document.createElement('canvas');
const imageRef = ref(null);
const stageConfig = {
width: window.innerWidth,
height: window.innerHeight
};
onMounted(() => {
// Load gifler library
const script = document.createElement('script');
script.src = 'https://unpkg.com/gifler@0.1.0/gifler.min.js';
script.onload = () => {
// use external library to parse and draw gif animation
function onDrawFrame(ctx, frame) {
// update canvas size
canvas.width = frame.width;
canvas.height = frame.height;
// update canvas that we are using for Konva.Image
ctx.drawImage(frame.buffer, 0, 0);
// update Konva.Image
imageRef.value.getNode().getLayer().batchDraw();
}
gifler('https://konvajs.org/assets/yoda.gif').frames(canvas, onDrawFrame);
};
document.head.appendChild(script);
return () => script.remove();
});
</script>
Instructions: The demo shows an animated GIF rendered on canvas using the gifler library. The GIF is parsed and each frame is drawn onto a canvas, which is then used as the source for a Konva.Image shape.