feat: update renderConfig to move and scale content

This commit is contained in:
Arnošt Pleskot 2023-08-10 21:19:19 +02:00
parent 31a1047c5c
commit bc5313b165
No known key found for this signature in database
2 changed files with 114 additions and 53 deletions

View File

@ -4,7 +4,12 @@ import { getCommonBounds, getElementAbsoluteCoords } from "../element/bounds";
import { renderScene, renderSceneToSvg } from "../renderer/renderScene"; import { renderScene, renderSceneToSvg } from "../renderer/renderScene";
import { distance, isOnlyExportingSingleFrame } from "../utils"; import { distance, isOnlyExportingSingleFrame } from "../utils";
import { AppState, BinaryFiles } from "../types"; import { AppState, BinaryFiles } from "../types";
import { DEFAULT_EXPORT_PADDING, SVG_NS, THEME_FILTER } from "../constants"; import {
DEFAULT_EXPORT_PADDING,
SVG_NS,
THEME,
THEME_FILTER,
} from "../constants";
import { getDefaultAppState } from "../appState"; import { getDefaultAppState } from "../appState";
import { serializeAsJSON } from "../data/json"; import { serializeAsJSON } from "../data/json";
import { import {
@ -13,6 +18,7 @@ import {
} from "../element/image"; } from "../element/image";
import Scene from "./Scene"; import Scene from "./Scene";
import { applyFancyBackground } from "./fancyBackground"; import { applyFancyBackground } from "./fancyBackground";
import { RenderConfig } from "./types";
export const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`; export const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;
@ -41,7 +47,7 @@ export const exportToCanvas = async (
) => { ) => {
const [minX, minY, width, height] = getCanvasSize(elements, exportPadding); const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);
const { canvas, scale = 1 } = createCanvas(width, height); let { canvas, scale = 1 } = createCanvas(width, height);
const defaultAppState = getDefaultAppState(); const defaultAppState = getDefaultAppState();
@ -55,21 +61,7 @@ export const exportToCanvas = async (
const onlyExportingSingleFrame = isOnlyExportingSingleFrame(elements); const onlyExportingSingleFrame = isOnlyExportingSingleFrame(elements);
if (appState.fancyBackgroundImageUrl) { let renderConfig: RenderConfig = {
await applyFancyBackground(
canvas,
appState.fancyBackgroundImageUrl,
viewBackgroundColor,
);
}
renderScene({
elements,
appState,
scale,
rc: rough.canvas(canvas),
canvas,
renderConfig: {
viewBackgroundColor: viewBackgroundColor:
exportBackground && !appState.fancyBackgroundImageUrl exportBackground && !appState.fancyBackgroundImageUrl
? viewBackgroundColor ? viewBackgroundColor
@ -82,14 +74,36 @@ export const exportToCanvas = async (
shouldCacheIgnoreZoom: false, shouldCacheIgnoreZoom: false,
remotePointerUsernames: {}, remotePointerUsernames: {},
remotePointerUserStates: {}, remotePointerUserStates: {},
theme: appState.exportWithDarkMode ? "dark" : "light", theme: appState.exportWithDarkMode ? THEME.DARK : THEME.LIGHT,
imageCache, imageCache,
renderScrollbars: false, renderScrollbars: false,
renderSelection: false, renderSelection: false,
renderGrid: false, renderGrid: false,
isExporting: true, isExporting: true,
exportBackgroundImage: appState.fancyBackgroundImageUrl, exportBackgroundImage: appState.fancyBackgroundImageUrl,
}, };
if (appState.fancyBackgroundImageUrl) {
const updatedRenderProps = await applyFancyBackground({
canvas,
fancyBackgroundImageUrl: appState.fancyBackgroundImageUrl,
backgroundColor: viewBackgroundColor,
scale,
renderConfig,
});
console.log(scale, updatedRenderProps.scale);
renderConfig = updatedRenderProps.renderConfig;
scale = updatedRenderProps.scale;
}
renderScene({
elements,
appState,
scale,
rc: rough.canvas(canvas),
canvas,
renderConfig,
}); });
return canvas; return canvas;

View File

@ -1,7 +1,12 @@
import { FANCY_BG_BORDER_RADIUS, FANCY_BG_PADDING } from "../constants"; import {
DEFAULT_EXPORT_PADDING,
FANCY_BG_BORDER_RADIUS,
FANCY_BG_PADDING,
} from "../constants";
import { loadHTMLImageElement } from "../element/image"; import { loadHTMLImageElement } from "../element/image";
import { roundRect } from "../renderer/roundRect"; import { roundRect } from "../renderer/roundRect";
import { DataURL } from "../types"; import { DataURL } from "../types";
import { RenderConfig } from "./types";
type Dimensions = { w: number; h: number }; type Dimensions = { w: number; h: number };
@ -25,23 +30,35 @@ const getScaleToFit = (contentSize: Dimensions, containerSize: Dimensions) => {
const addImageBackground = ( const addImageBackground = (
context: CanvasRenderingContext2D, context: CanvasRenderingContext2D,
canvasWidth: number, canvasDimensions: Dimensions,
canvasHeight: number,
fancyBackgroundImage: HTMLImageElement, fancyBackgroundImage: HTMLImageElement,
) => { ) => {
context.save(); context.save();
context.beginPath(); context.beginPath();
if (context.roundRect) { if (context.roundRect) {
context.roundRect(0, 0, canvasWidth, canvasHeight, FANCY_BG_BORDER_RADIUS); context.roundRect(
0,
0,
canvasDimensions.w,
canvasDimensions.h,
FANCY_BG_BORDER_RADIUS,
);
} else { } else {
roundRect(context, 0, 0, canvasWidth, canvasHeight, FANCY_BG_BORDER_RADIUS); roundRect(
context,
0,
0,
canvasDimensions.w,
canvasDimensions.h,
FANCY_BG_BORDER_RADIUS,
);
} }
const scale = getScaleToFill( const scale = getScaleToFill(
{ w: fancyBackgroundImage.width, h: fancyBackgroundImage.height }, { w: fancyBackgroundImage.width, h: fancyBackgroundImage.height },
{ w: canvasWidth, h: canvasHeight }, { w: canvasDimensions.w, h: canvasDimensions.h },
); );
const x = (canvasWidth - fancyBackgroundImage.width * scale) / 2; const x = (canvasDimensions.w - fancyBackgroundImage.width * scale) / 2;
const y = (canvasHeight - fancyBackgroundImage.height * scale) / 2; const y = (canvasDimensions.h - fancyBackgroundImage.height * scale) / 2;
context.clip(); context.clip();
context.drawImage( context.drawImage(
fancyBackgroundImage, fancyBackgroundImage,
@ -56,8 +73,7 @@ const addImageBackground = (
const addContentBackground = ( const addContentBackground = (
context: CanvasRenderingContext2D, context: CanvasRenderingContext2D,
canvasWidth: number, normalizedDimensions: Dimensions,
canvasHeight: number,
contentBackgroundColor: string, contentBackgroundColor: string,
) => { ) => {
const shadows = [ const shadows = [
@ -94,8 +110,8 @@ const addContentBackground = (
context.roundRect( context.roundRect(
FANCY_BG_PADDING, FANCY_BG_PADDING,
FANCY_BG_PADDING, FANCY_BG_PADDING,
canvasWidth - FANCY_BG_PADDING * 2, normalizedDimensions.w - FANCY_BG_PADDING * 2,
canvasHeight - FANCY_BG_PADDING * 2, normalizedDimensions.h - FANCY_BG_PADDING * 2,
FANCY_BG_BORDER_RADIUS, FANCY_BG_BORDER_RADIUS,
); );
} else { } else {
@ -103,8 +119,8 @@ const addContentBackground = (
context, context,
FANCY_BG_PADDING, FANCY_BG_PADDING,
FANCY_BG_PADDING, FANCY_BG_PADDING,
canvasWidth - FANCY_BG_PADDING * 2, normalizedDimensions.w - FANCY_BG_PADDING * 2,
canvasHeight - FANCY_BG_PADDING * 2, normalizedDimensions.h - FANCY_BG_PADDING * 2,
FANCY_BG_BORDER_RADIUS, FANCY_BG_BORDER_RADIUS,
); );
} }
@ -118,23 +134,54 @@ const addContentBackground = (
}); });
}; };
export const applyFancyBackground = async ( const updateRenderConfig = (
canvas: HTMLCanvasElement, renderConfig: RenderConfig,
fancyBackgroundImageUrl: DataURL, canvasDimensions: Dimensions,
backgroundColor: string, ): { scale: number; renderConfig: RenderConfig } => {
) => { const totalPadding =
FANCY_BG_PADDING + FANCY_BG_BORDER_RADIUS + DEFAULT_EXPORT_PADDING;
return {
renderConfig: {
...renderConfig,
scrollX: renderConfig.scrollX + totalPadding,
scrollY: renderConfig.scrollY + totalPadding,
},
scale: getScaleToFit(canvasDimensions, {
w: canvasDimensions.w - totalPadding * 2,
h: canvasDimensions.h - totalPadding * 2,
}),
};
};
export const applyFancyBackground = async ({
canvas,
fancyBackgroundImageUrl,
backgroundColor,
renderConfig,
}: {
canvas: HTMLCanvasElement;
fancyBackgroundImageUrl: DataURL;
backgroundColor: string;
scale: number;
renderConfig: RenderConfig;
}) => {
const context = canvas.getContext("2d")!; const context = canvas.getContext("2d")!;
const fancyBackgroundImage = await loadHTMLImageElement( const fancyBackgroundImage = await loadHTMLImageElement(
fancyBackgroundImageUrl, fancyBackgroundImageUrl,
); );
addImageBackground( const canvasDimensions: Dimensions = { w: canvas.width, h: canvas.height };
context,
canvas.width,
canvas.height,
fancyBackgroundImage,
);
addContentBackground(context, canvas.width, canvas.height, backgroundColor); // const normalizedDimensions: Dimensions = {
// w: canvas.width / scale,
// h: canvas.height / scale,
// };
addImageBackground(context, canvasDimensions, fancyBackgroundImage);
addContentBackground(context, canvasDimensions, backgroundColor);
return updateRenderConfig(renderConfig, canvasDimensions);
}; };