upgrade to new cropperjs 2.0 API
This commit is contained in:
parent
246160d966
commit
eda51ae486
4 changed files with 86 additions and 45 deletions
|
|
@ -1,5 +1,4 @@
|
||||||
import Cropper from 'cropperjs'
|
import 'cropperjs' // This adds all of the cropperjs's components into DOM
|
||||||
import 'cropperjs/dist/cropper.css'
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faCircleNotch
|
faCircleNotch
|
||||||
|
|
@ -19,19 +18,6 @@ const ImageCropper = {
|
||||||
type: Function,
|
type: Function,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
cropperOptions: {
|
|
||||||
type: Object,
|
|
||||||
default () {
|
|
||||||
return {
|
|
||||||
aspectRatio: 1,
|
|
||||||
autoCropArea: 1,
|
|
||||||
viewMode: 1,
|
|
||||||
movable: false,
|
|
||||||
zoomable: false,
|
|
||||||
guides: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mimes: {
|
mimes: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon'
|
default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon'
|
||||||
|
|
@ -48,7 +34,6 @@ const ImageCropper = {
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
cropper: undefined,
|
|
||||||
dataUrl: undefined,
|
dataUrl: undefined,
|
||||||
filename: undefined,
|
filename: undefined,
|
||||||
submitting: false
|
submitting: false
|
||||||
|
|
@ -67,27 +52,30 @@ const ImageCropper = {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
destroy () {
|
destroy () {
|
||||||
if (this.cropper) {
|
|
||||||
this.cropper.destroy()
|
|
||||||
}
|
|
||||||
this.$refs.input.value = ''
|
this.$refs.input.value = ''
|
||||||
this.dataUrl = undefined
|
this.dataUrl = undefined
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
},
|
},
|
||||||
submit (cropping = true) {
|
submit (cropping = true) {
|
||||||
this.submitting = true
|
this.submitting = true
|
||||||
this.submitHandler(cropping && this.cropper, this.file)
|
|
||||||
|
let cropperPromise
|
||||||
|
if (cropping) {
|
||||||
|
cropperPromise = this.$refs.cropperSelection.$toCanvas()
|
||||||
|
} else {
|
||||||
|
cropperPromise = Promise.resolve()
|
||||||
|
}
|
||||||
|
cropperPromise.then(canvas => {
|
||||||
|
this.submitHandler(canvas, this.file)
|
||||||
.then(() => this.destroy())
|
.then(() => this.destroy())
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.submitting = false
|
this.submitting = false
|
||||||
})
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
pickImage () {
|
pickImage () {
|
||||||
this.$refs.input.click()
|
this.$refs.input.click()
|
||||||
},
|
},
|
||||||
createCropper () {
|
|
||||||
this.cropper = new Cropper(this.$refs.img, this.cropperOptions)
|
|
||||||
},
|
|
||||||
getTriggerDOM () {
|
getTriggerDOM () {
|
||||||
return typeof this.trigger === 'object' ? this.trigger : document.querySelector(this.trigger)
|
return typeof this.trigger === 'object' ? this.trigger : document.querySelector(this.trigger)
|
||||||
},
|
},
|
||||||
|
|
@ -103,6 +91,29 @@ const ImageCropper = {
|
||||||
reader.readAsDataURL(this.file)
|
reader.readAsDataURL(this.file)
|
||||||
this.$emit('changed', this.file, reader)
|
this.$emit('changed', this.file, reader)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
inSelection(selection, maxSelection) {
|
||||||
|
return (
|
||||||
|
selection.x >= maxSelection.x
|
||||||
|
&& selection.y >= maxSelection.y
|
||||||
|
&& (selection.x + selection.width) <= (maxSelection.x + maxSelection.width)
|
||||||
|
&& (selection.y + selection.height) <= (maxSelection.y + maxSelection.height)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onCropperSelectionChange(event) {
|
||||||
|
const cropperCanvas = this.$refs.cropperCanvas
|
||||||
|
const cropperCanvasRect = cropperCanvas.getBoundingClientRect()
|
||||||
|
const selection = event.detail
|
||||||
|
const maxSelection = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: cropperCanvasRect.width,
|
||||||
|
height: cropperCanvasRect.height,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.inSelection(selection, maxSelection)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,43 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="image-cropper">
|
<div class="image-cropper">
|
||||||
<div v-if="dataUrl">
|
<div v-if="dataUrl">
|
||||||
<div class="image-cropper-image-container">
|
<cropper-canvas
|
||||||
<img
|
background
|
||||||
ref="img"
|
class="image-cropper-canvas"
|
||||||
:src="dataUrl"
|
ref="cropperCanvas"
|
||||||
alt=""
|
height="25em"
|
||||||
@load.stop="createCropper"
|
|
||||||
>
|
>
|
||||||
</div>
|
<cropper-image
|
||||||
|
:src="dataUrl"
|
||||||
|
alt="Picture"
|
||||||
|
ref="cropperImage"
|
||||||
|
class="image-cropper-image"
|
||||||
|
translatable
|
||||||
|
scalable
|
||||||
|
/>
|
||||||
|
<cropper-shade hidden />
|
||||||
|
<cropper-handle action="select" plain />
|
||||||
|
<cropper-selection
|
||||||
|
ref="cropperSelection"
|
||||||
|
initial-coverage="1"
|
||||||
|
aspect-ratio="1"
|
||||||
|
movable
|
||||||
|
resizable
|
||||||
|
@change="onCropperSelectionChange"
|
||||||
|
>
|
||||||
|
<cropper-grid role="grid" covered></cropper-grid>
|
||||||
|
<cropper-crosshair centered></cropper-crosshair>
|
||||||
|
<cropper-handle action="move" theme-color="rgba(255, 255, 255, 0.35)"></cropper-handle>
|
||||||
|
<cropper-handle action="n-resize"></cropper-handle>
|
||||||
|
<cropper-handle action="e-resize"></cropper-handle>
|
||||||
|
<cropper-handle action="s-resize"></cropper-handle>
|
||||||
|
<cropper-handle action="w-resize"></cropper-handle>
|
||||||
|
<cropper-handle action="ne-resize"></cropper-handle>
|
||||||
|
<cropper-handle action="nw-resize"></cropper-handle>
|
||||||
|
<cropper-handle action="se-resize"></cropper-handle>
|
||||||
|
<cropper-handle action="sw-resize"></cropper-handle>
|
||||||
|
</cropper-selection>
|
||||||
|
</cropper-canvas>
|
||||||
<div class="image-cropper-buttons-wrapper">
|
<div class="image-cropper-buttons-wrapper">
|
||||||
<button
|
<button
|
||||||
class="button-default btn"
|
class="button-default btn"
|
||||||
|
|
@ -55,20 +84,18 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-image-container {
|
&-canvas {
|
||||||
position: relative;
|
height: 25em;
|
||||||
|
width: 25em;
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-buttons-wrapper {
|
&-buttons-wrapper {
|
||||||
margin-top: 10px;
|
display: grid;
|
||||||
|
grid-gap: 0.5em;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
margin-top: 5px;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ const ProfileTab = {
|
||||||
this.submitBackground('')
|
this.submitBackground('')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
submitAvatar (cropper, file) {
|
submitAvatar (canvas, file) {
|
||||||
const that = this
|
const that = this
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
function updateAvatar (avatar, avatarName) {
|
function updateAvatar (avatar, avatarName) {
|
||||||
|
|
@ -232,8 +232,8 @@ const ProfileTab = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cropper) {
|
if (canvas) {
|
||||||
cropper.getCroppedCanvas().toBlob((data) => updateAvatar(data, file.name), file.type)
|
canvas.toBlob((data) => updateAvatar(data, file.name), file.type)
|
||||||
} else {
|
} else {
|
||||||
updateAvatar(file, file.name)
|
updateAvatar(file, file.name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,9 @@ export default defineConfig(async ({ mode, command }) => {
|
||||||
if (tag === 'pinch-zoom') {
|
if (tag === 'pinch-zoom') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if (tag.startsWith('cropper-')) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue