Skip to content

Commit 12bfbf7

Browse files
committed
Fixed #31990
1 parent 32456b6 commit 12bfbf7

File tree

7 files changed

+100
-0
lines changed

7 files changed

+100
-0
lines changed

package-lock.json

Lines changed: 7 additions & 0 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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"chartjs-adapter-dayjs-4": "1.0.4",
2222
"chartjs-plugin-zoom": "2.0.1",
2323
"clippie": "4.1.3",
24+
"cropperjs": "1.6.2",
2425
"css-loader": "7.1.2",
2526
"dayjs": "1.11.13",
2627
"dropzone": "6.0.0-beta.2",

templates/user/settings/profile.tmpl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,21 @@
127127
<input id="new-avatar" name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
128128
</div>
129129

130+
<div class="inline field cropper hidden" id="cropper">
131+
<div class="preview">
132+
<h3>预览</h3>
133+
<div>
134+
<img id="result">
135+
</div>
136+
</div>
137+
<div class="editor">
138+
<h3>编辑</h3>
139+
<div>
140+
<img id="image">
141+
</div>
142+
</div>
143+
</div>
144+
130145
<div class="field">
131146
<button class="ui primary button">{{ctx.Locale.Tr "settings.update_avatar"}}</button>
132147
<button class="ui red button link-action" data-url="{{.Link}}/avatar/delete">{{ctx.Locale.Tr "settings.delete_current_avatar"}}</button>

web_src/css/features/cropper.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@import "cropperjs/dist/cropper.css";
2+
3+
.cropper {
4+
display: flex;
5+
column-gap: 10px;
6+
}
7+
8+
.hidden {
9+
display: none;
10+
}
11+
12+
.editor {
13+
flex: 1;
14+
}
15+
16+
#result {
17+
overflow: hidden;
18+
width: 256px;
19+
height: 256px;
20+
max-width: 256px;
21+
max-height: 256px;
22+
}

web_src/css/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
@import "./features/codeeditor.css";
4141
@import "./features/projects.css";
4242
@import "./features/tribute.css";
43+
@import "./features/cropper.css";
4344
@import "./features/console.css";
4445

4546
@import "./markup/content.css";
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import Cropper from 'cropperjs';
2+
3+
export function initCompCropper() {
4+
if (!document.querySelector('#cropper')) {
5+
return;
6+
}
7+
8+
let filename;
9+
const image = document.querySelector('#image');
10+
const result = document.querySelector('#result');
11+
const input = document.querySelector('#new-avatar');
12+
13+
const done = function (url) {
14+
image.src = url;
15+
16+
const cropper = new Cropper(image, {
17+
aspectRatio: 1,
18+
viewMode: 1,
19+
crop() {
20+
const canvas = cropper.getCroppedCanvas();
21+
result.src = canvas.toDataURL();
22+
canvas.toBlob((blob) => {
23+
const file = new File([blob], filename, {type: 'image/jpeg', lastModified: Date.now()});
24+
const container = new DataTransfer();
25+
container.items.add(file);
26+
input.files = container.files;
27+
});
28+
},
29+
});
30+
document.querySelector('#cropper').classList.remove('hidden');
31+
};
32+
33+
input.addEventListener('change', (e) => {
34+
const files = e.target.files;
35+
36+
let reader;
37+
let file;
38+
if (files && files.length > 0) {
39+
file = files[0];
40+
filename = file.name;
41+
if (URL) {
42+
done(URL.createObjectURL(file));
43+
} else if (FileReader) {
44+
reader = new FileReader();
45+
reader.addEventListener('load', () => {
46+
done(reader.result);
47+
});
48+
reader.readAsDataURL(file);
49+
}
50+
}
51+
});
52+
}

web_src/js/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {initRepoRelease, initRepoReleaseNew} from './features/repo-release.ts';
4949
import {initRepoEditor} from './features/repo-editor.ts';
5050
import {initCompSearchUserBox} from './features/comp/SearchUserBox.ts';
5151
import {initInstall} from './features/install.ts';
52+
import {initCompCropper} from './features/comp/Cropper.ts';
5253
import {initCompWebHookEditor} from './features/comp/WebHookEditor.ts';
5354
import {initRepoBranchButton} from './features/repo-branch.ts';
5455
import {initCommonOrganization} from './features/common-organization.ts';
@@ -137,6 +138,7 @@ onDomReady(() => {
137138

138139
initCompSearchUserBox,
139140
initCompWebHookEditor,
141+
initCompCropper,
140142

141143
initInstall,
142144

0 commit comments

Comments
 (0)