|
@@ -0,0 +1,147 @@
|
|
|
+<template>
|
|
|
+ <teleport to="body">
|
|
|
+ <div v-if="store.sheetViewModal" class="dialog-container">
|
|
|
+ <header ref="mouseHandler" class="tw-flex tw-place-content-between">
|
|
|
+ <div class="tw-text-2xl tw-cursor-move">原图</div>
|
|
|
+ <div class="tw-mx-8 tw-flex-grow">
|
|
|
+ <span
|
|
|
+ v-for="(u, index) in dataUrls"
|
|
|
+ :key="index"
|
|
|
+ @click="checkedIndex = index"
|
|
|
+ class="image-index hover:tw-bg-gray-300"
|
|
|
+ :class="checkedIndex === index && 'tw-bg-gray-300'"
|
|
|
+ >{{ index + 1 }}</span
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <a-button shape="circle" @click="store.sheetViewModal = false">
|
|
|
+ <template #icon><CloseOutlined /></template>
|
|
|
+ </a-button>
|
|
|
+ </header>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <div
|
|
|
+ v-for="(url, index) in dataUrls"
|
|
|
+ :key="index"
|
|
|
+ style="display: none"
|
|
|
+ :class="index === checkedIndex && 'show-image'"
|
|
|
+ >
|
|
|
+ <img :src="url" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </teleport>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+import { defineComponent, reactive, ref, watchEffect } from "vue";
|
|
|
+import { CloseOutlined } from "@ant-design/icons-vue";
|
|
|
+import { store } from "@/features/mark/store";
|
|
|
+import { loadImage } from "@/utils/utils";
|
|
|
+import { PictureSlice } from "@/types";
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: "SheetViewModal",
|
|
|
+ components: { CloseOutlined },
|
|
|
+ props: {},
|
|
|
+ emits: ["close"],
|
|
|
+ setup() {
|
|
|
+ const dataUrls: Array<string> = reactive([]);
|
|
|
+ watchEffect(async () => {
|
|
|
+ const urls =
|
|
|
+ store.currentTask?.sheetUrls.map((s) => store.setting.fileServer + s) ??
|
|
|
+ [];
|
|
|
+ const images = [];
|
|
|
+ for (const url of urls) {
|
|
|
+ images.push(await loadImage(url));
|
|
|
+ }
|
|
|
+
|
|
|
+ const sheetConfig = store.setting.sheetConfig;
|
|
|
+
|
|
|
+ for (let i = 0; i < images.length; i++) {
|
|
|
+ if (sheetConfig.length === 0) {
|
|
|
+ dataUrls.push(
|
|
|
+ getDataUrlForSheetConfig(
|
|
|
+ images[i],
|
|
|
+ i % 2 === 0
|
|
|
+ ? [
|
|
|
+ // 通过-1来标记该用默认遮盖规则
|
|
|
+ { i: -1, x: 0, y: 0, w: 0, h: 0 },
|
|
|
+ ]
|
|
|
+ : []
|
|
|
+ )
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ const scs = sheetConfig.filter((s) => s.i - 1 === i);
|
|
|
+ dataUrls.push(getDataUrlForSheetConfig(images[i], scs));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ const checkedIndex = ref(0);
|
|
|
+
|
|
|
+ return { store, dataUrls, checkedIndex };
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+export function getDataUrlForSheetConfig(
|
|
|
+ image: HTMLImageElement,
|
|
|
+ sliceConfigs: Array<PictureSlice>
|
|
|
+) {
|
|
|
+ const canvas = document.createElement("canvas");
|
|
|
+ canvas.width = image.naturalWidth;
|
|
|
+ canvas.height = image.naturalWidth;
|
|
|
+ const ctx = canvas.getContext("2d");
|
|
|
+ if (!ctx) {
|
|
|
+ console.log('canvas.getContext("2d") error');
|
|
|
+ return "null";
|
|
|
+ }
|
|
|
+ // drawImage 画图软件透明色
|
|
|
+ ctx?.drawImage(image, 0, 0);
|
|
|
+
|
|
|
+ ctx.fillStyle = "grey";
|
|
|
+ for (const sc of sliceConfigs) {
|
|
|
+ if (sc.i === -1) {
|
|
|
+ ctx.fillRect(0, 0, image.naturalWidth / 2, image.naturalHeight / 3);
|
|
|
+ } else if (sc.w === 0 && sc.h === 0) {
|
|
|
+ ctx.fillRect(0, 0, image.naturalWidth, image.naturalHeight);
|
|
|
+ } else {
|
|
|
+ ctx.fillRect(sc.x, sc.y, sc.w, sc.h);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const dataurl = canvas.toDataURL();
|
|
|
+
|
|
|
+ return dataurl;
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.dialog-container {
|
|
|
+ /* always top */
|
|
|
+ z-index: 99999;
|
|
|
+ position: absolute;
|
|
|
+ background-color: white;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+}
|
|
|
+header {
|
|
|
+ background-color: #eff3f6;
|
|
|
+}
|
|
|
+.image-index {
|
|
|
+ display: inline-block;
|
|
|
+ border: 1px solid grey;
|
|
|
+ width: 25px;
|
|
|
+ margin-right: 10px;
|
|
|
+ margin-top: 5px;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 5px;
|
|
|
+
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.show-image {
|
|
|
+ display: block !important;
|
|
|
+}
|
|
|
+</style>
|