Page MenuHomePhorge

No OneTemporary

Size
13 KB
Referenced Files
None
Subscribers
None
diff --git a/package.json b/package.json
index bc8b48613..e7dde2034 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
"body-scroll-lock": "3.1.5",
"chromatism": "3.0.0",
"click-outside-vue3": "4.0.1",
- "cropperjs": "1.6.2",
+ "cropperjs": "2.0.0",
"escape-html": "1.0.3",
"globals": "^16.0.0",
"hash-sum": "^2.0.0",
diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js
index 55e901a03..3cb4f6fd1 100644
--- a/src/components/image_cropper/image_cropper.js
+++ b/src/components/image_cropper/image_cropper.js
@@ -1,5 +1,4 @@
-import Cropper from 'cropperjs'
-import 'cropperjs/dist/cropper.css'
+import 'cropperjs' // This adds all of the cropperjs's components into DOM
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faCircleNotch
@@ -19,19 +18,6 @@ const ImageCropper = {
type: Function,
required: true
},
- cropperOptions: {
- type: Object,
- default () {
- return {
- aspectRatio: 1,
- autoCropArea: 1,
- viewMode: 1,
- movable: false,
- zoomable: false,
- guides: false
- }
- }
- },
mimes: {
type: String,
default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon'
@@ -48,7 +34,6 @@ const ImageCropper = {
},
data () {
return {
- cropper: undefined,
dataUrl: undefined,
filename: undefined,
submitting: false
@@ -67,27 +52,30 @@ const ImageCropper = {
},
methods: {
destroy () {
- if (this.cropper) {
- this.cropper.destroy()
- }
this.$refs.input.value = ''
this.dataUrl = undefined
this.$emit('close')
},
submit (cropping = true) {
this.submitting = true
- this.submitHandler(cropping && this.cropper, this.file)
- .then(() => this.destroy())
- .finally(() => {
- this.submitting = false
- })
+
+ let cropperPromise
+ if (cropping) {
+ cropperPromise = this.$refs.cropperSelection.$toCanvas()
+ } else {
+ cropperPromise = Promise.resolve()
+ }
+ cropperPromise.then(canvas => {
+ this.submitHandler(canvas, this.file)
+ .then(() => this.destroy())
+ .finally(() => {
+ this.submitting = false
+ })
+ })
},
pickImage () {
this.$refs.input.click()
},
- createCropper () {
- this.cropper = new Cropper(this.$refs.img, this.cropperOptions)
- },
getTriggerDOM () {
return typeof this.trigger === 'object' ? this.trigger : document.querySelector(this.trigger)
},
@@ -103,6 +91,29 @@ const ImageCropper = {
reader.readAsDataURL(this.file)
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 () {
diff --git a/src/components/image_cropper/image_cropper.vue b/src/components/image_cropper/image_cropper.vue
index 8647ed4d7..6d11ad4ec 100644
--- a/src/components/image_cropper/image_cropper.vue
+++ b/src/components/image_cropper/image_cropper.vue
@@ -1,14 +1,43 @@
<template>
<div class="image-cropper">
<div v-if="dataUrl">
- <div class="image-cropper-image-container">
- <img
- ref="img"
+ <cropper-canvas
+ background
+ class="image-cropper-canvas"
+ ref="cropperCanvas"
+ height="25em"
+ >
+ <cropper-image
:src="dataUrl"
- alt=""
- @load.stop="createCropper"
+ 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"
>
- </div>
+ <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">
<button
class="button-default btn"
@@ -55,20 +84,18 @@
display: none;
}
- &-image-container {
- position: relative;
-
- img {
- display: block;
- max-width: 100%;
- }
+ &-canvas {
+ height: 25em;
+ width: 25em;
}
&-buttons-wrapper {
- margin-top: 10px;
+ display: grid;
+ grid-gap: 0.5em;
+ grid-template-columns: 1fr 1fr 1fr;
button {
- margin-top: 5px;
+ margin-top: 1em;
}
}
}
diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js
index 6b3ab2615..a549a8705 100644
--- a/src/components/settings_modal/tabs/profile_tab.js
+++ b/src/components/settings_modal/tabs/profile_tab.js
@@ -216,7 +216,7 @@ const ProfileTab = {
this.submitBackground('')
}
},
- submitAvatar (cropper, file) {
+ submitAvatar (canvas, file) {
const that = this
return new Promise((resolve, reject) => {
function updateAvatar (avatar, avatarName) {
@@ -232,8 +232,8 @@ const ProfileTab = {
})
}
- if (cropper) {
- cropper.getCroppedCanvas().toBlob((data) => updateAvatar(data, file.name), file.type)
+ if (canvas) {
+ canvas.toBlob((data) => updateAvatar(data, file.name), file.type)
} else {
updateAvatar(file, file.name)
}
diff --git a/vite.config.js b/vite.config.js
index 0d50e6fe4..429fd0686 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -97,6 +97,9 @@ export default defineConfig(async ({ mode, command }) => {
if (tag === 'pinch-zoom') {
return true
}
+ if (tag.startsWith('cropper-')) {
+ return true
+ }
return false
}
}
diff --git a/yarn.lock b/yarn.lock
index 664ed5c27..8f11d7fc4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1004,6 +1004,105 @@
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
+"@cropper/element-canvas@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-canvas/-/element-canvas-2.0.0.tgz#d41f47cf6fd293e6bcb78a39956d9bed24036c69"
+ integrity sha512-GPtGJgSm92crJhhhwUsaMw3rz2KfJWWSz7kRAlufFEV/EHTP5+6r6/Z1BCGRna830i+Avqbm435XLOtA7PVJwA==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element-crosshair@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-crosshair/-/element-crosshair-2.0.0.tgz#ff4d026a383a5b8517119e6939b0c38a58b839c1"
+ integrity sha512-KfPfyrdeFvUC31Ws7ATtcalWWSaMtrC6bMoCipZhqbUOE7wZoL4ecDSL6BUOZxPa74awZUqfzirCDjHvheBfyw==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element-grid@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-grid/-/element-grid-2.0.0.tgz#a5f3b3a8fb1579517cdd984da767cbe9e855f99e"
+ integrity sha512-i78SQ0IJTLFveKX6P7svkfMYVdgHrQ8ZmmEw8keFy9n1ZVbK+SK0UHK5FNMRNI/gtVhKJOGEnK/zeyjUdj4Iyw==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element-handle@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-handle/-/element-handle-2.0.0.tgz#44d8fa04f78eb7180efece8940cd4a6ab966e7f1"
+ integrity sha512-ZJvW+0MkK9E8xYymGdoruaQn2kwjSHFpNSWinjyq6csuVQiCPxlX5ovAEDldmZ9MWePPtWEi3vLKQOo2Yb0T8g==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element-image@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-image/-/element-image-2.0.0.tgz#9c6a52cb71fe0f62befb7ef3bb9d06561a9f06d0"
+ integrity sha512-9BxiTS/aHRmrjopaFQb9mQQXmx4ruhYHGkDZMVz24AXpMFjUY6OpqrWse/WjzD9tfhMFvEdu17b3VAekcAgpeg==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/element-canvas" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element-selection@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-selection/-/element-selection-2.0.0.tgz#8b69b310cbb8e6eb15a63d077eae052b332f01c9"
+ integrity sha512-ensNnbIfJsJ8bhbJTH/RXtk2URFvTOO4TvfRk461n2FPEC588D7rwBmUJxQg74IiTi4y1JbCI+6j+4LyzYBLCQ==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/element-canvas" "^2.0.0"
+ "@cropper/element-image" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element-shade@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-shade/-/element-shade-2.0.0.tgz#ddfcf69c5d4db20b6beae8cbfab82e69218e4a6d"
+ integrity sha512-jv/2bbNZnhU4W+T4G0c8ADocLIZvQFTXgCf2RFDNhI5UVxurzWBnDdb8Mx8LnVplnkTqO+xUmHZYve0CwgWo+Q==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/element-canvas" "^2.0.0"
+ "@cropper/element-selection" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element-viewer@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element-viewer/-/element-viewer-2.0.0.tgz#a2b67af726ee0eb6c7aa86ebb4878a051a1344d9"
+ integrity sha512-zY+3VRN5TvpM8twlphYtXw0tzJL2VgzeK7ufhL1BixVqOdRxwP13TprYIhqwGt9EW/SyJZUiaIu396T89kRX8A==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/element-canvas" "^2.0.0"
+ "@cropper/element-image" "^2.0.0"
+ "@cropper/element-selection" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/element@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/element/-/element-2.0.0.tgz#5eb636842aa47468de451dfab0987ef3fd783808"
+ integrity sha512-lsthn0nQq73GExUE7Mg/ss6Q3RXADGDv055hxoLFwvl/wGHgy6ZkYlfLZ/VmgBHC6jDK5IgPBFnqrPqlXWSGBA==
+ dependencies:
+ "@cropper/utils" "^2.0.0"
+
+"@cropper/elements@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/elements/-/elements-2.0.0.tgz#48782beb470c313ee964ba26ea5f163455d2f380"
+ integrity sha512-PQkPo1nUjxLFUQuHYu+6atfHxpX9B41Xribao6wpvmvmNIFML6LQdNqqWYb6LyM7ujsu71CZdBiMT5oetjJVoQ==
+ dependencies:
+ "@cropper/element" "^2.0.0"
+ "@cropper/element-canvas" "^2.0.0"
+ "@cropper/element-crosshair" "^2.0.0"
+ "@cropper/element-grid" "^2.0.0"
+ "@cropper/element-handle" "^2.0.0"
+ "@cropper/element-image" "^2.0.0"
+ "@cropper/element-selection" "^2.0.0"
+ "@cropper/element-shade" "^2.0.0"
+ "@cropper/element-viewer" "^2.0.0"
+
+"@cropper/utils@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@cropper/utils/-/utils-2.0.0.tgz#735873696e15073405ceadb9423507508d738103"
+ integrity sha512-cprLYr+7kK3faGgoOsTW9gIn5sefDr2KwOmgyjzIXk+8PLpW8FgFKEg5FoWfRD5zMAmkCBuX6rGKDK3VdUEGrg==
+
"@csstools/color-helpers@^5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.0.2.tgz#82592c9a7c2b83c293d9161894e2a6471feb97b8"
@@ -3147,10 +3246,13 @@ crc32-stream@^4.0.2:
crc-32 "^1.2.0"
readable-stream "^3.4.0"
-cropperjs@1.6.2:
- version "1.6.2"
- resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.6.2.tgz#d1a5d627d880581cca41b7901f06923500e4201b"
- integrity sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==
+cropperjs@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-2.0.0.tgz#0dc6187a66a27e8f6de1e7320c92997dbacc854b"
+ integrity sha512-TO2j0Qre01kPHbow4FuTrbdEB4jTmGRySxW49jyEIqlJZuEBfrvCTT0vC3eRB2WBXudDfKi1Onako6DKWKxeAQ==
+ dependencies:
+ "@cropper/elements" "^2.0.0"
+ "@cropper/utils" "^2.0.0"
cross-spawn@7.0.6, cross-spawn@^7.0.0, cross-spawn@^7.0.6:
version "7.0.6"

File Metadata

Mime Type
text/x-diff
Expires
Fri, Apr 4, 3:18 AM (8 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
85087
Default Alt Text
(13 KB)

Event Timeline