فهرست منبع

feat: 回传MIMeTYpe

gemercheung 9 ماه پیش
والد
کامیت
a2c62381c6
1فایلهای تغییر یافته به همراه65 افزوده شده و 22 حذف شده
  1. 65 22
      src/view/pano/pano.vue

+ 65 - 22
src/view/pano/pano.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="pano-layout" v-loading="loading" >
+  <div class="pano-layout" v-loading="loading">
     <canvas ref="panoDomRef"></canvas>
     <div class="btns">
       <el-button
@@ -10,14 +10,6 @@
       >
         屏幕拍照
       </el-button>
-      <el-input-number
-        style="margin-right: 20px"
-        v-model="tempRadion"
-        :precision="2"
-        :step="0.01"
-        :min="1"
-        :max="3"
-      />
       <el-button
         size="large"
         style="margin-right: 20px; width: 100px"
@@ -64,15 +56,12 @@ import saveAs from "@/util/file-serve";
 import { DeviceType } from "@/store/device";
 import { initRelics, relics } from "@/store/relics";
 import { noValidPoint } from "../map/install";
-import { addWatermark } from "@/util/image";
 
 type Params = { pid?: string; relicsId?: string } | null;
 const params = computed(() => router.currentRoute.value.params as Params);
 const panoDomRef = ref<HTMLCanvasElement>();
 const destroyFns: (() => void)[] = [];
 const point = ref<ScenePoint>();
-const tempRadion = ref(3.0);
-
 watchEffect(() => {
   if (params.value?.pid) {
     const pid = Number(params.value!.pid);
@@ -91,8 +80,7 @@ watchEffect(() => {
 
 const panoUrls = computed(() => {
   return (
-    point.value &&
-    getPointPano(point.value, point.value.cameraType === DeviceType.CLUNT)
+    point.value && getPointPano(point.value, point.value.cameraType === DeviceType.CLUNT)
   );
 });
 const update = ref(false);
@@ -111,15 +99,73 @@ const copyGis = async () => {
   ElMessage.success("经纬度高程复制成功");
 };
 
+const canvas = document.createElement("canvas");
+// 水印添加函数
+const addWatermark = (imgURL: string, ration: number) => {
+  const ctx = canvas.getContext("2d");
+  const image = new Image();
+  image.src = imgURL;
+
+  return new Promise<string>((resolve, reject) => {
+    image.onload = () => {
+      canvas.width = image.width;
+      canvas.height = image.height;
+      ctx.drawImage(image, 0, 0, image.width, image.height);
+
+      const font = `${ration * 20}px Arial`;
+      const pos = point.value!.pos as number[];
+      const lines = `经度: ${toDegrees(pos[0])}\n纬度: ${toDegrees(pos[1])}`.split("\n");
+      const lineTopPadding = 5 * ration;
+      const lineBounds = lines.map((line) =>
+        getTextBound(line, font, [lineTopPadding, 0])
+      );
+      const bound = lineBounds.reduce(
+        (t, { width, height }) => {
+          t.width = Math.max(t.width, width);
+          t.height += height;
+          return t;
+        },
+        { width: 0, height: 0 }
+      );
+      const padding = 20 * ration;
+      const margin = 80 * ration;
+
+      const position = [
+        image.width - margin - bound.width,
+        image.height - margin - bound.height,
+      ];
+
+      ctx.rect(
+        position[0] - padding,
+        position[1] - padding,
+        bound.width + 2 * padding,
+        bound.height + 2 * padding
+      );
+      ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
+      ctx.fill();
+
+      ctx.font = font;
+      ctx.textBaseline = "top";
+      ctx.fillStyle = "#fff";
+      let itemTop = 0;
+      lines.forEach((line, ndx) => {
+        ctx.fillText(line, position[0], position[1] + itemTop + lineTopPadding);
+        itemTop += lineBounds[ndx].height;
+      });
+      resolve(canvas.toDataURL("image/jpeg", 1));
+    };
+    image.onerror = reject;
+  });
+};
+
 const photo = async () => {
   loading.value = true;
   await new Promise((resolve) => setTimeout(resolve, 300));
-  const ration = tempRadion.value;
-  console.log("ration", ration);
+  const ration = 3;
   setSize(ration, 1920, 1080);
-  let dataURL: Blob | string = panoDomRef.value.toDataURL("image/jpeg", 1);
+  let dataURL = panoDomRef.value.toDataURL("image/jpeg", 1);
   if (!noValidPoint(point.value)) {
-    dataURL = await addWatermark(dataURL, point.value!.pos, ration);
+    dataURL = await addWatermark(dataURL, ration);
   }
 
   await saveAs(dataURL, `${relics.value?.name}.jpg`);
@@ -161,10 +207,7 @@ onMounted(() => {
 
 onUnmounted(() => mergeFuns(...destroyFns)());
 watchEffect(() => {
-  if (
-    router.currentRoute.value.name.toString().includes("pano") &&
-    point.value
-  ) {
+  if (router.currentRoute.value.name.toString().includes("pano") && point.value) {
     setDocTitle(point.value.index.toString() || relics.value.name);
   }
 });