Merge pull request #1956 from Human-Connection/cropper-enhancements

Refactor and tidy up crop image implementation
This commit is contained in:
mattwr18 2019-11-04 11:13:21 +01:00 committed by GitHub
commit abbd090eb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 46 deletions

View File

@ -963,7 +963,7 @@
url-regex "~4.1.1"
video-extensions "~1.1.0"
"@metascraper/helpers@^5.7.14", "@metascraper/helpers@^5.7.17":
"@metascraper/helpers@^5.7.17":
version "5.7.17"
resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.7.17.tgz#401897c7239090ca7149b83e581712845bbb3709"
integrity sha512-t21LqfDpaIrWg2JaivXG6mVzUsIVW05cAsKySA5Tj9Hgi9oZXxaaNes5XipOzk6P242RI48SDo7CkSbYiio7Tw==
@ -3589,7 +3589,6 @@ extsprintf@^1.2.0:
faker@Marak/faker.js#master:
version "4.1.0"
uid "9fd8d7d37b398842d0784a116a340f7aa6afb89b"
resolved "https://codeload.github.com/Marak/faker.js/tar.gz/9fd8d7d37b398842d0784a116a340f7aa6afb89b"
fast-deep-equal@^2.0.1:

View File

@ -15,6 +15,7 @@ describe('TeaserImage.vue', () => {
$toast: {
error: jest.fn(),
},
$t: jest.fn(string => string),
}
})
describe('mount', () => {

View File

@ -7,8 +7,13 @@
:use-custom-slot="true"
@vdropzone-error="verror"
@vdropzone-thumbnail="transformImage"
@vdropzone-drop="dropzoneDrop"
>
<div class="crop-overlay" ref="cropperOverlay" v-show="showCropper">
<ds-button @click="cropImage" class="crop-confirm" primary>
{{ $t('contribution.teaserImage.cropperConfirm') }}
</ds-button>
<ds-button @click="cancelCrop" class="crop-cancel" icon="close"></ds-button>
</div>
<div
:class="{
'hc-attachments-upload-area-post': true,
@ -47,7 +52,14 @@ export default {
maxFilesize: 5.0,
previewTemplate: this.template(),
},
image: null,
file: null,
editor: null,
cropper: null,
thumbnailElement: null,
oldImage: null,
error: false,
showCropper: false,
}
},
watch: {
@ -72,50 +84,53 @@ export default {
this.$toast.error(file.status, message)
},
transformImage(file) {
let thumbnailElement, editor, confirm, thumbnailPreview, contributionImage
// Create the image editor overlay
editor = document.createElement('div')
thumbnailElement = document.querySelectorAll('#postdropzone')[0]
thumbnailPreview = document.querySelectorAll('.thumbnail-preview')[0]
if (thumbnailPreview) thumbnailPreview.remove()
contributionImage = document.querySelectorAll('.contribution-image')[0]
if (contributionImage) contributionImage.remove()
editor.classList.add('crop-overlay')
thumbnailElement.appendChild(editor)
// Create the confirm button
confirm = document.createElement('button')
confirm.classList.add('crop-confirm', 'ds-button', 'ds-button-primary')
confirm.textContent = this.$t('contribution.teaserImage.cropperConfirm')
confirm.addEventListener('click', () => {
// Get the canvas with image data from Cropper.js
let canvas = cropper.getCroppedCanvas()
canvas.toBlob(blob => {
this.$refs.el.manuallyAddFile(blob, canvas.toDataURL(), null, null, {
dontSubstractMaxFiles: false,
addToFiles: true,
})
image = new Image()
image.src = canvas.toDataURL()
image.classList.add('thumbnail-preview')
thumbnailElement.appendChild(image)
// Remove the editor from view
editor.parentNode.removeChild(editor)
const croppedImageFile = new File([blob], file.name, { type: 'image/jpeg' })
this.$emit('addTeaserImage', croppedImageFile)
}, 'image/jpeg')
})
editor.appendChild(confirm)
// Load the image
let image = new Image()
image.src = URL.createObjectURL(file)
editor.appendChild(image)
// Create Cropper.js and pass image
let cropper = new Cropper(image, { zoomable: false, autoCropArea: 1.0 })
this.file = file
this.showCropper = true
this.initEditor()
this.initCropper()
},
dropzoneDrop() {
let cropOverlay = document.querySelectorAll('.crop-overlay')[0]
if (cropOverlay) cropOverlay.remove()
initEditor() {
this.editor = this.$refs.cropperOverlay
this.clearImages()
this.thumbnailElement.appendChild(this.editor)
},
clearImages() {
this.thumbnailElement = document.querySelectorAll('#postdropzone')[0]
const thumbnailPreview = document.querySelectorAll('.thumbnail-preview')[0]
if (thumbnailPreview) thumbnailPreview.remove()
const contributionImage = document.querySelectorAll('.contribution-image')[0]
this.oldImage = contributionImage
if (contributionImage) contributionImage.remove()
},
initCropper() {
this.image = new Image()
this.image.src = URL.createObjectURL(this.file)
this.editor.appendChild(this.image)
this.cropper = new Cropper(this.image, { zoomable: false, autoCropArea: 0.9 })
},
cropImage() {
this.showCropper = false
const canvas = this.cropper.getCroppedCanvas()
canvas.toBlob(blob => {
this.setupPreview(canvas)
this.removeCropper()
const croppedImageFile = new File([blob], this.file.name, { type: 'image/jpeg' })
this.$emit('addTeaserImage', croppedImageFile)
}, 'image/jpeg')
},
setupPreview(canvas) {
this.image = new Image()
this.image.src = canvas.toDataURL()
this.image.classList.add('thumbnail-preview')
this.thumbnailElement.appendChild(this.image)
},
cancelCrop() {
this.showCropper = false
if (this.oldImage) this.thumbnailElement.appendChild(this.oldImage)
this.removeCropper()
},
removeCropper() {
this.editor.removeChild(document.querySelectorAll('.cropper-container')[0])
},
},
}
@ -209,4 +224,10 @@ export default {
top: 10px;
z-index: 1;
}
.crop-cancel {
position: absolute;
right: 10px;
top: 10px;
z-index: 1;
}
</style>