如何在 Canvas 上动画 GIF
如何在画布上显示动画 GIF?
你不能直接将 GIF 图像插入到画布中。但我们可以使用外部库来解析 GIF,然后将其作为 Konva.Image
形状绘制到图层中。
在这个演示中,我们将使用 gifler 来解析和绘制 GIF。你可以使用任何其他库。
- Vanilla
- React
- Vue
import Konva from 'konva'; // 加载 gifler 库 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'); // 使用外部库解析并绘制 GIF 动画 function onDrawFrame(ctx, frame) { // 更新画布大小 canvas.width = frame.width; canvas.height = frame.height; // 更新我们用于 Konva.Image 的画布 ctx.drawImage(frame.buffer, 0, 0); // 重新绘制图层 layer.draw(); } script.onload = () => { gifler('https://konvajs.org/assets/yoda.gif').frames(canvas, onDrawFrame); }; // 将结果画布绘制到舞台作为 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(() => { // 加载 gifler 库 const script = document.createElement('script'); script.src = 'https://unpkg.com/gifler@0.1.0/gifler.min.js'; script.onload = () => { // 使用外部库解析并绘制 GIF 动画 function onDrawFrame(ctx, frame) { // 更新画布大小 canvasRef.current.width = frame.width; canvasRef.current.height = frame.height; // 更新我们用于 Konva.Image 的画布 ctx.drawImage(frame.buffer, 0, 0); // 更新 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(() => { // 加载 gifler 库 const script = document.createElement('script'); script.src = 'https://unpkg.com/gifler@0.1.0/gifler.min.js'; script.onload = () => { // 使用外部库解析并绘制 GIF 动画 function onDrawFrame(ctx, frame) { // 更新画布大小 canvas.width = frame.width; canvas.height = frame.height; // 更新我们用于 Konva.Image 的画布 ctx.drawImage(frame.buffer, 0, 0); // 更新 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>
说明:该演示展示了使用 gifler 库在画布上呈现的动画 GIF。GIF 被解析,并且每一帧都绘制到画布上,然后该画布被用作 Konva.Image 形状的源。