mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-10 17:33:24 +01:00
Fix safari icons support
This commit is contained in:
parent
85f560324b
commit
6b7a7660f1
@ -36,7 +36,7 @@ import DragManager from './DragManager';
|
||||
import RelationshipPivot from './RelationshipPivot';
|
||||
import Relationship from './Relationship';
|
||||
import SVGExporter from './export/SVGExporter';
|
||||
import PNGExporter from './export/PNGExporter';
|
||||
import BinaryImageExporter from './export/PNGExporter';
|
||||
|
||||
import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher';
|
||||
import TopicFeatureFactory from './TopicFeature';
|
||||
@ -369,7 +369,11 @@ class Designer extends Events {
|
||||
break;
|
||||
}
|
||||
case 'png': {
|
||||
exporter = new PNGExporter(mindmap, svgElement, size.width, size.height);
|
||||
exporter = new BinaryImageExporter(mindmap, svgElement, size.width, size.height, 'image/png');
|
||||
break;
|
||||
}
|
||||
case 'jpeg': {
|
||||
exporter = new BinaryImageExporter(mindmap, svgElement, size.width, size.height, 'image/jpeg');
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -2,16 +2,21 @@
|
||||
import { Mindmap } from "../..";
|
||||
import Exporter from "./Exporter";
|
||||
import SVGExporter from "./SVGExporter";
|
||||
|
||||
class PNGExporter implements Exporter {
|
||||
/**
|
||||
* Based on https://mybyways.com/blog/convert-svg-to-png-using-your-browser
|
||||
*/
|
||||
class BinaryImageExporter implements Exporter {
|
||||
svgElement: Element;
|
||||
mindmap: Mindmap;
|
||||
width: number;
|
||||
height: number;
|
||||
imgFormat: string;
|
||||
|
||||
constructor(mindmap: Mindmap, svgElement: Element, width: number, height: number) {
|
||||
constructor(mindmap: Mindmap, svgElement: Element, width: number, height: number, imgFormat: 'image/png' | 'image/jpeg') {
|
||||
this.svgElement = svgElement;
|
||||
this.mindmap = mindmap;
|
||||
this.imgFormat = imgFormat;
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
@ -19,19 +24,28 @@ class PNGExporter implements Exporter {
|
||||
async export(): Promise<string> {
|
||||
const svgExporter = new SVGExporter(this.mindmap, this.svgElement);
|
||||
const svgUrl = await svgExporter.export();
|
||||
|
||||
|
||||
// Get the device pixel ratio, falling back to 1. But, I will double the resolution to look nicer.
|
||||
const dpr = (window.devicePixelRatio || 1) * 2;
|
||||
|
||||
// Create canvas ...
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.setAttribute('width', this.width.toString());
|
||||
canvas.setAttribute('height', this.height.toString());
|
||||
canvas.setAttribute('width', (this.width * dpr).toString() );
|
||||
canvas.setAttribute('height', (this.height * dpr).toString());
|
||||
|
||||
// Render the image and wait for the response ...
|
||||
const img = new Image();
|
||||
const result = new Promise<string>((resolve, reject) => {
|
||||
|
||||
img.onload = () => {
|
||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
||||
const imgDataUri = canvas.toDataURL('image/png').replace('image/png', 'octet/stream');
|
||||
const ctx = canvas.getContext('2d');
|
||||
// Scale for retina ...
|
||||
ctx.scale(dpr, dpr);
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
const imgDataUri = canvas
|
||||
.toDataURL(this.imgFormat)
|
||||
.replace('image/png', 'octet/stream');
|
||||
URL.revokeObjectURL(imgDataUri);
|
||||
resolve(imgDataUri);
|
||||
}
|
||||
@ -40,4 +54,4 @@ class PNGExporter implements Exporter {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export default PNGExporter;
|
||||
export default BinaryImageExporter;
|
||||
|
@ -11,13 +11,17 @@ class SVGExporter implements Exporter {
|
||||
export(): Promise<string> {
|
||||
// Replace all images for in-line images ...
|
||||
const imagesElements: HTMLCollection = this.svgElement.getElementsByTagName('image');
|
||||
let svgTxt:string = new XMLSerializer().serializeToString(this.svgElement);
|
||||
let svgTxt:string = new XMLSerializer()
|
||||
.serializeToString(this.svgElement);
|
||||
|
||||
// Are namespace declared ?. Otherwise, force the declaration ...
|
||||
if(svgTxt.indexOf('xmlns:xlink=')!==-1){
|
||||
svgTxt.replace('<svg ', '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
|
||||
svgTxt = svgTxt.replace('<svg ', '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
|
||||
}
|
||||
|
||||
// Add white background. This is mainly for PNG export ...
|
||||
svgTxt = svgTxt.replace('<svg ', '<svg style="background-color:white" ');
|
||||
|
||||
const blob = new Blob([svgTxt], { type: 'image/svg+xml' });
|
||||
const result = URL.createObjectURL(blob);
|
||||
return Promise.resolve(result);
|
||||
|
@ -213,20 +213,22 @@ class Menu extends IMenu {
|
||||
|
||||
this._addButton('export', false, false, () => {
|
||||
const formatType = 'png';
|
||||
designer.export(formatType).then((url) => {
|
||||
// Create hidden anchor to force download ...
|
||||
const anchor = document.createElement('a');
|
||||
anchor.style = 'display: none';
|
||||
anchor.download = `${mapId}.${formatType}`;
|
||||
anchor.href = url;
|
||||
document.body.appendChild(anchor);
|
||||
|
||||
// Trigger click ...
|
||||
anchor.click();
|
||||
designer.export(formatType)
|
||||
.then((url) => {
|
||||
// Create hidden anchor to force download ...
|
||||
const anchor = document.createElement('a');
|
||||
anchor.style = 'display: none';
|
||||
anchor.download = `${mapId}.${formatType}`;
|
||||
anchor.href = url;
|
||||
document.body.appendChild(anchor);
|
||||
|
||||
// Clean up ...
|
||||
document.body.removeChild(anchor);
|
||||
});
|
||||
// Trigger click ...
|
||||
anchor.click();
|
||||
|
||||
// Clean up ...
|
||||
document.body.removeChild(anchor);
|
||||
});
|
||||
|
||||
// Create anchor element ...
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
import XMLSerializerFactory from '../../../src/components/persistence/XMLSerializerFactory';
|
||||
import SVGExporter from '../../../src/components/export/SVGExporter';
|
||||
import PNGExporter from '../../../src/components/export/PNGExporter';
|
||||
import BinaryImageExporter from '../../../src/components/export/PNGExporter';
|
||||
|
||||
test('mindplot generation of simple maps', async () => {
|
||||
// Load mindmap DOM ...
|
||||
|
Loading…
Reference in New Issue
Block a user