使用畫布渲染一組分層的影像,用戶可以在之后下載編譯后的影像。但是,當使用image.onload它時,影像的順序分層,從 CDN 加載最快。
我正在努力實作它們在代碼行進展方面是分層的。有沒有辦法實作這一目標?我嘗試過異步函式,但并沒有真正實作任何目標。以下是我目前的代碼:
import React, { useRef, useEffect } from 'react';
interface CanvasProps {
width: number;
height: number;
base: string;
eyes: string;
hat: string;
backpack: string;
clothes: string;
selected: number;
}
const Canvas = ({ width, height, base, eyes, hat, backpack, clothes, selected }: CanvasProps) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const renderImages = async (context) => {
var bg_image = new Image();
var base_image = new Image();
var eyes_image = new Image();
var hats_image = new Image();
var backpacks_image = new Image();
var clothes_image = new Image();
bg_image.crossOrigin="*";
base_image.crossOrigin="*";
eyes_image.crossOrigin="*";
hats_image.crossOrigin="*";
clothes_image.crossOrigin="*";
backpacks_image.crossOrigin="*";
base_image.src = base;
eyes_image.src = eyes;
hats_image.src = hat;
clothes_image.src = backpack;
backpacks_image.src = clothes;
base_image.onload = function(){ context.drawImage(base_image, 0, 0, 650, 650) }
eyes_image.onload = function(){ context.drawImage(eyes_image, 0, 0, 650, 650) }
hats_image.onload = function(){ context.drawImage(hats_image, 0, 0, 650, 650) }
clothes_image.onload = function(){ context.drawImage(clothes_image, 0, 0, 650, 650) }
backpacks_image.onload = function(){ context.drawImage(backpacks_image, 0, 0, 650, 650) }
}
useEffect(() => {
if (canvasRef.current) {
const canvas = canvasRef.current;
if (canvasRef.current) {
const context = canvas.getContext('2d');
if (context) {
context.clearRect(0, 0, 650, 650);
renderImages(context);
}
}
}
},[selected]);
return <canvas id="canvas" ref={canvasRef} height={height} width={width} />;
};
Canvas.defaultProps = {
width: window.innerWidth,
height: window.innerHeight
};
export default Canvas;
uj5u.com熱心網友回復:
您可以將您的影像創建包裝在影像Promise加載完成后決議并等待每個影像加載完成,以實作您想要的同步流程。
const getImg = (url: string) => {
const img = new Image();
img.crossOrigin="*";
img.src = url;
return new Promise((res, rej) => {
img.onload = () => res(img);
img.onerror = (err) => rej(err);
});
}
const renderImages = async (context) => {
const baseImg = await getImg(base);
context.drawImage(baseImg, 0, 0, 650, 650);
const eyesImg = await getImg(eyes);
context.drawImage(eyesImg, 0, 0, 650, 650);
const hatImg = await getImg(hat);
context.drawImage(hatImg, 0, 0, 650, 650);
const backpackImg = await getImg(backpack);
context.drawImage(backpackImg, 0, 0, 650, 650);
const clothesImg = await getImg(clothes);
context.drawImage(clothesImg, 0, 0, 650, 650);
}
uj5u.com熱心網友回復:
我將使用一個陣列image_sources而不是您正在使用的許多變數
(基礎、眼睛、帽子、背包、衣服),這種方法的好處是:
- 這將顯著減少渲染函式代碼的大小。
- 我們可以遞回呼叫
renderImages順序繪制所有影像。 - 您的代碼已準備好處理用戶需要的盡可能多的影像層。
這是我的粗略原型:
const renderImages = (context, index) => {
if (index < image_sources.length) {
let image = new Image();
image.crossOrigin = "*";
image.src = image_sources[index];
image.onload = function() {
context.drawImage(image, 0, 0, 650, 650)
renderImages(context, index 1)
}
}
}
useEffect(() => {
if (canvasRef.current) {
const canvas = canvasRef.current;
if (canvasRef.current) {
const context = canvas.getContext('2d');
if (context) {
context.clearRect(0, 0, 650, 650);
renderImages(context, 0);
}
}
}
}, [selected]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/352879.html
標籤:javascript 反应 打字稿 异步 帆布
