diff --git a/README.md b/README.md
index 142911d..c4c6cf7 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Pseudo-vector image creator.
## [Launch Application](https://malulleybovo.github.io/SymbolArtEditorOnline/)
- #### Version 2.2.0
+ #### Version 2.3.0
### Quickly get down to business and make art with fluidity and agility.
Symbol Art Editor was designed based on three pillars: simplicity, ease of use, and agility.
diff --git a/res/templates/optionsview.html b/res/templates/optionsview.html
index d6dd170..73f0a3e 100644
--- a/res/templates/optionsview.html
+++ b/res/templates/optionsview.html
@@ -1,6 +1,6 @@
-
v2.2.0
© 2021 Copyright malulleybovo
+
v2.3.0
© 2021 Copyright malulleybovo
@@ -26,6 +26,12 @@
Options
USED TO SAVE THIS PROJECT
+
+
S.A. SCREENSHOT
+
EXPORT
+
+
S.A. IN PNG FORMAT
+
S.A. COMPONENT
INCLUDE
diff --git a/src/UIApplication.js b/src/UIApplication.js
index b8cfd8a..d20e24d 100644
--- a/src/UIApplication.js
+++ b/src/UIApplication.js
@@ -312,4 +312,11 @@ class UIApplication {
document.body.appendChild(this._renderer.domElement);
}
+ async imageBlob() {
+ let pngData = await this._renderer.pngData();
+ let stream = await fetch(pngData);
+ let blob = await stream.blob();
+ return blob;
+ }
+
}
diff --git a/src/view/UIOptionsView.js b/src/view/UIOptionsView.js
index 3442b19..6b2b115 100644
--- a/src/view/UIOptionsView.js
+++ b/src/view/UIOptionsView.js
@@ -125,6 +125,18 @@ class UIOptionsView extends UIView {
});
})();
+ _pngExportButton = (() => {
+ this.didLoad(_ => {
+ this._pngExportButton = this.view.find('#pngexportbutton');
+ this.updateState();
+ this._pngExportButton.gestureRecognizer = new UITapGestureRecognizer({
+ targetHtmlElement: this._pngExportButton[0], onTap: () => {
+ this._requestToExportAsPng();
+ }
+ });
+ });
+ })();
+
_importAsComponentButton = (() => {
this.didLoad(_ => {
this._importAsComponentButton = this.view.find('#importascomponentbutton');
@@ -326,4 +338,14 @@ class UIOptionsView extends UIView {
link[0].click();
}
+ _requestToExportAsPng() {
+ UIApplication.shared.imageBlob().then(blob => {
+ let fileUrl = URL.createObjectURL(blob);
+ let link = $('
');
+ link[0].href = fileUrl;
+ link[0].download = 'symbolArtPreview.png';
+ link[0].click();
+ });
+ }
+
}
diff --git a/src/view/renderer/Renderer.js b/src/view/renderer/Renderer.js
index 31d9947..d9c1fdf 100644
--- a/src/view/renderer/Renderer.js
+++ b/src/view/renderer/Renderer.js
@@ -813,4 +813,44 @@ class Renderer {
}
}
+ async pngData() {
+ return new Promise((resolve, reject) => {
+ this._previewSymbolArtDelimiter.outlineMaterial.visible = false;
+ try {
+ let width = SymbolArt.viewableDimensions.width;
+ let height = SymbolArt.viewableDimensions.height;
+ if (width > height && width > window.innerWidth) {
+ height = height * window.innerWidth / width;
+ width = window.innerWidth;
+ } else if (width < height && height > window.innerHeight) {
+ width = width * window.innerHeight / height;
+ height = window.innerHeight;
+ }
+ this._engine.clear();
+ this._engine.setViewport(0, window.innerHeight - height, width, height);
+ this._engine.setScissor(0, window.innerHeight - height, width, height);
+ this._engine.render(this._scene, this._previewCamera);
+ let snapshot = this._engine.domElement.toDataURL();
+ let previewImage = new Image();
+ previewImage.crossOrigin = 'anonymous';
+ previewImage.onload = async _ => {
+ let previewCanvas = document.createElement('canvas');
+ let context = previewCanvas.getContext('2d');
+ previewCanvas.width = width;
+ previewCanvas.height = height;
+ context.drawImage(previewImage, 0, 0, width, height, 0, 0, width, height);
+ let pngData = previewCanvas.toDataURL();
+ resolve(pngData);
+ };
+ previewImage.onerror = _ => {
+ reject();
+ }
+ previewImage.src = snapshot;
+ } catch (e) {
+ this._previewSymbolArtDelimiter.outlineMaterial.visible = true;
+ reject();
+ }
+ });
+ }
+
}