mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-22 14:47:56 +01:00
Add image export support.
This commit is contained in:
parent
e54d4ff543
commit
d1e52d8f05
@ -47,6 +47,9 @@
|
|||||||
"appbar.tooltip-undo": {
|
"appbar.tooltip-undo": {
|
||||||
"defaultMessage": "Undo"
|
"defaultMessage": "Undo"
|
||||||
},
|
},
|
||||||
|
"editor-panel.icon-title": {
|
||||||
|
"defaultMessage": "Icon"
|
||||||
|
},
|
||||||
"editor-panel.link-panel-title": {
|
"editor-panel.link-panel-title": {
|
||||||
"defaultMessage": "Link"
|
"defaultMessage": "Link"
|
||||||
},
|
},
|
||||||
@ -158,9 +161,6 @@
|
|||||||
"icon-picker.show-images": {
|
"icon-picker.show-images": {
|
||||||
"defaultMessage": "Show images"
|
"defaultMessage": "Show images"
|
||||||
},
|
},
|
||||||
"editor-panel.icon-title": {
|
|
||||||
"defaultMessage": "Icon"
|
|
||||||
},
|
|
||||||
"link.help_text": {
|
"link.help_text": {
|
||||||
"defaultMessage": "Address is not valid"
|
"defaultMessage": "Address is not valid"
|
||||||
},
|
},
|
||||||
@ -195,7 +195,7 @@
|
|||||||
"defaultMessage": "Collpase children"
|
"defaultMessage": "Collpase children"
|
||||||
},
|
},
|
||||||
"shortcut-help-pane.copy-and-text": {
|
"shortcut-help-pane.copy-and-text": {
|
||||||
"defaultMessage": "Copy and paste topics"
|
"defaultMessage": "Copy and paste topics/Copy mindmap image to clipboard."
|
||||||
},
|
},
|
||||||
"shortcut-help-pane.delete-topic": {
|
"shortcut-help-pane.delete-topic": {
|
||||||
"defaultMessage": "Delete topic"
|
"defaultMessage": "Delete topic"
|
||||||
|
@ -133,7 +133,7 @@ const KeyboardShorcutsHelp = (): ReactElement => {
|
|||||||
<td>
|
<td>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="shortcut-help-pane.copy-and-text"
|
id="shortcut-help-pane.copy-and-text"
|
||||||
defaultMessage="Copy and paste topics"
|
defaultMessage="Copy and paste topics/Copy mindmap image to clipboard."
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>Ctrl + C / Ctrl + V</td>
|
<td>Ctrl + C / Ctrl + V</td>
|
||||||
|
@ -57,6 +57,7 @@ import WidgetManager from './WidgetManager';
|
|||||||
import { TopicShapeType } from './model/INodeModel';
|
import { TopicShapeType } from './model/INodeModel';
|
||||||
import { LineType } from './ConnectionLine';
|
import { LineType } from './ConnectionLine';
|
||||||
import XMLSerializerFactory from './persistence/XMLSerializerFactory';
|
import XMLSerializerFactory from './persistence/XMLSerializerFactory';
|
||||||
|
import ImageExpoterFactory from './export/ImageExporterFactory';
|
||||||
|
|
||||||
class Designer extends Events {
|
class Designer extends Events {
|
||||||
private _mindmap: Mindmap | null;
|
private _mindmap: Mindmap | null;
|
||||||
@ -377,7 +378,7 @@ class Designer extends Events {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
copyToClipboard(): void {
|
async copyToClipboard(): Promise<void> {
|
||||||
let topics = this.getModel().filterSelectedTopics();
|
let topics = this.getModel().filterSelectedTopics();
|
||||||
if (topics.length > 0) {
|
if (topics.length > 0) {
|
||||||
const mindmap = new Mindmap();
|
const mindmap = new Mindmap();
|
||||||
@ -391,19 +392,34 @@ class Designer extends Events {
|
|||||||
nodeModel.connectTo(central);
|
nodeModel.connectTo(central);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Serialize to mindmap ...
|
// Create text blob ...
|
||||||
const serializer = XMLSerializerFactory.createFromMindmap(mindmap);
|
const serializer = XMLSerializerFactory.createFromMindmap(mindmap);
|
||||||
const document = serializer.toXML(mindmap);
|
const document = serializer.toXML(mindmap);
|
||||||
const xmmStr: string = new XMLSerializer().serializeToString(document);
|
const xmlStr: string = new XMLSerializer().serializeToString(document);
|
||||||
|
const textPlainBlob = new Blob([xmlStr], { type: 'text/plain' });
|
||||||
|
|
||||||
// Convert to node, only text/html is supported...
|
// Create image blob ...
|
||||||
const type = 'text/plain';
|
const workspace = designer.getWorkSpace();
|
||||||
const blob = new Blob([xmmStr], { type });
|
const svgElement = workspace.getSVGElement();
|
||||||
|
const size = { width: window.innerWidth, height: window.innerHeight };
|
||||||
|
|
||||||
|
const imageUrl = ImageExpoterFactory.create(
|
||||||
|
'png',
|
||||||
|
svgElement,
|
||||||
|
size.width,
|
||||||
|
size.height,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
let imgStr = await imageUrl.exportAndEncode();
|
||||||
|
imgStr = imgStr.replace('octet/stream', 'image/png');
|
||||||
|
const imgBlob = await (await fetch(imgStr)).blob();
|
||||||
|
|
||||||
|
// Finally, add to clipboard ...
|
||||||
const clipboard = new ClipboardItem({
|
const clipboard = new ClipboardItem({
|
||||||
[blob.type]: blob,
|
[textPlainBlob.type]: textPlainBlob,
|
||||||
|
[imgBlob.type]: imgBlob,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Copy to clipboard ...
|
|
||||||
navigator.clipboard.write([clipboard]).then(
|
navigator.clipboard.write([clipboard]).then(
|
||||||
() => console.log('Copy of node success'),
|
() => console.log('Copy of node success'),
|
||||||
(e) => console.error(e),
|
(e) => console.error(e),
|
||||||
|
@ -44,7 +44,7 @@ class BinaryImageExporter extends Exporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export(): Promise<string> {
|
export(): Promise<string> {
|
||||||
throw new Error('Images can not be exporeted');
|
throw new Error('Images can not be exported');
|
||||||
}
|
}
|
||||||
|
|
||||||
exportAndEncode(): Promise<string> {
|
exportAndEncode(): Promise<string> {
|
||||||
|
@ -25,12 +25,10 @@ abstract class Exporter {
|
|||||||
this._contentType = contentType;
|
this._contentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
exportAndEncode(): Promise<string> {
|
async exportAndEncode(): Promise<string> {
|
||||||
const exportValue = this.export();
|
const exportValue = await this.export();
|
||||||
return exportValue.then((value: string) => {
|
const blob = new Blob([exportValue], { type: this._contentType });
|
||||||
const blob = new Blob([value], { type: this._contentType });
|
return URL.createObjectURL(blob);
|
||||||
return URL.createObjectURL(blob);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract export(): Promise<string>;
|
abstract export(): Promise<string>;
|
||||||
|
@ -127,8 +127,10 @@ const ExportDialog = ({
|
|||||||
exporter = TextExporterFactory.create(formatType, mindmap);
|
exporter = TextExporterFactory.create(formatType, mindmap);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default: {
|
||||||
throw new Error('Unsupported encoding');
|
const exhaustiveCheck: never = formatType;
|
||||||
|
throw new Error(`Unhandled color case: ${exhaustiveCheck}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return exporter.exportAndEncode();
|
return exporter.exportAndEncode();
|
||||||
|
Loading…
Reference in New Issue
Block a user