Skip to content

Commit 4ccc498

Browse files
committed
Upgrade cropperjs to v2
1 parent 6f13331 commit 4ccc498

File tree

4 files changed

+174
-26
lines changed

4 files changed

+174
-26
lines changed

package-lock.json

Lines changed: 129 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"chartjs-adapter-dayjs-4": "1.0.4",
2222
"chartjs-plugin-zoom": "2.2.0",
2323
"clippie": "4.1.5",
24-
"cropperjs": "1.6.2",
24+
"cropperjs": "2.0.0",
2525
"css-loader": "7.1.2",
2626
"dayjs": "1.11.13",
2727
"dropzone": "6.0.0-beta.2",

web_src/css/features/cropper.css

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
@import "cropperjs/dist/cropper.css";
2-
31
.avatar-file-with-cropper + .cropper-panel .cropper-wrapper {
4-
max-width: 400px;
2+
width: 400px;
53
max-height: 400px;
64
}
5+
6+
cropper-canvas {
7+
height: 400px;
8+
}

web_src/js/features/comp/Cropper.ts

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {showElem, type DOMEvent} from '../../utils/dom.ts';
1+
import {CropperCanvas, CropperImage} from 'cropperjs';
2+
import {createElementFromHTML, showElem, type DOMEvent} from '../../utils/dom.ts';
23

34
type CropperOpts = {
45
container: HTMLElement,
@@ -7,33 +8,54 @@ type CropperOpts = {
78
}
89

910
async function initCompCropper({container, fileInput, imageSource}: CropperOpts) {
10-
const {default: Cropper} = await import(/* webpackChunkName: "cropperjs" */'cropperjs');
11+
await import(/* webpackChunkName: "cropperjs" */'cropperjs');
1112
let currentFileName = '';
1213
let currentFileLastModified = 0;
13-
const cropper = new Cropper(imageSource, {
14-
aspectRatio: 1,
15-
viewMode: 2,
16-
autoCrop: false,
17-
crop() {
18-
const canvas = cropper.getCroppedCanvas();
19-
canvas.toBlob((blob) => {
20-
const croppedFileName = currentFileName.replace(/\.[^.]{3,4}$/, '.png');
21-
const croppedFile = new File([blob], croppedFileName, {type: 'image/png', lastModified: currentFileLastModified});
22-
const dataTransfer = new DataTransfer();
23-
dataTransfer.items.add(croppedFile);
24-
fileInput.files = dataTransfer.files;
25-
});
26-
},
14+
15+
const canvasEl = createElementFromHTML<CropperCanvas>(`
16+
<cropper-canvas background>
17+
<cropper-image src="${imageSource.src}" rotatable scalable skewable translatable></cropper-image>
18+
<cropper-shade hidden></cropper-shade>
19+
<cropper-handle action="select" plain></cropper-handle>
20+
<cropper-selection initial-coverage="0.5" initial-aspect-ratio="1" movable resizable>
21+
<cropper-grid role="grid" covered></cropper-grid>
22+
<cropper-crosshair centered></cropper-crosshair>
23+
<cropper-handle action="move" theme-color="#ffffff23"></cropper-handle>
24+
<cropper-handle action="n-resize"></cropper-handle>
25+
<cropper-handle action="e-resize"></cropper-handle>
26+
<cropper-handle action="s-resize"></cropper-handle>
27+
<cropper-handle action="w-resize"></cropper-handle>
28+
<cropper-handle action="ne-resize"></cropper-handle>
29+
<cropper-handle action="nw-resize"></cropper-handle>
30+
<cropper-handle action="se-resize"></cropper-handle>
31+
<cropper-handle action="sw-resize"></cropper-handle>
32+
</cropper-selection>
33+
</cropper-canvas>
34+
`);
35+
36+
const imgEl = canvasEl.querySelector<CropperImage>('cropper-image');
37+
38+
canvasEl.addEventListener('action', async (e) => {
39+
const canvas = await (e.target as CropperCanvas).$toCanvas();
40+
canvas.toBlob((blob) => {
41+
const croppedFileName = currentFileName.replace(/\.[^.]{3,4}$/, '.png');
42+
const croppedFile = new File([blob], croppedFileName, {type: 'image/png', lastModified: currentFileLastModified});
43+
const dataTransfer = new DataTransfer();
44+
dataTransfer.items.add(croppedFile);
45+
fileInput.files = dataTransfer.files;
46+
});
2747
});
2848

49+
imageSource.replaceWith(canvasEl);
50+
2951
fileInput.addEventListener('input', (e: DOMEvent<Event, HTMLInputElement>) => {
3052
const files = e.target.files;
3153
if (files?.length > 0) {
3254
currentFileName = files[0].name;
3355
currentFileLastModified = files[0].lastModified;
3456
const fileURL = URL.createObjectURL(files[0]);
3557
imageSource.src = fileURL;
36-
cropper.replace(fileURL);
58+
imgEl.src = fileURL;
3759
showElem(container);
3860
}
3961
});

0 commit comments

Comments
 (0)