|
@@ -52,7 +52,7 @@ import {
|
|
|
ScenePoint,
|
|
|
scenePoints,
|
|
|
} from "@/store/scene";
|
|
|
-import { copyText, toDegrees } from "@/util";
|
|
|
+import { copyText, toDegrees, getTextBound } from "@/util";
|
|
|
import { ElMessage } from "element-plus";
|
|
|
import saveAs from "@/util/file-serve";
|
|
|
import { DeviceType } from "@/store/device";
|
|
@@ -87,26 +87,90 @@ const panoUrls = computed(() => {
|
|
|
const update = ref(false);
|
|
|
const loading = ref(false);
|
|
|
|
|
|
-const copyGis = async () => {
|
|
|
+const getGis = () => {
|
|
|
const pos = point.value!.pos as number[];
|
|
|
- await copyText(
|
|
|
- `经度:${toDegrees(pos[0])}, 纬度: ${toDegrees(pos[1])}, 高程: ${pos[2]}`
|
|
|
- );
|
|
|
+ return `经度: ${toDegrees(pos[0])}\n纬度: ${toDegrees(pos[1])}\n高程: ${round(
|
|
|
+ pos[2],
|
|
|
+ 4
|
|
|
+ )}`;
|
|
|
+};
|
|
|
+
|
|
|
+const copyGis = async () => {
|
|
|
+ await copyText(getGis());
|
|
|
ElMessage.success("经纬度高程复制成功");
|
|
|
};
|
|
|
|
|
|
-const photo = () => {
|
|
|
+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/jpg", 1));
|
|
|
+ };
|
|
|
+ image.onerror = reject;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const photo = async () => {
|
|
|
loading.value = true;
|
|
|
- setSize(3, 1920, 1080);
|
|
|
- panoDomRef.value!.toBlob(async (blob) => {
|
|
|
- if (blob) {
|
|
|
- await saveAs(blob, `${relics.value?.name}.jpg`);
|
|
|
- ElMessage.success("图片导出成功");
|
|
|
- }
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, 300));
|
|
|
+ const ration = 3;
|
|
|
+ setSize(ration, 1920, 1080);
|
|
|
+ let dataURL = panoDomRef.value.toDataURL("image/jpg", 1);
|
|
|
+ dataURL = await addWatermark(dataURL, ration);
|
|
|
|
|
|
- setSize(devicePixelRatio);
|
|
|
- loading.value = false;
|
|
|
- }, "image/jpg");
|
|
|
+ await saveAs(dataURL, `${relics.value?.name}.jpg`);
|
|
|
+ ElMessage.success("图片导出成功");
|
|
|
+ setSize(devicePixelRatio);
|
|
|
+ loading.value = false;
|
|
|
};
|
|
|
|
|
|
let pano: ReturnType<typeof init>;
|