mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-11 09:08:14 +08:00
✨ 实现截图分享深渊数据,其他部分的截图分享待定
This commit is contained in:
45
package-lock.json
generated
45
package-lock.json
generated
@@ -12,6 +12,7 @@
|
|||||||
"@mdi/font": "7.2.96",
|
"@mdi/font": "7.2.96",
|
||||||
"@tauri-apps/api": "^1.3.0",
|
"@tauri-apps/api": "^1.3.0",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"js-md5": "^0.7.3",
|
"js-md5": "^0.7.3",
|
||||||
"pinia": "^2.0.36",
|
"pinia": "^2.0.36",
|
||||||
"pinia-plugin-persistedstate": "^3.1.0",
|
"pinia-plugin-persistedstate": "^3.1.0",
|
||||||
@@ -1029,6 +1030,14 @@
|
|||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/base64id": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/base64id/-/base64id-2.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/base64id/-/base64id-2.0.0.tgz",
|
||||||
@@ -1436,6 +1445,14 @@
|
|||||||
"node": ">=12.22"
|
"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": {
|
"node_modules/css-tree": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz",
|
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz",
|
||||||
@@ -3094,6 +3111,18 @@
|
|||||||
"node": ">=8"
|
"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": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||||
@@ -5536,6 +5565,14 @@
|
|||||||
"@tauri-apps/api": "^1.2.0"
|
"@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": {
|
"node_modules/text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
|
||||||
@@ -5791,6 +5828,14 @@
|
|||||||
"node": ">= 0.4.0"
|
"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": {
|
"node_modules/v8-compile-cache": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
"@mdi/font": "7.2.96",
|
"@mdi/font": "7.2.96",
|
||||||
"@tauri-apps/api": "^1.3.0",
|
"@tauri-apps/api": "^1.3.0",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"js-md5": "^0.7.3",
|
"js-md5": "^0.7.3",
|
||||||
"pinia": "^2.0.36",
|
"pinia": "^2.0.36",
|
||||||
"pinia-plugin-persistedstate": "^3.1.0",
|
"pinia-plugin-persistedstate": "^3.1.0",
|
||||||
|
|||||||
@@ -6,6 +6,10 @@
|
|||||||
第 {{ item.id }} 期
|
第 {{ item.id }} 期
|
||||||
</v-tab>
|
</v-tab>
|
||||||
<div class="ua-tab-bottom">
|
<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-btn class="ua-btn" @click="getAbyssData">
|
||||||
<v-icon>mdi-refresh</v-icon>
|
<v-icon>mdi-refresh</v-icon>
|
||||||
<span>刷新</span>
|
<span>刷新</span>
|
||||||
@@ -14,35 +18,37 @@
|
|||||||
</v-tabs>
|
</v-tabs>
|
||||||
<v-window v-model="userTab" class="ua-window">
|
<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">
|
<v-window-item v-for="item in localAbyss" :key="item.id" :value="item.id" class="ua-window-item">
|
||||||
<div class="uaw-title">
|
<div :ref="getAbyssRef">
|
||||||
<span>挑战回顾【{{ user.gameUid }}】</span>
|
<div class="uaw-title">
|
||||||
<span>更新于 {{ item.updated }}</span>
|
<span>第 {{ item.id }} 期 挑战回顾【{{ user.gameUid }}】</span>
|
||||||
</div>
|
<span>更新于 {{ item.updated }}</span>
|
||||||
<div class="uaw-sub-title">
|
</div>
|
||||||
<img src="/src/assets/icons/arrow-right.svg" alt="character">
|
<div class="uaw-sub-title">
|
||||||
<span>统计周期 {{ item.startTime }} ~ {{ item.endTime }}</span>
|
<img src="/src/assets/icons/arrow-right.svg" alt="character">
|
||||||
</div>
|
<span>统计周期 {{ item.startTime }} ~ {{ item.endTime }}</span>
|
||||||
<div class="uaw-o-box">
|
</div>
|
||||||
<TuaOverview title="战斗次数" :val-text="item.totalBattleTimes" />
|
<div class="uaw-o-box">
|
||||||
<TuaOverview title="获得渊星" :val-text="item.totalStar" />
|
<TuaOverview title="战斗次数" :val-text="item.totalBattleTimes" />
|
||||||
<TuaOverview title="最深抵达" :val-text="item.maxFloor" />
|
<TuaOverview title="获得渊星" :val-text="item.totalStar" />
|
||||||
</div>
|
<TuaOverview title="最深抵达" :val-text="item.maxFloor" />
|
||||||
<div class="uaw-o-box">
|
</div>
|
||||||
<TuaOverview title="最多击破" :val-icons="item.defeatRank" />
|
<div class="uaw-o-box">
|
||||||
<TuaOverview title="最多承伤" :val-icons="item.takeDamageRank" />
|
<TuaOverview title="最多击破" :val-icons="item.defeatRank" />
|
||||||
<TuaOverview title="最强一击" :val-icons="item.damageRank" />
|
<TuaOverview title="最多承伤" :val-icons="item.takeDamageRank" />
|
||||||
</div>
|
<TuaOverview title="最强一击" :val-icons="item.damageRank" />
|
||||||
<div class="uaw-o-box">
|
</div>
|
||||||
<TuaOverview title="元素战技" :val-icons="item.normalSkillRank" />
|
<div class="uaw-o-box">
|
||||||
<TuaOverview title="出战次数" :val-icons="item.revealRank" :icon-num="4" />
|
<TuaOverview title="元素战技" :val-icons="item.normalSkillRank" />
|
||||||
<TuaOverview title="元素爆发" :val-icons="item.energySkillRank" />
|
<TuaOverview title="出战次数" :val-icons="item.revealRank" :icon-num="4" />
|
||||||
</div>
|
<TuaOverview title="元素爆发" :val-icons="item.energySkillRank" />
|
||||||
<div class="uaw-sub-title">
|
</div>
|
||||||
<img src="/src/assets/icons/arrow-right.svg" alt="character">
|
<div class="uaw-sub-title">
|
||||||
<span>详情</span>
|
<img src="/src/assets/icons/arrow-right.svg" alt="character">
|
||||||
</div>
|
<span>详情</span>
|
||||||
<div class="uaw-d-box">
|
</div>
|
||||||
<TuaDetail v-for="floor in JSON.parse(item.floors) as TGApp.Sqlite.Abyss.Floor[]" :model-value="floor" />
|
<div class="uaw-d-box">
|
||||||
|
<TuaDetail v-for="floor in JSON.parse(item.floors) as TGApp.Sqlite.Abyss.Floor[]" :model-value="floor" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
</v-window>
|
</v-window>
|
||||||
@@ -63,6 +69,8 @@ import { useUserStore } from "../../store/modules/user";
|
|||||||
// utils
|
// utils
|
||||||
import TGRequest from "../../web/request/TGRequest";
|
import TGRequest from "../../web/request/TGRequest";
|
||||||
import TGSqlite from "../../plugins/Sqlite";
|
import TGSqlite from "../../plugins/Sqlite";
|
||||||
|
import html2canvas from "html2canvas";
|
||||||
|
import { saveCanvasImg } from "../../utils/saveImg";
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -79,6 +87,7 @@ const user = computed(() => userStore.getCurAccount());
|
|||||||
const localAbyss = ref([] as TGApp.Sqlite.Abyss.SingleTable[]);
|
const localAbyss = ref([] as TGApp.Sqlite.Abyss.SingleTable[]);
|
||||||
const localAbyssID = ref([] as number[]);
|
const localAbyssID = ref([] as number[]);
|
||||||
const curAbyss = ref({} as TGApp.Sqlite.Abyss.SingleTable);
|
const curAbyss = ref({} as TGApp.Sqlite.Abyss.SingleTable);
|
||||||
|
const abyssRef = ref(null as unknown as HTMLElement);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
loadingTitle.value = "正在加载深渊数据";
|
loadingTitle.value = "正在加载深渊数据";
|
||||||
@@ -120,6 +129,39 @@ async function getAbyssData (): Promise<void> {
|
|||||||
function toAbyss (id: number): void {
|
function toAbyss (id: number): void {
|
||||||
curAbyss.value = localAbyss.value.find((item) => item.id === id)!;
|
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>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.ua-box {
|
.ua-box {
|
||||||
|
|||||||
30
src/utils/saveImg.ts
Normal file
30
src/utils/saveImg.ts
Normal 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
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user