diff --git a/src/playground/playground.css b/src/playground/playground.css
index f6144dfe..0b8e3f3d 100644
--- a/src/playground/playground.css
+++ b/src/playground/playground.css
@@ -4,7 +4,7 @@ body {
margin: 0px;
}
-body, html {
+body, html, .wrapper {
height: 100%
}
@@ -12,4 +12,12 @@ body, html {
height: 90%;
width: 90%;
margin: auto;
-}
\ No newline at end of file
+}
+
+#fileInput {
+ display: none;
+}
+
+.playgroundButton {
+ margin: 4px;
+}
diff --git a/src/playground/playground.jsx b/src/playground/playground.jsx
index e5cd5813..963ed980 100644
--- a/src/playground/playground.jsx
+++ b/src/playground/playground.jsx
@@ -29,19 +29,23 @@ class Playground extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
+ 'downloadImage',
'handleUpdateName',
- 'handleUpdateImage'
+ 'handleUpdateImage',
+ 'onUploadImage'
]);
// Append ?dir=rtl to URL to get RTL layout
const match = location.search.match(/dir=([^&]+)/);
const rtl = match && match[1] == 'rtl';
+ this.id = 0;
this.state = {
name: 'meow',
rotationCenterX: 20,
rotationCenterY: 400,
imageFormat: 'svg', // 'svg', 'png', or 'jpg'
image: svgString, // svg string or data URI
- rtl: rtl
+ imageId: this.id, // If this changes, the paint editor will reload
+ rtl: rtl,
};
this.reusableCanvas = document.createElement('canvas');
}
@@ -49,7 +53,12 @@ class Playground extends React.Component {
this.setState({name});
}
handleUpdateImage (isVector, image, rotationCenterX, rotationCenterY) {
- console.log(image);
+ this.setState({
+ imageFormat: isVector ? 'svg' : 'png'
+ });
+ if (!isVector) {
+ console.log(`Image width: ${image.width} Image height: ${image.height}`);
+ }
console.log(`rotationCenterX: ${rotationCenterX} rotationCenterY: ${rotationCenterY}`);
if (isVector) {
this.setState({image, rotationCenterX, rotationCenterY});
@@ -67,14 +76,105 @@ class Playground extends React.Component {
});
}
}
+ downloadImage () {
+ const downloadLink = document.createElement('a');
+ document.body.appendChild(downloadLink);
+
+ const format = this.state.imageFormat;
+ let data = this.state.image;
+ if (format === 'png' || format === 'jpg') {
+ data = this.b64toByteArray(data);
+ } else {
+ data = [data];
+ }
+ const blob = new Blob(data, {type: format});
+ const filename = `${this.state.name}.${format}`;
+ if ('download' in HTMLAnchorElement.prototype) {
+ const url = window.URL.createObjectURL(blob);
+ downloadLink.href = url;
+ downloadLink.download = filename;
+ downloadLink.type = blob.type;
+ downloadLink.click();
+ window.URL.revokeObjectURL(url);
+ } else {
+ // iOS Safari, open a new page and set href to data-uri
+ let popup = window.open('', '_blank');
+ const reader = new FileReader();
+ reader.onloadend = function () {
+ popup.location.href = reader.result;
+ popup = null;
+ };
+ reader.readAsDataURL(blob);
+ }
+ document.body.removeChild(downloadLink);
+ }
+ b64toByteArray (b64Data, sliceSize=512) {
+ // Remove header
+ b64Data = b64Data.substring(b64Data.indexOf('base64,') + 7);
+
+ const byteCharacters = atob(b64Data);
+ const byteArrays = [];
+
+ for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
+ const slice = byteCharacters.slice(offset, offset + sliceSize);
+
+ const byteNumbers = new Array(slice.length);
+ for (let i = 0; i < slice.length; i++) {
+ byteNumbers[i] = slice.charCodeAt(i);
+ }
+
+ const byteArray = new Uint8Array(byteNumbers);
+ byteArrays.push(byteArray);
+ }
+
+ return byteArrays;
+ }
+ uploadImage() {
+ document.getElementById(styles.fileInput).click();
+ }
+ onUploadImage(event) {
+ var file = event.target.files[0];
+ var type = file.type === 'image/svg+xml' ? 'svg' :
+ file.type === 'image/png' ? 'png' :
+ file.type === 'image/jpg' ? 'jpg' :
+ file.type === 'image/jpeg' ? 'jpg' :
+ null;
+
+ var reader = new FileReader();
+ if (type === 'svg') {
+ reader.readAsText(file,'UTF-8');
+ } else if (type === 'png' || type === 'jpg'){
+ reader.readAsDataURL(file);
+ } else {
+ alert("Couldn't read file type: " + file.type);
+ }
+
+ const that = this;
+ reader.onload = readerEvent => {
+ var content = readerEvent.target.result; // this is the content!
+
+ that.setState({
+ image: content,
+ name: file.name.split('.').slice(0, -1).join('.'),
+ imageId: ++that.id,
+ imageFormat: type,
+ rotationCenterX: undefined,
+ rotationCenterY: undefined,
+ });
+ }
+ }
render () {
return (
-