excalidraw/src/scene/export.ts
Pete Hunt dcb93f75e6
[RFC] Randomized names next to mouse pointers. (#971)
* [WIP] Add names next to pointers

This implements the rendering and messaging across. Still need to do the UI to set the name.

Also, not really sure what's the best place to send the name and store it.

* Add randomized names

Co-authored-by: Christopher Chedeau <vjeux@fb.com>
2020-03-15 18:56:38 -07:00

119 lines
3.3 KiB
TypeScript

import rough from "roughjs/bin/rough";
import { ExcalidrawElement } from "../element/types";
import { getCommonBounds } from "../element/bounds";
import { renderScene, renderSceneToSvg } from "../renderer/renderScene";
import { distance, SVG_NS } from "../utils";
import { normalizeScroll } from "./scroll";
import { AppState } from "../types";
export function exportToCanvas(
elements: readonly ExcalidrawElement[],
appState: AppState,
{
exportBackground,
exportPadding = 10,
viewBackgroundColor,
scale = 1,
}: {
exportBackground: boolean;
exportPadding?: number;
scale?: number;
viewBackgroundColor: string;
},
createCanvas: (width: number, height: number) => any = function(
width,
height,
) {
const tempCanvas = document.createElement("canvas");
tempCanvas.width = width * scale;
tempCanvas.height = height * scale;
return tempCanvas;
},
) {
// calculate smallest area to fit the contents in
const [minX, minY, maxX, maxY] = getCommonBounds(elements);
const width = distance(minX, maxX) + exportPadding * 2;
const height = distance(minY, maxY) + exportPadding * 2;
const tempCanvas: any = createCanvas(width, height);
renderScene(
elements,
appState,
null,
scale,
rough.canvas(tempCanvas),
tempCanvas,
{
viewBackgroundColor: exportBackground ? viewBackgroundColor : null,
scrollX: normalizeScroll(-minX + exportPadding),
scrollY: normalizeScroll(-minY + exportPadding),
zoom: 1,
remotePointerViewportCoords: {},
remotePointerUsernames: {},
},
{
renderScrollbars: false,
renderSelection: false,
renderOptimizations: false,
},
);
return tempCanvas;
}
export function exportToSvg(
elements: readonly ExcalidrawElement[],
{
exportBackground,
exportPadding = 10,
viewBackgroundColor,
}: {
exportBackground: boolean;
exportPadding?: number;
viewBackgroundColor: string;
},
): SVGSVGElement {
// calculate canvas dimensions
const [minX, minY, maxX, maxY] = getCommonBounds(elements);
const width = distance(minX, maxX) + exportPadding * 2;
const height = distance(minY, maxY) + exportPadding * 2;
// initialze SVG root
const svgRoot = document.createElementNS(SVG_NS, "svg");
svgRoot.setAttribute("version", "1.1");
svgRoot.setAttribute("xmlns", SVG_NS);
svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
svgRoot.innerHTML = `
<defs>
<style>
@font-face {
font-family: "Virgil";
src: url("https://excalidraw.com/FG_Virgil.ttf");
}
@font-face {
font-family: "Cascadia";
src: url("https://excalidraw.com/Cascadia.ttf");
}
</style>
</defs>
`;
// render backgroiund rect
if (exportBackground && viewBackgroundColor) {
const rect = svgRoot.ownerDocument!.createElementNS(SVG_NS, "rect");
rect.setAttribute("x", "0");
rect.setAttribute("y", "0");
rect.setAttribute("width", `${width}`);
rect.setAttribute("height", `${height}`);
rect.setAttribute("fill", viewBackgroundColor);
svgRoot.appendChild(rect);
}
const rsvg = rough.svg(svgRoot);
renderSceneToSvg(elements, rsvg, svgRoot, {
offsetX: -minX + exportPadding,
offsetY: -minY + exportPadding,
});
return svgRoot;
}