code optimization

pull/32565/head
Kerwin Bryant 3 months ago
parent c71520088d
commit 8863e9275f
  1. 1
      options/locale/locale_en-US.ini
  2. 15
      templates/user/settings/profile.tmpl
  3. 36
      web_src/css/features/cropper.css
  4. 45
      web_src/js/features/comp/Cropper.ts

@ -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

@ -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>

@ -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 {
display: none;
}
.editor { .cropper-editor {
flex: 1; flex: 1;
} max-width: 100%;
overflow: hidden;
.cropper-wrapper {
height: 600px;
max-height: 600px;
}
>div {
display: flex;
column-gap: 10px;
}
}
#result { #cropper-result {
overflow: hidden; overflow: hidden;
width: 256px; width: 256px;
height: 256px; height: 256px;
max-width: 256px; max-width: 256px;
max-height: 256px; max-height: 256px;
}
} }

@ -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) => {

Loading…
Cancel
Save