Parcourir la source

Move cropping to a standalone image-editor plugin

Artur Paikin il y a 4 ans
Parent
commit
25f4f405fe

+ 20 - 70
packages/@uppy/dashboard/src/components/FilePreview.js

@@ -1,77 +1,27 @@
 const getFileTypeIcon = require('../utils/getFileTypeIcon')
-const { h, Component } = require('preact')
+const { h } = require('preact')
 
-const Cropper = require('cropperjs')
-
-// module.exports = function FilePreview (props) {
-//   const file = props.file
-
-//   if (file.preview) {
-//     return <img class="uppy-DashboardItem-previewImg" alt={file.name} src={file.preview} />
-//   }
-
-//   const { color, icon } = getFileTypeIcon(file.type)
-
-//   return (
-//     <div class="uppy-DashboardItem-previewIconWrap">
-//       <span class="uppy-DashboardItem-previewIcon" style={{ color: color }}>{icon}</span>
-//       <svg aria-hidden="true" focusable="false" class="uppy-DashboardItem-previewIconBg" width="58" height="76" viewBox="0 0 58 76"><rect fill="#FFF" width="58" height="76" rx="3" fill-rule="evenodd" /></svg>
-//     </div>
-//   )
-// }
-
-module.exports = class FilePreview extends Component {
-  componentDidMount () {
-    const file = this.props.file
-    if (file.preview) {
-      const cropper = new Cropper(this.img, {
-        aspectRatio: 16 / 9,
-        crop (event) {
-          console.log(event.detail.x)
-          console.log(event.detail.y)
-          console.log(event.detail.width)
-          console.log(event.detail.height)
-          console.log(event.detail.rotate)
-          console.log(event.detail.scaleX)
-          console.log(event.detail.scaleY)
-        }
-      })
-
-      setTimeout(() => {
-        cropper.getCroppedCanvas().toBlob((blob) => {
-          console.log(blob)
-          this.props.uppy.setFileState(file.id, {
-            data: blob,
-            preview: null
-          })
-          const updatedFile = this.props.uppy.getFile(file.id)
-          this.props.uppy.emit('thumbnail:request', updatedFile)
-        })
-      }, 5000)
-    }
-  }
-
-  render () {
-    const file = this.props.file
-
-    if (file.preview) {
-      return (
-        <img
-          class="uppy-DashboardItem-previewImg"
-          alt={file.name}
-          src={file.preview}
-          ref={(ref) => { this.img = ref }}
-        />
-      )
-    }
-
-    const { color, icon } = getFileTypeIcon(file.type)
+module.exports = function FilePreview (props) {
+  const file = props.file
 
+  if (file.preview) {
     return (
-      <div class="uppy-DashboardItem-previewIconWrap">
-        <span class="uppy-DashboardItem-previewIcon" style={{ color: color }}>{icon}</span>
-        <svg aria-hidden="true" focusable="false" class="uppy-DashboardItem-previewIconBg" width="58" height="76" viewBox="0 0 58 76"><rect fill="#FFF" width="58" height="76" rx="3" fill-rule="evenodd" /></svg>
-      </div>
+      <img
+        class="uppy-Dashboard-Item-previewImg"
+        alt={file.name}
+        src={file.preview}
+      />
     )
   }
+
+  const { color, icon } = getFileTypeIcon(file.type)
+
+  return (
+    <div class="uppy-Dashboard-Item-previewIconWrap">
+      <span class="uppy-Dashboard-Item-previewIcon" style={{ color: color }}>{icon}</span>
+      <svg aria-hidden="true" focusable="false" class="uppy-Dashboard-Item-previewIconBg" width="58" height="76" viewBox="0 0 58 76">
+        <rect fill="#FFF" width="58" height="76" rx="3" fill-rule="evenodd" />
+      </svg>
+    </div>
+  )
 }

+ 21 - 0
packages/@uppy/image-editor/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2020 Transloadit
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 42 - 0
packages/@uppy/image-editor/README.md

@@ -0,0 +1,42 @@
+# @uppy/file-input
+
+<img src="https://uppy.io/images/logos/uppy-dog-head-arrow.svg" width="120" alt="Uppy logo: a superman puppy in a pink suit" align="right">
+
+<a href="https://www.npmjs.com/package/@uppy/file-input"><img src="https://img.shields.io/npm/v/@uppy/file-input.svg?style=flat-square"></a>
+<a href="https://travis-ci.org/transloadit/uppy"><img src="https://img.shields.io/travis/transloadit/uppy/master.svg?style=flat-square" alt="Build Status"></a>
+
+FileInput is the most barebones UI for selecting files—it shows a single button that, when clicked, opens up the browser’s file selector.
+
+**[Read the docs](https://uppy.io/docs/fileinput)** | **[Try it](https://uppy.io/examples/xhrupload/)**
+
+Uppy is being developed by the folks at [Transloadit](https://transloadit.com), a versatile file encoding service.
+
+## Example
+
+```js
+const Uppy = require('@uppy/core')
+const FileInput = require('@uppy/file-input')
+
+const uppy = Uppy()
+uppy.use(FileInput, {
+  // Options
+})
+```
+
+## Installation
+
+```bash
+$ npm install @uppy/file-input --save
+```
+
+We recommend installing from npm and then using a module bundler such as [Webpack](https://webpack.js.org/), [Browserify](http://browserify.org/) or [Rollup.js](http://rollupjs.org/).
+
+Alternatively, you can also use this plugin in a pre-built bundle from Transloadit's CDN: Edgly. In that case `Uppy` will attach itself to the global `window.Uppy` object. See the [main Uppy documentation](https://uppy.io/docs/#Installation) for instructions.
+
+## Documentation
+
+Documentation for this plugin can be found on the [Uppy website](https://uppy.io/docs/fileinput).
+
+## License
+
+[The MIT License](./LICENSE).

+ 31 - 0
packages/@uppy/image-editor/package.json

@@ -0,0 +1,31 @@
+{
+  "name": "@uppy/image-editor",
+  "description": "Image editor and cropping UI",
+  "version": "0.1.0",
+  "license": "MIT",
+  "main": "lib/index.js",
+  "style": "dist/style.min.css",
+  "types": "types/index.d.ts",
+  "keywords": [
+    "file uploader",
+    "upload",
+    "uppy",
+    "uppy-plugin",
+    "image-editor",
+    "cropper"
+  ],
+  "homepage": "https://uppy.io",
+  "bugs": {
+    "url": "https://github.com/transloadit/uppy/issues"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/transloadit/uppy.git"
+  },
+  "dependencies": {
+    "preact": "8.2.9"
+  },
+  "peerDependencies": {
+    "@uppy/core": "^1.0.0"
+  }
+}

+ 0 - 0
packages/@uppy/dashboard/src/components/FileCard/cropper.scss → packages/@uppy/image-editor/src/cropper.scss


+ 118 - 0
packages/@uppy/image-editor/src/index.js

@@ -0,0 +1,118 @@
+const { Plugin } = require('@uppy/core')
+const Cropper = require('cropperjs')
+// const Translator = require('@uppy/utils/lib/Translator')
+const { h } = require('preact')
+
+module.exports = class ImageEditor extends Plugin {
+  static VERSION = require('../package.json').version
+
+  constructor (uppy, opts) {
+    super(uppy, opts)
+    this.id = this.opts.id || 'ImageEditor'
+    this.title = 'Image Editor'
+    this.type = 'editor'
+
+    // this.defaultLocale = {
+    //   strings: {
+    //     chooseFiles: 'Choose files'
+    //   }
+    // }
+
+    // Default options
+    const defaultOptions = {}
+
+    // Merge default options with the ones set by user
+    this.opts = { ...defaultOptions, ...opts }
+
+    // this.i18nInit()
+
+    this.initEditor = this.initEditor.bind(this)
+    this.setCurrentImage = this.setCurrentImage.bind(this)
+    this.render = this.render.bind(this)
+  }
+
+  // setOptions (newOpts) {
+  //   super.setOptions(newOpts)
+  //   this.i18nInit()
+  // }
+
+  // i18nInit () {
+  //   this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
+  //   this.i18n = this.translator.translate.bind(this.translator)
+  //   this.i18nArray = this.translator.translateArray.bind(this.translator)
+  //   this.setPluginState() // so that UI re-renders and we see the updated locale
+  // }
+
+  initEditor () {
+    const { currentImage } = this.getPluginState()
+
+    if (currentImage.preview) {
+      const cropper = new Cropper(this.imgElement, {
+        aspectRatio: 16 / 9,
+        crop (event) {
+          console.log(event.detail.x)
+          console.log(event.detail.y)
+          console.log(event.detail.width)
+          console.log(event.detail.height)
+          console.log(event.detail.rotate)
+          console.log(event.detail.scaleX)
+          console.log(event.detail.scaleY)
+        }
+      })
+
+      setTimeout(() => {
+        cropper.getCroppedCanvas().toBlob((blob) => {
+          console.log(blob)
+          this.uppy.setFileState(currentImage.id, {
+            data: blob,
+            preview: null
+          })
+          const updatedFile = this.uppy.getFile(currentImage.id)
+          this.uppy.emit('thumbnail:request', updatedFile)
+        })
+      }, 5000)
+    }
+  }
+
+  setCurrentImage (file) {
+    const firstFile = this.uppy.getFiles()[0]
+    this.setPluginState({
+      currentImage: firstFile
+    })
+  }
+
+  install () {
+    this.setPluginState({
+      currentImage: null
+    })
+
+    const target = this.opts.target
+    if (target) {
+      this.mount(target, this)
+    }
+  }
+
+  uninstall () {
+    this.unmount()
+  }
+
+  render (state) {
+    console.log(this.getPluginState())
+    const { currentImage } = this.getPluginState()
+
+    if (currentImage === null) {
+      return
+    }
+
+    return (
+      <div class="uppy-ImageCropper">
+        <img
+          class="uppy-ImageCropper-image"
+          alt={currentImage.name}
+          src={currentImage.preview}
+          ref={(ref) => { this.imgElement = ref }}
+        />
+      </div>
+    )
+  }
+}

+ 4 - 0
packages/@uppy/image-editor/src/style.scss

@@ -0,0 +1,4 @@
+@import '@uppy/core/src/_utils.scss';
+@import '@uppy/core/src/_variables.scss';
+@import 'cropper.scss';
+

+ 16 - 0
packages/@uppy/image-editor/types/index.d.ts

@@ -0,0 +1,16 @@
+import Uppy = require('@uppy/core')
+import FileInputLocale = require('./generatedLocale')
+
+declare module FileInput {
+  export interface FileInputOptions extends Uppy.PluginOptions {
+    replaceTargetContent?: boolean
+    target?: Uppy.PluginTarget
+    pretty?: boolean
+    inputName?: string
+    locale?: FileInputLocale
+  }
+}
+
+declare class FileInput extends Uppy.Plugin<FileInput.FileInputOptions> {}
+
+export = FileInput

+ 1 - 0
packages/@uppy/image-editor/types/index.test-d.ts

@@ -0,0 +1 @@
+import FileInput = require('../')

+ 2 - 1
packages/uppy/src/style.scss

@@ -8,4 +8,5 @@
 @import '@uppy/status-bar/src/style.scss';
 @import '@uppy/url/src/style.scss';
 @import '@uppy/webcam/src/style.scss';
-@import '@uppy/screen-capture/src/style.scss'
+@import '@uppy/screen-capture/src/style.scss';
+@import '@uppy/image-editor/src/style.scss';