gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import {showElem, type DOMEvent} from '../../utils/dom.ts';
  2. type CropperOpts = {
  3. container: HTMLElement,
  4. imageSource: HTMLImageElement,
  5. fileInput: HTMLInputElement,
  6. };
  7. async function initCompCropper({container, fileInput, imageSource}: CropperOpts) {
  8. const {default: Cropper} = await import(/* webpackChunkName: "cropperjs" */'cropperjs');
  9. let currentFileName = '';
  10. let currentFileLastModified = 0;
  11. const cropper = new Cropper(imageSource, {
  12. aspectRatio: 1,
  13. viewMode: 2,
  14. autoCrop: false,
  15. crop() {
  16. const canvas = cropper.getCroppedCanvas();
  17. canvas.toBlob((blob) => {
  18. const croppedFileName = currentFileName.replace(/\.[^.]{3,4}$/, '.png');
  19. const croppedFile = new File([blob], croppedFileName, {type: 'image/png', lastModified: currentFileLastModified});
  20. const dataTransfer = new DataTransfer();
  21. dataTransfer.items.add(croppedFile);
  22. fileInput.files = dataTransfer.files;
  23. });
  24. },
  25. });
  26. fileInput.addEventListener('input', (e: DOMEvent<Event, HTMLInputElement>) => {
  27. const files = e.target.files;
  28. if (files?.length > 0) {
  29. currentFileName = files[0].name;
  30. currentFileLastModified = files[0].lastModified;
  31. const fileURL = URL.createObjectURL(files[0]);
  32. imageSource.src = fileURL;
  33. cropper.replace(fileURL);
  34. showElem(container);
  35. }
  36. });
  37. }
  38. export async function initAvatarUploaderWithCropper(fileInput: HTMLInputElement) {
  39. const panel = fileInput.nextElementSibling as HTMLElement;
  40. if (!panel?.matches('.cropper-panel')) throw new Error('Missing cropper panel for avatar uploader');
  41. const imageSource = panel.querySelector<HTMLImageElement>('.cropper-source');
  42. await initCompCropper({container: panel, fileInput, imageSource});
  43. }