Factor out auto-sizing-svg.tsx.
rodzic
3e1b66a984
commit
327f99fdae
|
@ -0,0 +1,50 @@
|
|||
import React, { useEffect, useRef, useState } from "react";
|
||||
|
||||
/**
|
||||
* An SVG element with an optional background color that
|
||||
* automatically sizes itself to its contents.
|
||||
*/
|
||||
export const AutoSizingSvg = React.forwardRef(
|
||||
(
|
||||
props: {
|
||||
padding: number;
|
||||
bgColor?: string;
|
||||
children: JSX.Element | JSX.Element[];
|
||||
},
|
||||
ref: React.ForwardedRef<SVGSVGElement>
|
||||
) => {
|
||||
const { bgColor, padding } = props;
|
||||
const [x, setX] = useState(0);
|
||||
const [y, setY] = useState(0);
|
||||
const [width, setWidth] = useState(1);
|
||||
const [height, setHeight] = useState(1);
|
||||
const gRef = useRef<SVGGElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const svgEl = gRef.current;
|
||||
if (svgEl) {
|
||||
const bbox = svgEl.getBBox();
|
||||
setX(bbox.x - padding);
|
||||
setY(bbox.y - padding);
|
||||
setWidth(bbox.width + padding * 2);
|
||||
setHeight(bbox.height + padding * 2);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={`${width}px`}
|
||||
height={`${height}px`}
|
||||
viewBox={`${x} ${y} ${width} ${height}`}
|
||||
ref={ref}
|
||||
>
|
||||
{bgColor && (
|
||||
<rect x={x} y={y} width={width} height={height} fill={bgColor} />
|
||||
)}
|
||||
<g ref={gRef}>{props.children}</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
);
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||
import React, { useContext, useRef, useState } from "react";
|
||||
import { SvgVocabulary } from "../svg-vocabulary";
|
||||
import {
|
||||
createSvgSymbolContext,
|
||||
|
@ -18,6 +18,7 @@ import { Random } from "../random";
|
|||
import { SymbolContextWidget } from "../symbol-context-widget";
|
||||
import { range } from "../util";
|
||||
import { getBoundingBoxCenter, uniformlyScaleToFit } from "../bounding-box";
|
||||
import { AutoSizingSvg } from "../auto-sizing-svg";
|
||||
|
||||
const DEFAULT_BG_COLOR = "#858585";
|
||||
|
||||
|
@ -439,51 +440,6 @@ function exportSvg(filename: string, svgRef: React.RefObject<SVGSVGElement>) {
|
|||
document.body.removeChild(anchor);
|
||||
}
|
||||
|
||||
const AutoSizingSvg = React.forwardRef(
|
||||
(
|
||||
props: {
|
||||
padding: number;
|
||||
bgColor?: string;
|
||||
children: JSX.Element | JSX.Element[];
|
||||
},
|
||||
ref: React.ForwardedRef<SVGSVGElement>
|
||||
) => {
|
||||
const { bgColor, padding } = props;
|
||||
const [x, setX] = useState(0);
|
||||
const [y, setY] = useState(0);
|
||||
const [width, setWidth] = useState(1);
|
||||
const [height, setHeight] = useState(1);
|
||||
const gRef = useRef<SVGGElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const svgEl = gRef.current;
|
||||
if (svgEl) {
|
||||
const bbox = svgEl.getBBox();
|
||||
setX(bbox.x - padding);
|
||||
setY(bbox.y - padding);
|
||||
setWidth(bbox.width + padding * 2);
|
||||
setHeight(bbox.height + padding * 2);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={`${width}px`}
|
||||
height={`${height}px`}
|
||||
viewBox={`${x} ${y} ${width} ${height}`}
|
||||
ref={ref}
|
||||
>
|
||||
{bgColor && (
|
||||
<rect x={x} y={y} width={width} height={height} fill={bgColor} />
|
||||
)}
|
||||
<g ref={gRef}>{props.children}</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
function getDownloadFilename(randomSeed: number | null) {
|
||||
let downloadBasename = "mystic-symbolic-creature";
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue