code optimization

This commit is contained in:
Kerwin Bryant 2024-11-20 08:12:55 +00:00
parent c71520088d
commit bfdb076952
4 changed files with 57 additions and 40 deletions

View File

@ -763,6 +763,7 @@ uploaded_avatar_not_a_image = The uploaded file is not an image.
uploaded_avatar_is_too_big = The uploaded file size (%d KiB) exceeds the maximum size (%d KiB). uploaded_avatar_is_too_big = The uploaded file size (%d KiB) exceeds the maximum size (%d KiB).
update_avatar_success = Your avatar has been updated. update_avatar_success = Your avatar has been updated.
update_user_avatar_success = The user's avatar has been updated. update_user_avatar_success = The user's avatar has been updated.
cropper_prompt = Note: The saved image format after cropping is unified as JPEG.
change_password = Update Password change_password = Update Password
old_password = Current Password old_password = Current Password

View File

@ -127,17 +127,20 @@
<input id="new-avatar" name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp"> <input id="new-avatar" name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
</div> </div>
<div class="inline field cropper hidden" id="cropper"> <div class="inline field cropper-panel tw-hidden" id="cropper-panel">
<div class="preview"> <div class="cropper-preview">
<h3>{{ctx.Locale.Tr "preview"}}</h3> <h3>{{ctx.Locale.Tr "preview"}}</h3>
<div> <div>
<img id="result"> <img id="cropper-result">
</div> </div>
</div> </div>
<div class="editor"> <div class="cropper-editor">
<h3>{{ctx.Locale.Tr "edit"}}</h3>
<div> <div>
<img id="image"> <h3>{{ctx.Locale.Tr "edit"}}</h3>
<span>{{ctx.Locale.Tr "settings.cropper_prompt"}}</span>
</div>
<div class="cropper-wrapper">
<img class="tw-hidden" id="cropper-source">
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,22 +1,28 @@
@import "cropperjs/dist/cropper.css"; @import "cropperjs/dist/cropper.css";
.cropper { .cropper-panel {
display: flex; display: flex;
column-gap: 10px; column-gap: 10px;
}
.hidden { .cropper-editor {
display: none; flex: 1;
} max-width: 100%;
overflow: hidden;
.cropper-wrapper {
height: 600px;
max-height: 600px;
}
>div {
display: flex;
column-gap: 10px;
}
}
.editor { #cropper-result {
flex: 1; overflow: hidden;
} width: 256px;
height: 256px;
#result { max-width: 256px;
overflow: hidden; max-height: 256px;
width: 256px; }
height: 256px;
max-width: 256px;
max-height: 256px;
} }

View File

@ -1,33 +1,40 @@
import Cropper from 'cropperjs'; import Cropper from 'cropperjs';
import {showElem} from '../../utils/dom.ts';
export function initCompCropper() { export function initCompCropper() {
if (!document.querySelector('#cropper')) { const cropperContainer = document.querySelector('#cropper-panel');
if (!cropperContainer) {
return; return;
} }
let filename; let filename;
const image = document.querySelector('#image'); let cropper;
const result = document.querySelector('#result'); const source = document.querySelector('#cropper-source');
const result = document.querySelector('#cropper-result');
const input = document.querySelector('#new-avatar'); const input = document.querySelector('#new-avatar');
const done = function (url) { const done = function (url) {
image.src = url; source.src = url;
const cropper = new Cropper(image, { if (cropper) {
aspectRatio: 1, cropper.replace(url);
viewMode: 1, } else {
crop() { cropper = new Cropper(source, {
const canvas = cropper.getCroppedCanvas(); aspectRatio: 1,
result.src = canvas.toDataURL(); viewMode: 1,
canvas.toBlob((blob) => { crop() {
const file = new File([blob], filename, {type: 'image/jpeg', lastModified: Date.now()}); const canvas = cropper.getCroppedCanvas();
const container = new DataTransfer(); result.src = canvas.toDataURL();
container.items.add(file); canvas.toBlob((blob) => {
input.files = container.files; const file = new File([blob], filename, {type: 'image/jpeg', lastModified: Date.now()});
}); const container = new DataTransfer();
}, container.items.add(file);
}); input.files = container.files;
document.querySelector('#cropper').classList.remove('hidden'); });
},
});
}
showElem(cropperContainer);
}; };
input.addEventListener('change', (e) => { input.addEventListener('change', (e) => {