feat: load background image in promise
This commit is contained in:
parent
b64c3693fe
commit
fe17d88b74
@ -391,116 +391,124 @@ const addExportBackground = (
|
|||||||
normalizedCanvasHeight: number,
|
normalizedCanvasHeight: number,
|
||||||
svgUrl: string,
|
svgUrl: string,
|
||||||
rectangleColor: string,
|
rectangleColor: string,
|
||||||
): void => {
|
): Promise<void> => {
|
||||||
const MARGIN = 24;
|
return new Promise((resolve, reject) => {
|
||||||
const BORDER_RADIUS = 12;
|
const MARGIN = 24;
|
||||||
|
const BORDER_RADIUS = 12;
|
||||||
|
|
||||||
const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
|
const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
|
||||||
|
|
||||||
// Create a new image object
|
// Create a new image object
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
|
|
||||||
// When the image has loaded
|
// When the image has loaded
|
||||||
img.onload = (): void => {
|
img.onload = (): void => {
|
||||||
// Scale image to fill canvas and draw it onto the canvas
|
// Scale image to fill canvas and draw it onto the canvas
|
||||||
ctx.save();
|
|
||||||
ctx.beginPath();
|
|
||||||
if (ctx.roundRect) {
|
|
||||||
ctx.roundRect(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
normalizedCanvasWidth,
|
|
||||||
normalizedCanvasHeight,
|
|
||||||
BORDER_RADIUS,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
roundRect(
|
|
||||||
ctx,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
normalizedCanvasWidth,
|
|
||||||
normalizedCanvasHeight,
|
|
||||||
BORDER_RADIUS,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const scale = Math.max(
|
|
||||||
normalizedCanvasWidth / img.width,
|
|
||||||
normalizedCanvasHeight / img.height,
|
|
||||||
);
|
|
||||||
const x = (normalizedCanvasWidth - img.width * scale) / 2;
|
|
||||||
const y = (normalizedCanvasHeight - img.height * scale) / 2;
|
|
||||||
ctx.clip();
|
|
||||||
ctx.drawImage(img, x, y, img.width * scale, img.height * scale);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
// Create shadow similar to the CSS box-shadow
|
|
||||||
const shadows = [
|
|
||||||
{
|
|
||||||
offsetX: 0,
|
|
||||||
offsetY: 0.7698959708213806,
|
|
||||||
blur: 1.4945039749145508,
|
|
||||||
alpha: 0.02,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offsetX: 0,
|
|
||||||
offsetY: 1.1299999952316284,
|
|
||||||
blur: 4.1321120262146,
|
|
||||||
alpha: 0.04,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offsetX: 0,
|
|
||||||
offsetY: 4.130000114440918,
|
|
||||||
blur: 9.94853401184082,
|
|
||||||
alpha: 0.05,
|
|
||||||
},
|
|
||||||
{ offsetX: 0, offsetY: 13, blur: 33, alpha: 0.07 },
|
|
||||||
];
|
|
||||||
|
|
||||||
shadows.forEach((shadow, index): void => {
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.shadowColor = `rgba(0, 0, 0, ${shadow.alpha})`;
|
|
||||||
ctx.shadowBlur = shadow.blur;
|
|
||||||
ctx.shadowOffsetX = shadow.offsetX;
|
|
||||||
ctx.shadowOffsetY = shadow.offsetY;
|
|
||||||
|
|
||||||
if (ctx.roundRect) {
|
if (ctx.roundRect) {
|
||||||
ctx.roundRect(
|
ctx.roundRect(
|
||||||
MARGIN,
|
0,
|
||||||
MARGIN,
|
0,
|
||||||
normalizedCanvasWidth - MARGIN * 2,
|
normalizedCanvasWidth,
|
||||||
normalizedCanvasHeight - MARGIN * 2,
|
normalizedCanvasHeight,
|
||||||
BORDER_RADIUS,
|
BORDER_RADIUS,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
roundRect(
|
roundRect(
|
||||||
ctx,
|
ctx,
|
||||||
MARGIN,
|
0,
|
||||||
MARGIN,
|
0,
|
||||||
normalizedCanvasWidth - MARGIN * 2,
|
normalizedCanvasWidth,
|
||||||
normalizedCanvasHeight - MARGIN * 2,
|
normalizedCanvasHeight,
|
||||||
BORDER_RADIUS,
|
BORDER_RADIUS,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const scale = Math.max(
|
||||||
if (index === shadows.length - 1) {
|
normalizedCanvasWidth / img.width,
|
||||||
ctx.fillStyle = rectangleColor;
|
normalizedCanvasHeight / img.height,
|
||||||
ctx.fill();
|
);
|
||||||
}
|
const x = (normalizedCanvasWidth - img.width * scale) / 2;
|
||||||
|
const y = (normalizedCanvasHeight - img.height * scale) / 2;
|
||||||
|
ctx.clip();
|
||||||
|
ctx.drawImage(img, x, y, img.width * scale, img.height * scale);
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
});
|
|
||||||
|
|
||||||
// Reset shadow properties for future drawings
|
// Create shadow similar to the CSS box-shadow
|
||||||
ctx.shadowColor = "transparent";
|
const shadows = [
|
||||||
ctx.shadowBlur = 0;
|
{
|
||||||
ctx.shadowOffsetX = 0;
|
offsetX: 0,
|
||||||
ctx.shadowOffsetY = 0;
|
offsetY: 0.7698959708213806,
|
||||||
};
|
blur: 1.4945039749145508,
|
||||||
|
alpha: 0.02,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offsetX: 0,
|
||||||
|
offsetY: 1.1299999952316284,
|
||||||
|
blur: 4.1321120262146,
|
||||||
|
alpha: 0.04,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offsetX: 0,
|
||||||
|
offsetY: 4.130000114440918,
|
||||||
|
blur: 9.94853401184082,
|
||||||
|
alpha: 0.05,
|
||||||
|
},
|
||||||
|
{ offsetX: 0, offsetY: 13, blur: 33, alpha: 0.07 },
|
||||||
|
];
|
||||||
|
|
||||||
// Start loading the image
|
shadows.forEach((shadow, index): void => {
|
||||||
img.src = svgUrl;
|
ctx.save();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.shadowColor = `rgba(0, 0, 0, ${shadow.alpha})`;
|
||||||
|
ctx.shadowBlur = shadow.blur;
|
||||||
|
ctx.shadowOffsetX = shadow.offsetX;
|
||||||
|
ctx.shadowOffsetY = shadow.offsetY;
|
||||||
|
|
||||||
|
if (ctx.roundRect) {
|
||||||
|
ctx.roundRect(
|
||||||
|
MARGIN,
|
||||||
|
MARGIN,
|
||||||
|
normalizedCanvasWidth - MARGIN * 2,
|
||||||
|
normalizedCanvasHeight - MARGIN * 2,
|
||||||
|
BORDER_RADIUS,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
roundRect(
|
||||||
|
ctx,
|
||||||
|
MARGIN,
|
||||||
|
MARGIN,
|
||||||
|
normalizedCanvasWidth - MARGIN * 2,
|
||||||
|
normalizedCanvasHeight - MARGIN * 2,
|
||||||
|
BORDER_RADIUS,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index === shadows.length - 1) {
|
||||||
|
ctx.fillStyle = rectangleColor;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset shadow properties for future drawings
|
||||||
|
ctx.shadowColor = "transparent";
|
||||||
|
ctx.shadowBlur = 0;
|
||||||
|
ctx.shadowOffsetX = 0;
|
||||||
|
ctx.shadowOffsetY = 0;
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
img.onerror = (): void => {
|
||||||
|
reject(new Error(`Failed to load image with URL ${svgUrl}`));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start loading the image
|
||||||
|
img.src = svgUrl;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const _renderScene = ({
|
export const _renderScene = ({
|
||||||
@ -558,13 +566,19 @@ export const _renderScene = ({
|
|||||||
}
|
}
|
||||||
context.save();
|
context.save();
|
||||||
if (isExporting && exportBackgroundImage) {
|
if (isExporting && exportBackgroundImage) {
|
||||||
addExportBackground(
|
(async () => {
|
||||||
canvas,
|
try {
|
||||||
normalizedCanvasWidth,
|
await addExportBackground(
|
||||||
normalizedCanvasHeight,
|
canvas,
|
||||||
exportBackgroundImage,
|
normalizedCanvasWidth,
|
||||||
renderConfig.viewBackgroundColor,
|
normalizedCanvasHeight,
|
||||||
);
|
exportBackgroundImage,
|
||||||
|
renderConfig.viewBackgroundColor!,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to add background:", error);
|
||||||
|
}
|
||||||
|
})();
|
||||||
} else {
|
} else {
|
||||||
context.fillStyle = renderConfig.viewBackgroundColor;
|
context.fillStyle = renderConfig.viewBackgroundColor;
|
||||||
context.fillRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight);
|
context.fillRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user