MarkBody.vue 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <template>
  2. <div class="mark-body-container" ref="container">
  3. <div :style="{ width: answerPaperScale }">
  4. <template v-for="(item, index) in imageWithStyles" :key="index">
  5. <img :src="item.url" />
  6. </template>
  7. <!-- style="border: 1px solid black; background: black" -->
  8. </div>
  9. </div>
  10. </template>
  11. <script lang="ts">
  12. import { computed, defineComponent, reactive, ref, watchEffect } from "vue";
  13. import { store } from "./store";
  14. import filters from "@/filters";
  15. interface ImageStyle {
  16. width: number; // or string?
  17. }
  18. export default defineComponent({
  19. name: "MarkBody",
  20. setup() {
  21. const container = ref(null);
  22. const imageWithStyles: Array<any> = reactive([]);
  23. watchEffect(async () => {
  24. if (store.currentTask?.sliceConfig) {
  25. async function loadImage(url: string): Promise<HTMLImageElement> {
  26. return new Promise((resolve, reject) => {
  27. const image = new Image();
  28. image.setAttribute("crossorigin", "anonymous");
  29. image.src = url;
  30. image.onload = () => resolve(image);
  31. image.onerror = reject;
  32. });
  33. }
  34. for (const url of store.currentTask.sliceUrls) {
  35. await loadImage(filters.toCompleteUrl(url));
  36. }
  37. let zIndex = 500;
  38. for (const sliceConfig of store.currentTask.sliceConfig) {
  39. const url = filters.toCompleteUrl(
  40. store.currentTask.sliceUrls[sliceConfig.i - 1]
  41. );
  42. const image = await loadImage(url);
  43. const div: HTMLDivElement = container.value;
  44. const maxSliceWidth = Math.max(
  45. ...store.currentTask.sliceConfig.map((v) => v.w)
  46. );
  47. const canvas = document.createElement("canvas");
  48. canvas.width = Math.max(sliceConfig.w, maxSliceWidth);
  49. canvas.height = sliceConfig.h;
  50. const ctx = canvas.getContext("2d");
  51. ctx?.drawImage(
  52. image,
  53. sliceConfig.x,
  54. sliceConfig.y,
  55. sliceConfig.w,
  56. sliceConfig.h,
  57. 0,
  58. 0,
  59. sliceConfig.w,
  60. sliceConfig.h
  61. );
  62. // console.log(image, canvas.height, sliceConfig, ctx);
  63. // console.log(canvas.toDataURL());
  64. imageWithStyles.push({
  65. url: canvas.toDataURL(),
  66. });
  67. }
  68. }
  69. });
  70. const answerPaperScale = computed(() => {
  71. const scale = store.setting.uiSetting["answer.paper.scale"] || 1;
  72. return scale * 100 + "%";
  73. });
  74. return { container, store, imageWithStyles, answerPaperScale };
  75. },
  76. });
  77. </script>
  78. <style scoped>
  79. .mark-body-container {
  80. height: calc(100vh - 21px);
  81. overflow: scroll;
  82. }
  83. .mark-body-container img {
  84. width: 100%;
  85. }
  86. </style>