diff --git a/package-lock.json b/package-lock.json index 5e116fa3d..6f5b2b367 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13892,6 +13892,11 @@ "moment-timezone": "^0.5.25" } }, + "cropperjs": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.6.tgz", + "integrity": "sha512-eAgWf4j7sNJIG329qUHIFi17PSV0VtuWyAu9glZSgu/KlQSrfTQOC2zAz+jHGa5fAB+bJldEnQwvJEaJ8zRf5A==" + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", diff --git a/package.json b/package.json index cb4fea781..fc9baeaf3 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "@uppy/react-native": "file:packages/@uppy/react-native", "@uppy/redux-dev-tools": "file:packages/@uppy/redux-dev-tools", "@uppy/robodog": "file:packages/@uppy/robodog", + "@uppy/screen-capture": "file:packages/@uppy/screen-capture", "@uppy/status-bar": "file:packages/@uppy/status-bar", "@uppy/store-default": "file:packages/@uppy/store-default", "@uppy/store-redux": "file:packages/@uppy/store-redux", @@ -70,8 +71,8 @@ "@uppy/url": "file:packages/@uppy/url", "@uppy/utils": "file:packages/@uppy/utils", "@uppy/webcam": "file:packages/@uppy/webcam", - "@uppy/screen-capture": "file:packages/@uppy/screen-capture", "@uppy/xhr-upload": "file:packages/@uppy/xhr-upload", + "cropperjs": "^1.5.6", "remark-lint-uppy": "file:private/remark-lint-uppy", "uppy": "file:packages/uppy", "uppy.io": "file:website" diff --git a/packages/@uppy/dashboard/src/components/FileCard/cropper.scss b/packages/@uppy/dashboard/src/components/FileCard/cropper.scss new file mode 100644 index 000000000..f70d18860 --- /dev/null +++ b/packages/@uppy/dashboard/src/components/FileCard/cropper.scss @@ -0,0 +1,304 @@ +/*! + * Cropper.js v1.5.6 + * https://fengyuanchen.github.io/cropperjs + * + * Copyright 2015-present Chen Fengyuan + * Released under the MIT license + * + * Date: 2019-10-04T04:33:44.164Z + */ + + .cropper-container { + direction: ltr; + font-size: 0; + line-height: 0; + position: relative; + -ms-touch-action: none; + touch-action: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.cropper-container img { + display: block; + height: 100%; + image-orientation: 0deg; + max-height: none !important; + max-width: none !important; + min-height: 0 !important; + min-width: 0 !important; + width: 100%; +} + +.cropper-wrap-box, +.cropper-canvas, +.cropper-drag-box, +.cropper-crop-box, +.cropper-modal { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +.cropper-wrap-box, +.cropper-canvas { + overflow: hidden; +} + +.cropper-drag-box { + background-color: #fff; + opacity: 0; +} + +.cropper-modal { + background-color: #000; + opacity: 0.5; +} + +.cropper-view-box { + display: block; + height: 100%; + outline: 1px solid #39f; + outline-color: rgba(51, 153, 255, 0.75); + overflow: hidden; + width: 100%; +} + +.cropper-dashed { + border: 0 dashed #eee; + display: block; + opacity: 0.5; + position: absolute; +} + +.cropper-dashed.dashed-h { + border-bottom-width: 1px; + border-top-width: 1px; + height: calc(100% / 3); + left: 0; + top: calc(100% / 3); + width: 100%; +} + +.cropper-dashed.dashed-v { + border-left-width: 1px; + border-right-width: 1px; + height: 100%; + left: calc(100% / 3); + top: 0; + width: calc(100% / 3); +} + +.cropper-center { + display: block; + height: 0; + left: 50%; + opacity: 0.75; + position: absolute; + top: 50%; + width: 0; +} + +.cropper-center::before, +.cropper-center::after { + background-color: #eee; + content: ' '; + display: block; + position: absolute; +} + +.cropper-center::before { + height: 1px; + left: -3px; + top: 0; + width: 7px; +} + +.cropper-center::after { + height: 7px; + left: 0; + top: -3px; + width: 1px; +} + +.cropper-face, +.cropper-line, +.cropper-point { + display: block; + height: 100%; + opacity: 0.1; + position: absolute; + width: 100%; +} + +.cropper-face { + background-color: #fff; + left: 0; + top: 0; +} + +.cropper-line { + background-color: #39f; +} + +.cropper-line.line-e { + cursor: ew-resize; + right: -3px; + top: 0; + width: 5px; +} + +.cropper-line.line-n { + cursor: ns-resize; + height: 5px; + left: 0; + top: -3px; +} + +.cropper-line.line-w { + cursor: ew-resize; + left: -3px; + top: 0; + width: 5px; +} + +.cropper-line.line-s { + bottom: -3px; + cursor: ns-resize; + height: 5px; + left: 0; +} + +.cropper-point { + background-color: #39f; + height: 5px; + opacity: 0.75; + width: 5px; +} + +.cropper-point.point-e { + cursor: ew-resize; + margin-top: -3px; + right: -3px; + top: 50%; +} + +.cropper-point.point-n { + cursor: ns-resize; + left: 50%; + margin-left: -3px; + top: -3px; +} + +.cropper-point.point-w { + cursor: ew-resize; + left: -3px; + margin-top: -3px; + top: 50%; +} + +.cropper-point.point-s { + bottom: -3px; + cursor: s-resize; + left: 50%; + margin-left: -3px; +} + +.cropper-point.point-ne { + cursor: nesw-resize; + right: -3px; + top: -3px; +} + +.cropper-point.point-nw { + cursor: nwse-resize; + left: -3px; + top: -3px; +} + +.cropper-point.point-sw { + bottom: -3px; + cursor: nesw-resize; + left: -3px; +} + +.cropper-point.point-se { + bottom: -3px; + cursor: nwse-resize; + height: 20px; + opacity: 1; + right: -3px; + width: 20px; +} + +@media (min-width: 768px) { + .cropper-point.point-se { + height: 15px; + width: 15px; + } +} + +@media (min-width: 992px) { + .cropper-point.point-se { + height: 10px; + width: 10px; + } +} + +@media (min-width: 1200px) { + .cropper-point.point-se { + height: 5px; + opacity: 0.75; + width: 5px; + } +} + +.cropper-point.point-se::before { + background-color: #39f; + bottom: -50%; + content: ' '; + display: block; + height: 200%; + opacity: 0; + position: absolute; + right: -50%; + width: 200%; +} + +.cropper-invisible { + opacity: 0; +} + +.cropper-bg { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'); +} + +.cropper-hide { + display: block; + height: 0; + position: absolute; + width: 0; +} + +.cropper-hidden { + display: none !important; +} + +.cropper-move { + cursor: move; +} + +.cropper-crop { + cursor: crosshair; +} + +.cropper-disabled .cropper-drag-box, +.cropper-disabled .cropper-face, +.cropper-disabled .cropper-line, +.cropper-disabled .cropper-point { + cursor: not-allowed; +} diff --git a/packages/@uppy/dashboard/src/components/FileCard/index.js b/packages/@uppy/dashboard/src/components/FileCard/index.js index 03f46fa86..055499e1d 100644 --- a/packages/@uppy/dashboard/src/components/FileCard/index.js +++ b/packages/@uppy/dashboard/src/components/FileCard/index.js @@ -111,7 +111,7 @@ class FileCard extends Component {
- +
diff --git a/packages/@uppy/dashboard/src/components/FilePreview.js b/packages/@uppy/dashboard/src/components/FilePreview.js index 42e99f437..313b1af40 100644 --- a/packages/@uppy/dashboard/src/components/FilePreview.js +++ b/packages/@uppy/dashboard/src/components/FilePreview.js @@ -1,19 +1,77 @@ const getFileTypeIcon = require('../utils/getFileTypeIcon') -const { h } = require('preact') +const { h, Component } = require('preact') -module.exports = function FilePreview (props) { - const file = props.file +const Cropper = require('cropperjs') - if (file.preview) { - return {file.name} +// module.exports = function FilePreview (props) { +// const file = props.file + +// if (file.preview) { +// return {file.name} +// } + +// const { color, icon } = getFileTypeIcon(file.type) + +// return ( +//
+// {icon} +// +//
+// ) +// } + +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) + } } - const { color, icon } = getFileTypeIcon(file.type) + render () { + const file = this.props.file - return ( -
- {icon} - -
- ) + if (file.preview) { + return ( + {file.name} { this.img = ref }} + /> + ) + } + + const { color, icon } = getFileTypeIcon(file.type) + + return ( +
+ {icon} + +
+ ) + } } diff --git a/packages/@uppy/dashboard/src/index.js b/packages/@uppy/dashboard/src/index.js index ae79a8518..3936a01cf 100644 --- a/packages/@uppy/dashboard/src/index.js +++ b/packages/@uppy/dashboard/src/index.js @@ -832,6 +832,7 @@ module.exports = class Dashboard extends Plugin { i18n: this.i18n, i18nArray: this.i18nArray, removeFile: this.uppy.removeFile, + uppy: this.uppy, info: this.uppy.info, note: this.opts.note, metaFields: pluginState.metaFields, diff --git a/packages/@uppy/dashboard/src/style.scss b/packages/@uppy/dashboard/src/style.scss index d0ccb055b..f14bd8aca 100644 --- a/packages/@uppy/dashboard/src/style.scss +++ b/packages/@uppy/dashboard/src/style.scss @@ -8,6 +8,8 @@ @import './components/FileItem/index.scss'; @import './components/FileCard/index.scss'; +@import './components/FileCard/cropper.scss'; + // Transitions // .uppy-transition-slideDownUp-enter {