From 3429b36502fb945e738dffbdddb8da0b687a9102 Mon Sep 17 00:00:00 2001 From: dog Date: Mon, 22 Jan 2024 14:06:32 +0300 Subject: [PATCH] add cropperjs --- package-lock.json | 6 + package.json | 1 + .../_shared/ImageCropper/ImageCropper.tsx | 106 +++++++++++++++++- src/components/_shared/ImageCropper/index.tsx | 106 +----------------- 4 files changed, 113 insertions(+), 106 deletions(-) diff --git a/package-lock.json b/package-lock.json index f25bccad..e6790003 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.8.0", "license": "MIT", "dependencies": { + "cropperjs": "1.6.1", "form-data": "4.0.0", "i18next": "22.4.15", "i18next-icu": "2.3.0", @@ -7865,6 +7866,11 @@ "dev": true, "peer": true }, + "node_modules/cropperjs": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.6.1.tgz", + "integrity": "sha512-F4wsi+XkDHCOMrHMYjrTEE4QBOrsHHN5/2VsVAaRq8P7E5z7xQpT75S+f/9WikmBEailas3+yo+6zPIomW+NOA==" + }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", diff --git a/package.json b/package.json index 1c9101ed..9a635502 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "typecheck:watch": "tsc --noEmit --watch" }, "dependencies": { + "cropperjs": "1.6.1", "form-data": "4.0.0", "i18next": "22.4.15", "i18next-icu": "2.3.0", diff --git a/src/components/_shared/ImageCropper/ImageCropper.tsx b/src/components/_shared/ImageCropper/ImageCropper.tsx index 08e025d1..99d86faf 100644 --- a/src/components/_shared/ImageCropper/ImageCropper.tsx +++ b/src/components/_shared/ImageCropper/ImageCropper.tsx @@ -1 +1,105 @@ -export { ImageCropper } from './ImageCropper' +import { createSignal, Show } from 'solid-js' +import { createStore } from 'solid-js/store' +import Cropper from 'cropperjs' + +import styles from './ImageCropper.module.scss' + +export const ImageCropper = (props) => { + let cropImage + const [state, setState] = createStore({ + error: null, + loading: false, + file: {}, + croppedImage: null, + }), + [dropZoneActive, setDropZoneActive] = createSignal(false), + [uploading, setUploading] = createSignal(false), + [preview, setPreview] = createSignal(null), + [cropper, setCropper] = createSignal(null), + noPropagate = (e) => { + e.preventDefault() + }, + uploadFile = async (file) => { + if (!file) return + setUploading(true) + setState('loading', true) + setState('file', file) + try { + const reader = new FileReader() + reader.onload = (e) => { + setPreview(e.target.result) + setCropper( + new Cropper(cropImage, { + aspectRatio: 1 / 1, + viewMode: 1, + rotatable: false, + }), + ) + } + reader.readAsDataURL(file) + } catch (e) { + console.error('upload failed', e) + const message = e instanceof Error ? e.message : String(e) + setState('error', message) + } + setState('loading', false) + setUploading(false) + }, + handleFileDrop = async (e) => { + e.preventDefault() + setDropZoneActive(false) + uploadFile(e.dataTransfer.files[0]) + }, + handleFileInput = async (e) => { + e.preventDefault() + uploadFile(e.currentTarget.files[0]) + } + + return ( + <> + +
+
+ cropper +
+ +
+
+ +
+
(uploading() ? undefined : setDropZoneActive(true))} + onDragLeave={() => setDropZoneActive(false)} + onDragOver={noPropagate} + onDrop={(event) => (uploading() ? noPropagate(event) : handleFileDrop(event))} + > +
upload
+ +
+
+ + + + ) +} diff --git a/src/components/_shared/ImageCropper/index.tsx b/src/components/_shared/ImageCropper/index.tsx index a04b027b..08e025d1 100644 --- a/src/components/_shared/ImageCropper/index.tsx +++ b/src/components/_shared/ImageCropper/index.tsx @@ -1,105 +1 @@ -import { createSignal, Show } from 'solid-js' -import { createStore } from 'solid-js/store' -import Cropper from 'cropperjs' - -import styles from './ImageCropper.module.scss' - -export default function ImageCropper(props) { - let cropImage - const [state, setState] = createStore({ - error: null, - loading: false, - file: {}, - croppedImage: null, - }), - [dropZoneActive, setDropZoneActive] = createSignal(false), - [uploading, setUploading] = createSignal(false), - [preview, setPreview] = createSignal(null), - [cropper, setCropper] = createSignal(null), - noPropagate = (e) => { - e.preventDefault() - }, - uploadFile = async (file) => { - if (!file) return - setUploading(true) - setState('loading', true) - setState('file', file) - try { - const reader = new FileReader() - reader.onload = (e) => { - setPreview(e.target.result) - setCropper( - new Cropper(cropImage, { - aspectRatio: 1 / 1, - viewMode: 1, - rotatable: false, - }), - ) - } - reader.readAsDataURL(file) - } catch (e) { - console.error('upload failed', e) - const message = e instanceof Error ? e.message : String(e) - setState('error', message) - } - setState('loading', false) - setUploading(false) - }, - handleFileDrop = async (e) => { - e.preventDefault() - setDropZoneActive(false) - uploadFile(e.dataTransfer.files[0]) - }, - handleFileInput = async (e) => { - e.preventDefault() - uploadFile(e.currentTarget.files[0]) - } - - return ( - <> - -
-
- cropper -
- -
-
- -
-
(uploading() ? undefined : setDropZoneActive(true))} - onDragLeave={() => setDropZoneActive(false)} - onDragOver={noPropagate} - onDrop={(event) => (uploading() ? noPropagate(event) : handleFileDrop(event))} - > -
upload
- -
-
- - - - ) -} +export { ImageCropper } from './ImageCropper'