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(); + } + }); + } + }