实现截图分享深渊数据,其他部分的截图分享待定

This commit is contained in:
BTMuli
2023-06-09 23:37:02 +08:00
parent 03dfdc26e1
commit f74c803b5d
4 changed files with 147 additions and 29 deletions

45
package-lock.json generated
View File

@@ -12,6 +12,7 @@
"@mdi/font": "7.2.96",
"@tauri-apps/api": "^1.3.0",
"clipboard": "^2.0.11",
"html2canvas": "^1.4.1",
"js-md5": "^0.7.3",
"pinia": "^2.0.36",
"pinia-plugin-persistedstate": "^3.1.0",
@@ -1029,6 +1030,14 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/base64id/-/base64id-2.0.0.tgz",
@@ -1436,6 +1445,14 @@
"node": ">=12.22"
}
},
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz",
@@ -3094,6 +3111,18 @@
"node": ">=8"
}
},
"node_modules/html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"dependencies": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-8.0.2.tgz",
@@ -5536,6 +5565,14 @@
"@tauri-apps/api": "^1.2.0"
}
},
"node_modules/text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
@@ -5791,6 +5828,14 @@
"node": ">= 0.4.0"
}
},
"node_modules/utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"dependencies": {
"base64-arraybuffer": "^1.0.2"
}
},
"node_modules/v8-compile-cache": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",

View File

@@ -45,6 +45,7 @@
"@mdi/font": "7.2.96",
"@tauri-apps/api": "^1.3.0",
"clipboard": "^2.0.11",
"html2canvas": "^1.4.1",
"js-md5": "^0.7.3",
"pinia": "^2.0.36",
"pinia-plugin-persistedstate": "^3.1.0",

View File

@@ -6,6 +6,10 @@
{{ item.id }}
</v-tab>
<div class="ua-tab-bottom">
<v-btn class="ua-btn" @click="shareAbyss">
<v-icon>mdi-share</v-icon>
<span>分享</span>
</v-btn>
<v-btn class="ua-btn" @click="getAbyssData">
<v-icon>mdi-refresh</v-icon>
<span>刷新</span>
@@ -14,8 +18,9 @@
</v-tabs>
<v-window v-model="userTab" class="ua-window">
<v-window-item v-for="item in localAbyss" :key="item.id" :value="item.id" class="ua-window-item">
<div :ref="getAbyssRef">
<div class="uaw-title">
<span>挑战回顾{{ user.gameUid }}</span>
<span> {{ item.id }} 挑战回顾{{ user.gameUid }}</span>
<span>更新于 {{ item.updated }}</span>
</div>
<div class="uaw-sub-title">
@@ -44,6 +49,7 @@
<div class="uaw-d-box">
<TuaDetail v-for="floor in JSON.parse(item.floors) as TGApp.Sqlite.Abyss.Floor[]" :model-value="floor" />
</div>
</div>
</v-window-item>
</v-window>
<div v-show="localAbyssID.length === 0" class="user-empty">
@@ -63,6 +69,8 @@ import { useUserStore } from "../../store/modules/user";
// utils
import TGRequest from "../../web/request/TGRequest";
import TGSqlite from "../../plugins/Sqlite";
import html2canvas from "html2canvas";
import { saveCanvasImg } from "../../utils/saveImg";
// store
const userStore = useUserStore();
@@ -79,6 +87,7 @@ const user = computed(() => userStore.getCurAccount());
const localAbyss = ref([] as TGApp.Sqlite.Abyss.SingleTable[]);
const localAbyssID = ref([] as number[]);
const curAbyss = ref({} as TGApp.Sqlite.Abyss.SingleTable);
const abyssRef = ref(null as unknown as HTMLElement);
onMounted(async () => {
loadingTitle.value = "正在加载深渊数据";
@@ -120,6 +129,39 @@ async function getAbyssData (): Promise<void> {
function toAbyss (id: number): void {
curAbyss.value = localAbyss.value.find((item) => item.id === id)!;
}
function getAbyssRef (el: HTMLElement): void {
abyssRef.value = el;
}
async function shareAbyss (): Promise<void> {
const canvas = document.createElement("canvas");
// 获取 dom 宽高
const width = abyssRef.value.scrollWidth + 50;
const height = abyssRef.value.scrollHeight + 50;
// 设置 canvas 宽高
canvas.width = width * 1.2;
canvas.height = height * 1.2;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
// 图片压缩
canvas.getContext("2d")!.scale(1.2, 1.2);
// 设置 html2canvas 参数
const options = {
backgroundColor: "#ece5d8",
windowHeight: height,
width,
height,
useCORS: true,
canvas,
// 因为有放大,所以需要计算偏移量
x: -25,
y: -25,
};
const canvasData = await html2canvas(abyssRef.value, options);
const fileName = `深渊${curAbyss.value.id}-${user.value.gameUid}-${new Date().getTime()}.png`;
await saveCanvasImg(canvasData, fileName);
}
</script>
<style lang="css" scoped>
.ua-box {

30
src/utils/saveImg.ts Normal file
View File

@@ -0,0 +1,30 @@
/**
* @file utils saveImg.ts
* @description 用于保存图片的工具模块
* @author BTMuli <bt-muli@outlook.com>
* @since Alpha v0.2.0
*/
// tauri
import { dialog, fs } from "@tauri-apps/api";
/**
* @description 保存图片-canvas
* @since Alpha v0.2.0
* @param {HTMLCanvasElement} canvas - canvas元素
* @param {string} filename - 文件名
* @returns {Promise<void>} 无返回值
*/
export async function saveCanvasImg(canvas: HTMLCanvasElement, filename: string): Promise<void> {
const buffer = new Uint8Array(atob(canvas.toDataURL("image/png").split(",")[1]).split("").map((item) => item.charCodeAt(0)));
await dialog.save({
defaultPath: filename,
filters: [{ name: "图片", extensions: ["png"] }]
}).then(async (res) => {
if (res === null) return;
await fs.writeBinaryFile({
path: res,
contents: buffer
});
});
}