feat: dark theme export background

This commit is contained in:
Arnošt Pleskot 2023-08-13 20:00:17 +02:00
parent baa133cbb7
commit 787f5d68cf
No known key found for this signature in database
11 changed files with 172 additions and 75 deletions

View file

@ -3,9 +3,10 @@ import { NonDeletedExcalidrawElement } from "../element/types";
import { getCommonBounds, getElementAbsoluteCoords } from "../element/bounds";
import { renderSceneToSvg, renderStaticScene } from "../renderer/renderScene";
import { distance, isOnlyExportingSingleFrame } from "../utils";
import { AppState, BinaryFiles, DataURL } from "../types";
import { AppState, BinaryFiles } from "../types";
import {
DEFAULT_EXPORT_PADDING,
FANCY_BACKGROUND_IMAGES,
FANCY_BG_BORDER_RADIUS,
FANCY_BG_PADDING,
SVG_NS,
@ -51,7 +52,8 @@ export const exportToCanvas = async (
) => {
const exportWithFancyBackground =
exportBackground &&
!!appState.fancyBackgroundImageUrl &&
appState.fancyBackgroundImageKey &&
appState.fancyBackgroundImageKey !== "solid" &&
elements.length > 0;
const padding = !exportWithFancyBackground
? exportPadding
@ -75,7 +77,7 @@ export const exportToCanvas = async (
const renderConfig = {
viewBackgroundColor:
exportBackground && !appState.fancyBackgroundImageUrl
exportBackground && !exportWithFancyBackground
? viewBackgroundColor
: null,
scrollX: -minX + (onlyExportingSingleFrame ? 0 : padding),
@ -92,15 +94,19 @@ export const exportToCanvas = async (
renderSelection: false,
renderGrid: false,
isExporting: true,
exportBackgroundImage: appState.fancyBackgroundImageUrl,
exportBackgroundImage: appState.fancyBackgroundImageKey,
};
if (exportWithFancyBackground) {
if (
exportWithFancyBackground &&
appState.fancyBackgroundImageKey !== "solid"
) {
await applyFancyBackgroundOnCanvas({
canvas,
fancyBackgroundImageUrl: appState.fancyBackgroundImageUrl!,
fancyBackgroundImageKey: appState.fancyBackgroundImageKey,
backgroundColor: viewBackgroundColor,
exportScale: appState.exportScale,
theme: renderConfig.theme,
});
}
@ -139,7 +145,7 @@ export const exportToSvg = async (
exportWithDarkMode?: boolean;
exportEmbedScene?: boolean;
renderFrame?: boolean;
fancyBackgroundImageUrl: DataURL | null;
fancyBackgroundImageKey?: keyof typeof FANCY_BACKGROUND_IMAGES;
},
files: BinaryFiles | null,
opts?: {
@ -157,8 +163,9 @@ export const exportToSvg = async (
const exportWithFancyBackground =
exportBackground &&
!!appState.fancyBackgroundImageUrl &&
elements.length > 0;
elements.length > 0 &&
appState.fancyBackgroundImageKey &&
appState.fancyBackgroundImageKey !== "solid";
const padding = !exportWithFancyBackground
? exportPadding
@ -191,7 +198,8 @@ export const exportToSvg = async (
svgRoot.setAttribute("filter", THEME_FILTER);
}
let assetPath = "https://excalidraw.com/";
// let assetPath = "https://excalidraw.com/";
let assetPath = "http://localhost:3000/";
// Asset path needs to be determined only when using package
if (import.meta.env.VITE_IS_EXCALIDRAW_NPM_PACKAGE) {
assetPath =
@ -258,14 +266,17 @@ export const exportToSvg = async (
// render background rect
if (appState.exportBackground && viewBackgroundColor) {
if (appState.fancyBackgroundImageUrl) {
if (
appState.fancyBackgroundImageKey &&
appState.fancyBackgroundImageKey !== "solid"
) {
await applyFancyBackgroundOnSvg({
svgRoot,
fancyBackgroundImageUrl:
`${appState.fancyBackgroundImageUrl}` as DataURL,
fancyBackgroundImageKey: `${appState.fancyBackgroundImageKey}`,
backgroundColor: viewBackgroundColor,
dimensions: { w: width, h: height },
exportScale,
theme: appState.exportWithDarkMode ? THEME.DARK : THEME.LIGHT,
});
} else {
const rect = svgRoot.ownerDocument!.createElementNS(SVG_NS, "rect");

View file

@ -1,7 +1,15 @@
import { FANCY_BG_BORDER_RADIUS, FANCY_BG_PADDING, SVG_NS } from "../constants";
import {
FANCY_BACKGROUND_IMAGES,
FANCY_BG_BORDER_RADIUS,
FANCY_BG_PADDING,
IMAGE_INVERT_FILTER,
SVG_NS,
THEME,
THEME_FILTER,
} from "../constants";
import { loadHTMLImageElement, loadSVGElement } from "../element/image";
import { roundRect } from "../renderer/roundRect";
import { AppState, DataURL } from "../types";
import { AppState } from "../types";
type Dimensions = { w: number; h: number };
@ -62,6 +70,7 @@ const addContentBackground = (
normalizedDimensions: Dimensions,
contentBackgroundColor: string,
exportScale: AppState["exportScale"],
theme: AppState["theme"],
) => {
const shadows = [
{
@ -113,6 +122,9 @@ const addContentBackground = (
}
if (index === shadows.length - 1) {
if (theme === THEME.DARK) {
context.filter = THEME_FILTER;
}
context.fillStyle = contentBackgroundColor;
context.fill();
}
@ -123,17 +135,25 @@ const addContentBackground = (
export const applyFancyBackgroundOnCanvas = async ({
canvas,
fancyBackgroundImageUrl,
fancyBackgroundImageKey,
backgroundColor,
exportScale,
theme,
}: {
canvas: HTMLCanvasElement;
fancyBackgroundImageUrl: DataURL;
fancyBackgroundImageKey: Exclude<
keyof typeof FANCY_BACKGROUND_IMAGES,
"solid"
>;
backgroundColor: string;
exportScale: AppState["exportScale"];
theme: AppState["theme"];
}) => {
const context = canvas.getContext("2d")!;
const fancyBackgroundImageUrl =
FANCY_BACKGROUND_IMAGES[fancyBackgroundImageKey][theme];
const fancyBackgroundImage = await loadHTMLImageElement(
fancyBackgroundImageUrl,
);
@ -142,31 +162,45 @@ export const applyFancyBackgroundOnCanvas = async ({
addImageBackground(context, canvasDimensions, fancyBackgroundImage);
addContentBackground(context, canvasDimensions, backgroundColor, exportScale);
addContentBackground(
context,
canvasDimensions,
backgroundColor,
exportScale,
theme,
);
};
export const applyFancyBackgroundOnSvg = async ({
svgRoot,
fancyBackgroundImageUrl,
fancyBackgroundImageKey,
backgroundColor,
dimensions,
exportScale,
theme,
}: {
svgRoot: SVGSVGElement;
fancyBackgroundImageUrl: DataURL;
fancyBackgroundImageKey: Exclude<
keyof typeof FANCY_BACKGROUND_IMAGES,
"solid"
>;
backgroundColor: string;
dimensions: Dimensions;
exportScale: AppState["exportScale"];
theme: AppState["theme"];
}) => {
const fancyBackgroundImage = await loadSVGElement(
`${fancyBackgroundImageUrl}`,
);
const fancyBackgroundImageUrl =
FANCY_BACKGROUND_IMAGES[fancyBackgroundImageKey][theme];
const fancyBackgroundImage = await loadSVGElement(fancyBackgroundImageUrl);
fancyBackgroundImage.setAttribute("x", "0");
fancyBackgroundImage.setAttribute("y", "0");
fancyBackgroundImage.setAttribute("width", `${dimensions.w}`);
fancyBackgroundImage.setAttribute("height", `${dimensions.h}`);
fancyBackgroundImage.setAttribute("preserveAspectRatio", "none");
if (theme === THEME.DARK) {
fancyBackgroundImage.setAttribute("filter", IMAGE_INVERT_FILTER);
}
svgRoot.appendChild(fancyBackgroundImage);