mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-22 14:47:56 +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 RelationshipPivot from './RelationshipPivot';
|
||||||
import Relationship from './Relationship';
|
import Relationship from './Relationship';
|
||||||
import SVGExporter from './export/SVGExporter';
|
import SVGExporter from './export/SVGExporter';
|
||||||
import PNGExporter from './export/PNGExporter';
|
import BinaryImageExporter from './export/PNGExporter';
|
||||||
|
|
||||||
import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher';
|
import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher';
|
||||||
import TopicFeatureFactory from './TopicFeature';
|
import TopicFeatureFactory from './TopicFeature';
|
||||||
@ -369,7 +369,11 @@ class Designer extends Events {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'png': {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -2,16 +2,21 @@
|
|||||||
import { Mindmap } from "../..";
|
import { Mindmap } from "../..";
|
||||||
import Exporter from "./Exporter";
|
import Exporter from "./Exporter";
|
||||||
import SVGExporter from "./SVGExporter";
|
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;
|
svgElement: Element;
|
||||||
mindmap: Mindmap;
|
mindmap: Mindmap;
|
||||||
width: number;
|
width: number;
|
||||||
height: 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.svgElement = svgElement;
|
||||||
this.mindmap = mindmap;
|
this.mindmap = mindmap;
|
||||||
|
this.imgFormat = imgFormat;
|
||||||
|
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
@ -19,19 +24,28 @@ class PNGExporter implements Exporter {
|
|||||||
async export(): Promise<string> {
|
async export(): Promise<string> {
|
||||||
const svgExporter = new SVGExporter(this.mindmap, this.svgElement);
|
const svgExporter = new SVGExporter(this.mindmap, this.svgElement);
|
||||||
const svgUrl = await svgExporter.export();
|
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 ...
|
// Create canvas ...
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.setAttribute('width', this.width.toString());
|
canvas.setAttribute('width', (this.width * dpr).toString() );
|
||||||
canvas.setAttribute('height', this.height.toString());
|
canvas.setAttribute('height', (this.height * dpr).toString());
|
||||||
|
|
||||||
// Render the image and wait for the response ...
|
// Render the image and wait for the response ...
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
const result = new Promise<string>((resolve, reject) => {
|
const result = new Promise<string>((resolve, reject) => {
|
||||||
|
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
const ctx = canvas.getContext('2d');
|
||||||
const imgDataUri = canvas.toDataURL('image/png').replace('image/png', 'octet/stream');
|
// 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);
|
URL.revokeObjectURL(imgDataUri);
|
||||||
resolve(imgDataUri);
|
resolve(imgDataUri);
|
||||||
}
|
}
|
||||||
@ -40,4 +54,4 @@ class PNGExporter implements Exporter {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default PNGExporter;
|
export default BinaryImageExporter;
|
||||||
|
@ -11,13 +11,17 @@ class SVGExporter implements Exporter {
|
|||||||
export(): Promise<string> {
|
export(): Promise<string> {
|
||||||
// Replace all images for in-line images ...
|
// Replace all images for in-line images ...
|
||||||
const imagesElements: HTMLCollection = this.svgElement.getElementsByTagName('image');
|
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 ...
|
// Are namespace declared ?. Otherwise, force the declaration ...
|
||||||
if(svgTxt.indexOf('xmlns:xlink=')!==-1){
|
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 blob = new Blob([svgTxt], { type: 'image/svg+xml' });
|
||||||
const result = URL.createObjectURL(blob);
|
const result = URL.createObjectURL(blob);
|
||||||
return Promise.resolve(result);
|
return Promise.resolve(result);
|
||||||
|
@ -213,20 +213,22 @@ class Menu extends IMenu {
|
|||||||
|
|
||||||
this._addButton('export', false, false, () => {
|
this._addButton('export', false, false, () => {
|
||||||
const formatType = 'png';
|
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 ...
|
designer.export(formatType)
|
||||||
anchor.click();
|
.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 ...
|
// Trigger click ...
|
||||||
document.body.removeChild(anchor);
|
anchor.click();
|
||||||
});
|
|
||||||
|
// Clean up ...
|
||||||
|
document.body.removeChild(anchor);
|
||||||
|
});
|
||||||
|
|
||||||
// Create anchor element ...
|
// Create anchor element ...
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,7 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import XMLSerializerFactory from '../../../src/components/persistence/XMLSerializerFactory';
|
import XMLSerializerFactory from '../../../src/components/persistence/XMLSerializerFactory';
|
||||||
import SVGExporter from '../../../src/components/export/SVGExporter';
|
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 () => {
|
test('mindplot generation of simple maps', async () => {
|
||||||
// Load mindmap DOM ...
|
// Load mindmap DOM ...
|
||||||
|
Loading…
Reference in New Issue
Block a user