From b8b92269df8e575238b1313e63d625aa790f6049 Mon Sep 17 00:00:00 2001 From: Karishma Chadha <kchadha@scratch.mit.edu> Date: Thu, 19 Apr 2018 17:15:38 -0400 Subject: [PATCH] Handle SVG upload (with bitmap coming soon). --- src/components/target-pane/target-pane.jsx | 8 +-- src/containers/costume-tab.jsx | 62 +++++++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/components/target-pane/target-pane.jsx b/src/components/target-pane/target-pane.jsx index 7cc7a1ed2..4be489f69 100644 --- a/src/components/target-pane/target-pane.jsx +++ b/src/components/target-pane/target-pane.jsx @@ -89,9 +89,11 @@ const spriteShape = PropTypes.shape({ costume: PropTypes.shape({ url: PropTypes.string, name: PropTypes.string.isRequired, - bitmapResolution: PropTypes.number.isRequired, - rotationCenterX: PropTypes.number.isRequired, - rotationCenterY: PropTypes.number.isRequired + // The following are optional because costumes uploaded from disk + // will not have these properties available + bitmapResolution: PropTypes.number, + rotationCenterX: PropTypes.number, + rotationCenterY: PropTypes.number }), direction: PropTypes.number, id: PropTypes.string, diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx index 3ed2ce90f..c0ed6a4ba 100644 --- a/src/containers/costume-tab.jsx +++ b/src/containers/costume-tab.jsx @@ -49,7 +49,7 @@ const messages = defineMessages({ id: 'gui.costumeTab.addSurpriseCostume' }, addFileCostumeMsg: { - defaultMessage: 'Coming Soon', + defaultMessage: 'Upload Costume', description: 'Button to add a file upload costume in the editor tab', id: 'gui.costumeTab.addFileCostume' }, @@ -69,7 +69,10 @@ class CostumeTab extends React.Component { 'handleDuplicateCostume', 'handleNewBlankCostume', 'handleSurpriseCostume', - 'handleSurpriseBackdrop' + 'handleSurpriseBackdrop', + 'handleFileUploadClick', + 'handleCostumeUpload', + 'setFileInput' ]); const { editingTarget, @@ -158,14 +161,61 @@ class CostumeTab extends React.Component { }; this.props.vm.addCostume(item.md5, vmCostume); } - handleCostumeUpload () { + handleCostumeUpload (e) { + const thisFileInput = e.target; + let thisFile = null; + const reader = new FileReader(); + reader.onload = () => { + // Reset the file input value now that we have everything we need + // so that the user can upload the same image multiple times + // if they choose + thisFileInput.value = null; + // Cache the image in storage + const costumeBuffer = reader.result; + const storage = this.props.vm.runtime.storage; + const fileType = thisFile.type; // check what the browser thinks this is + // Only handling png and svg right now + let costumeFormat = null; + let assetType = null; + if (fileType === 'image/svg+xml') { + costumeFormat = storage.DataFormat.SVG; + assetType = storage.AssetType.ImageVector; + } else if (fileType === 'image/jpeg') { + costumeFormat = storage.DataFormat.JPG; + assetType = storage.AssetType.ImageBitmap; + } else { + costumeFormat = storage.DataFormat.PNG; + assetType = storage.AssetType.ImageBitmap; + } + + const md5 = storage.builtinHelper.cache( + assetType, costumeFormat, new Uint8Array(costumeBuffer)); + + const md5Ext = `${md5}.${costumeFormat}`; + + // We don't have info about bitmapResolution or rotationCenter... + const vmCostume = { + name: 'costume1', + // rotationCenterX: 0, + // rotationCenterY: 0, + // bitmapResolution: 1, + dataFormat: costumeFormat, + md5: `${md5Ext}` + }; + this.props.vm.addCostume(md5Ext, vmCostume); + + }; + if (thisFileInput.files) { + thisFile = thisFileInput.files[0]; + reader.readAsArrayBuffer(thisFile); + } } handleFileUploadClick () { - + this.fileInput.click(); } setFileInput (input) { - if (input && !this.fileInput) + this.fileInput = input; } formatCostumeDetails (size) { // Round up width and height for scratch-flash compatibility @@ -220,7 +270,7 @@ class CostumeTab extends React.Component { title: intl.formatMessage(messages.addFileCostumeMsg), img: fileUploadIcon, onClick: this.handleFileUploadClick, - fileAccept: '.svg', + fileAccept: '.svg,', // .png, .jpg, .jpeg coming soon fileChange: this.handleCostumeUpload, fileInput: this.setFileInput }, -- GitLab