Moving logic to generate SVG and PNG blobs to SVG/Image

This is to avoid reaching into the Image component to access the SVG ref
This commit is contained in:
Jeff Avallone 2018-05-28 12:47:49 -04:00
parent 3916d63f2d
commit d88defcc65
2 changed files with 29 additions and 21 deletions

View File

@ -29,11 +29,10 @@ class App extends React.PureComponent {
window.removeEventListener('hashchange', this.handleHashChange); window.removeEventListener('hashchange', this.handleHashChange);
} }
setSvgUrl(element) { async setSvgUrl() {
try { try {
const type = 'image/svg+xml'; const type = 'image/svg+xml';
const markup = element.outerHTML; const blob = await this.image.current.svgUrl(type);
const blob = new Blob([markup], { type });
this.setState({ this.setState({
svgUrl: { svgUrl: {
@ -49,24 +48,10 @@ class App extends React.PureComponent {
} }
} }
async setPngUrl(element) { async setPngUrl() {
try { try {
const type = 'image/png'; const type = 'image/png';
const markup = element.outerHTML; const blob = await this.image.current.pngUrl(type);
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const loader = new Image();
loader.width = canvas.width = Number(element.getAttribute('width')) * 2;
loader.height = canvas.height = Number(element.getAttribute('height')) * 2;
await new Promise(resolve => {
loader.onload = resolve;
loader.src = 'data:image/svg+xml,' + encodeURIComponent(markup);
});
context.drawImage(loader, 0, 0, loader.width, loader.height);
const blob = await new Promise(resolve => canvas.toBlob(resolve, type));
this.setState({ this.setState({
pngUrl: { pngUrl: {
@ -119,8 +104,8 @@ class App extends React.PureComponent {
expr expr
}, async () => { }, async () => {
await this.image.current.doReflow(); await this.image.current.doReflow();
this.setSvgUrl(this.image.current.svg.current); this.setSvgUrl();
this.setPngUrl(this.image.current.svg.current); this.setPngUrl();
}); });
} }

View File

@ -35,6 +35,29 @@ class Image extends React.PureComponent {
children = [React.createRef()] children = [React.createRef()]
async svgUrl(type) {
const markup = this.svg.current.outerHTML;
return new Blob([markup], { type });
}
async pngUrl(type) {
const markup = this.svg.current.outerHTML;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const loader = new window.Image(); // Using window.Image to avoid name conflict :(
loader.width = canvas.width = Number(this.svg.current.getAttribute('width')) * 2;
loader.height = canvas.height = Number(this.svg.current.getAttribute('height')) * 2;
await new Promise(resolve => {
loader.onload = resolve;
loader.src = 'data:image/svg+xml,' + encodeURIComponent(markup);
});
context.drawImage(loader, 0, 0, loader.width, loader.height);
return new Promise(resolve => canvas.toBlob(resolve, type));
}
reflow() { reflow() {
const { padding } = this.props; const { padding } = this.props;
const box = this.children[0].current.getBBox(); const box = this.children[0].current.getBBox();