diff --git a/src/components/App/index.js b/src/components/App/index.js
index 336bf57..b4a7303 100644
--- a/src/components/App/index.js
+++ b/src/components/App/index.js
@@ -10,54 +10,6 @@ import Message from 'components/Message';
const toUrl = params => new URLSearchParams(params).toString();
-const createSvgLink = async ({ svg }) => {
- try {
- const type = 'image/svg+xml';
- const blob = new Blob([svg], { type });
-
- return {
- url: URL.createObjectURL(blob),
- label: 'Download SVG',
- filename: 'image.svg',
- type
- };
- }
- catch (e) {
- console.error(e); // eslint-disable-line no-console
- }
-};
-
-const createPngLink = async ({ svg, width, height }) => {
- try {
- const type = 'image/png';
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- const loader = new Image();
-
- loader.width = canvas.width = Number(width) * 2;
- loader.height = canvas.height = Number(height) * 2;
-
- await new Promise(resolve => {
- loader.onload = resolve;
- loader.src = 'data:image/svg+xml,' + encodeURIComponent(svg);
- });
-
- context.drawImage(loader, 0, 0, loader.width, loader.height);
-
- const blob = await new Promise(resolve => canvas.toBlob(resolve, type));
-
- return {
- url: URL.createObjectURL(blob),
- label: 'Download PNG',
- filename: 'image.png',
- type
- };
- }
- catch (e) {
- console.error(e); // eslint-disable-line no-console
- }
-};
-
class App extends React.PureComponent {
state = {
loading: false,
@@ -134,15 +86,7 @@ class App extends React.PureComponent {
this.handleRender();
}
- handleSvgMarkup = async ({ svg, width, height }) => {
- if (svg !== this.state.svg) {
- this.setState({
- svg,
- svgLink: await createSvgLink({ svg }),
- pngLink: await createPngLink({ svg, width, height })
- });
- }
- }
+ handleSvg = imageDetails => this.setState({ imageDetails });
render() {
const {
@@ -154,8 +98,7 @@ class App extends React.PureComponent {
loading,
loadingError,
Render,
- svgLink,
- pngLink
+ imageDetails
} = this.state;
const formProps = {
@@ -163,20 +106,19 @@ class App extends React.PureComponent {
syntax,
expr
};
- const actions = {
- permalinkUrl,
- svgLink,
- pngLink
+ const actionProps = {
+ imageDetails,
+ permalinkUrl
};
const renderProps = {
- onRender: this.handleSvgMarkup,
+ onRender: this.handleSvg,
syntax,
expr
};
return <>
{ loading && }
diff --git a/src/components/Form/index.js b/src/components/Form/index.js
index b366275..5a25b6f 100644
--- a/src/components/Form/index.js
+++ b/src/components/Form/index.js
@@ -74,7 +74,7 @@ Form.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
- ]).isRequired
+ ])
};
export default Form;
diff --git a/src/components/FormActions/index.js b/src/components/FormActions/index.js
index 2616188..3495328 100644
--- a/src/components/FormActions/index.js
+++ b/src/components/FormActions/index.js
@@ -6,7 +6,99 @@ import LinkIcon from 'react-feather/dist/icons/link';
import style from './style.module.css';
+const createSvgLink = async ({ svg }) => {
+ try {
+ const type = 'image/svg+xml';
+ const blob = new Blob([svg], { type });
+
+ return {
+ url: URL.createObjectURL(blob),
+ label: 'Download SVG',
+ filename: 'image.svg',
+ type
+ };
+ }
+ catch (e) {
+ console.error(e); // eslint-disable-line no-console
+ }
+};
+
+const createPngLink = async ({ svg, width, height }) => {
+ try {
+ const type = 'image/png';
+ const canvas = document.createElement('canvas');
+ const context = canvas.getContext('2d');
+ const loader = new Image();
+
+ loader.width = canvas.width = width * 2;
+ loader.height = canvas.height = height * 2;
+
+ await new Promise(resolve => {
+ loader.onload = resolve;
+ loader.src = 'data:image/svg+xml,' + encodeURIComponent(svg);
+ });
+
+ context.drawImage(loader, 0, 0, loader.width, loader.height);
+
+ const blob = await new Promise(resolve => canvas.toBlob(resolve, type));
+
+ return {
+ url: URL.createObjectURL(blob),
+ label: 'Download PNG',
+ filename: 'image.png',
+ type
+ };
+ }
+ catch (e) {
+ console.error(e); // eslint-disable-line no-console
+ }
+};
+
class FormActions extends React.PureComponent {
+ state = {}
+
+ componentDidMount() {
+ const { imageDetails } = this.props;
+
+ if (!imageDetails) {
+ return;
+ }
+
+ if (imageDetails.svg) {
+ this.generateDownloadLinks();
+ }
+ }
+
+ componentDidUpdate(prevProps) {
+ const { imageDetails } = this.props;
+ const { imageDetails: prevImageDetails } = prevProps;
+
+ if (!imageDetails) {
+ return;
+ }
+
+ if (!prevImageDetails) {
+ this.generateDownloadLinks();
+ return;
+ }
+
+ if (imageDetails.svg !== prevImageDetails.svg
+ || imageDetails.width !== prevImageDetails.width
+ || imageDetails.height !== prevImageDetails.height) {
+ this.generateDownloadLinks();
+ return;
+ }
+ }
+
+ async generateDownloadLinks() {
+ const { imageDetails: { svg, width, height } } = this.props;
+
+ this.setState({
+ svgLink: await createSvgLink({ svg }),
+ pngLink: await createPngLink({ svg, width, height })
+ });
+ }
+
downloadLink({ url, filename, type, label }) {
return
@@ -17,10 +109,12 @@ class FormActions extends React.PureComponent {
render() {
const {
- permalinkUrl,
+ permalinkUrl
+ } = this.props;
+ const {
svgLink,
pngLink
- } = this.props;
+ } = this.state;
return
{ pngLink && this.downloadLink(pngLink) }
@@ -34,8 +128,11 @@ class FormActions extends React.PureComponent {
FormActions.propTypes = {
permalinkUrl: PropTypes.string,
- svgLink: PropTypes.object,
- pngLink: PropTypes.object
+ imageDetails: PropTypes.shape({
+ svg: PropTypes.string,
+ width: PropTypes.number,
+ height: PropTypes.number
+ })
};
export default FormActions;
diff --git a/src/components/Render/index.js b/src/components/Render/index.js
index 39e5184..d531580 100644
--- a/src/components/Render/index.js
+++ b/src/components/Render/index.js
@@ -16,8 +16,8 @@ class Render extends React.PureComponent {
const svg = this.svgContainer.current.querySelector('svg');
this.props.onRender({
svg: svg.outerHTML,
- width: svg.getAttribute('width'),
- height: svg.getAttribute('height')
+ width: Number(svg.getAttribute('width')),
+ height: Number(svg.getAttribute('height'))
});
}