Moving link generation into FormActions
This commit is contained in:
parent
f41518bd92
commit
42a1788c52
@ -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 <>
|
||||
<Form { ...formProps }>
|
||||
<FormActions { ...actions } />
|
||||
{ Render && <FormActions { ...actionProps } /> }
|
||||
</Form>
|
||||
|
||||
{ loading && <Loader /> }
|
||||
|
@ -74,7 +74,7 @@ Form.propTypes = {
|
||||
children: PropTypes.oneOfType([
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node
|
||||
]).isRequired
|
||||
])
|
||||
};
|
||||
|
||||
export default Form;
|
||||
|
@ -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 <li>
|
||||
<a href={ url } download={ filename } type={ type }>
|
||||
@ -17,10 +109,12 @@ class FormActions extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
permalinkUrl,
|
||||
permalinkUrl
|
||||
} = this.props;
|
||||
const {
|
||||
svgLink,
|
||||
pngLink
|
||||
} = this.props;
|
||||
} = this.state;
|
||||
|
||||
return <ul className={ style.actions }>
|
||||
{ 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;
|
||||
|
@ -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'))
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user