From 8805f315ae52e14766e34f0792f763362cca67d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arno=C5=A1t=20Pleskot?= Date: Fri, 28 Jul 2023 11:23:46 +0200 Subject: [PATCH] feat: render svg background on export --- public/backgrounds/01.svg | 25 ++++++++ public/backgrounds/02.svg | 20 +++++++ public/backgrounds/03.svg | 22 +++++++ public/backgrounds/04.svg | 32 +++++++++++ public/backgrounds/05.svg | 18 ++++++ src/renderer/renderScene.ts | 111 +++++++++++++++++++++++++++++++++++- 6 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 public/backgrounds/01.svg create mode 100644 public/backgrounds/02.svg create mode 100644 public/backgrounds/03.svg create mode 100644 public/backgrounds/04.svg create mode 100644 public/backgrounds/05.svg diff --git a/public/backgrounds/01.svg b/public/backgrounds/01.svg new file mode 100644 index 000000000..e2d88f75c --- /dev/null +++ b/public/backgrounds/01.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/backgrounds/02.svg b/public/backgrounds/02.svg new file mode 100644 index 000000000..091fc1ec8 --- /dev/null +++ b/public/backgrounds/02.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/public/backgrounds/03.svg b/public/backgrounds/03.svg new file mode 100644 index 000000000..19210b288 --- /dev/null +++ b/public/backgrounds/03.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/backgrounds/04.svg b/public/backgrounds/04.svg new file mode 100644 index 000000000..6c9c14467 --- /dev/null +++ b/public/backgrounds/04.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/backgrounds/05.svg b/public/backgrounds/05.svg new file mode 100644 index 000000000..38d7eea66 --- /dev/null +++ b/public/backgrounds/05.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/renderer/renderScene.ts b/src/renderer/renderScene.ts index f8fa79ed7..253613285 100644 --- a/src/renderer/renderScene.ts +++ b/src/renderer/renderScene.ts @@ -385,6 +385,100 @@ const frameClip = ( ); }; +const addExportBackground = ( + canvas: HTMLCanvasElement, + normalizedCanvasWidth: number, + normalizedCanvasHeight: number, + svgUrl: string, + rectangleColor: string, +): void => { + const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; + + // Create a new image object + const img = new Image(); + + // When the image has loaded + img.onload = (): void => { + // Draw the image onto the canvas + ctx.drawImage(img, 0, 0, normalizedCanvasWidth, canvas.height); + + // 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 => { + const MARGIN = 24; + const BORDER_RADIUS = 12; + + ctx.shadowColor = `rgba(0, 0, 0, ${shadow.alpha})`; + ctx.shadowBlur = shadow.blur; + ctx.shadowOffsetX = shadow.offsetX; + ctx.shadowOffsetY = shadow.offsetY; + + // Define path for rectangle + ctx.beginPath(); + ctx.moveTo(MARGIN, MARGIN); + ctx.lineTo(normalizedCanvasWidth - MARGIN, MARGIN); + ctx.quadraticCurveTo( + normalizedCanvasWidth, + MARGIN, + normalizedCanvasWidth, + MARGIN + BORDER_RADIUS, + ); + ctx.lineTo(normalizedCanvasWidth, normalizedCanvasHeight - MARGIN); + ctx.quadraticCurveTo( + normalizedCanvasWidth, + normalizedCanvasHeight, + normalizedCanvasWidth - MARGIN, + normalizedCanvasHeight, + ); + ctx.lineTo(MARGIN, normalizedCanvasHeight); + ctx.quadraticCurveTo( + 0, + normalizedCanvasHeight, + 0, + normalizedCanvasHeight - MARGIN, + ); + ctx.lineTo(0, MARGIN + BORDER_RADIUS); + ctx.quadraticCurveTo(0, MARGIN, MARGIN, MARGIN); + ctx.closePath(); + + if (index === shadows.length - 1) { + ctx.fillStyle = rectangleColor; + ctx.fill(); + } + }); + + // Reset shadow properties for future drawings + ctx.shadowColor = "transparent"; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + }; + + // Start loading the image + img.src = svgUrl; +}; + export const _renderScene = ({ elements, appState, @@ -438,8 +532,20 @@ export const _renderScene = ({ context.clearRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight); } context.save(); - context.fillStyle = renderConfig.viewBackgroundColor; - context.fillRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight); + if (isExporting) { + context.save(); + addExportBackground( + canvas, + normalizedCanvasWidth, + normalizedCanvasHeight, + "/backgrounds/01.svg", + "#fff", + ); + } else { + context.fillStyle = renderConfig.viewBackgroundColor; + context.fillRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight); + } + context.restore(); } else { context.clearRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight); @@ -994,6 +1100,7 @@ export const _renderScene = ({ } context.restore(); + return { atLeastOneVisibleElement: visibleElements.length > 0, scrollBars }; };