Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F194566
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment