Vue3 + dom-to-image 实现高质量截图复制与下载功能
📋 功能概述
基于 Vue3 和 dom-to-image 库实现的网页元素截图功能,支持:
- 🖼️ 高清截图生成(2倍分辨率)
- 📋 一键复制到剪贴板
- 💾 直接下载保存
- 🎨 自定义样式和背景色
⚠️ 重要提示
dom-to-image 版本必须锁定为 2.6.0,其他版本存在已知 bug 问题。
🚀 使用方法
- 调用
generateImgUrl()
生成截图 - 调用
handleScreenshot('copy')
复制图片 - 调用
handleScreenshot('download')
下载图片
🔧 技术特性
- 高分辨率输出:使用 2 倍缩放确保图片清晰度
- 字体抗锯齿:优化文字渲染效果
- 浏览器兼容性检测:自动检测 Clipboard API 支持
- 错误处理:完善的异常捕获和用户提示
vue
<template>
<view class="share-box">
<!-- 分享内容 -->
</view>
</template>
<script setup lang="ts">
import { ref } from "vue";
import domtoimage from "dom-to-image";
const imgUrl = ref("");
/**
* 生成高质量截图
* 使用2倍分辨率和抗锯齿优化
*/
const generateImgUrl = async () => {
// 等待 UI 完全渲染
await new Promise((resolve) => setTimeout(resolve, 100));
// 获取目标元素
const element = document.querySelector(".share-box") as HTMLElement;
if (!element) {
console.error("未找到目标元素");
return;
}
const dataUrl = await domtoimage.toPng(element, {
width: element.offsetWidth * 2, // 2倍宽度提升清晰度
height: element.offsetHeight * 2, // 2倍高度提升清晰度
style: {
transform: "scale(2)", // 2倍缩放
"transform-origin": "top left",
"font-smooth": "always", // 强制抗锯齿
"-webkit-font-smoothing": "antialiased",
},
cacheBust: true, // 避免缓存问题
quality: 1, // 最高质量(仅 toJpeg 有效)
bgcolor: "#ffffff", // 白色背景
});
imgUrl.value = dataUrl;
console.log("截图生成成功", imgUrl.value);
};
/**
* 处理截图操作
* @param val - 操作类型:'copy' 复制 | 'download' 下载
*/
const handleScreenshot = async (val: string) => {
if (val === "copy") {
await copyImage();
} else {
downLoadImage();
}
};
/**
* 复制图片到剪贴板
* 支持现代浏览器的 Clipboard API
*/
const copyImage = async () => {
// 检查图片是否已生成
if (!imgUrl.value) {
console.warn("请先生成图片");
return;
}
try {
// 将 base64 转换为 Blob 对象
const response = await fetch(imgUrl.value);
const blob = await response.blob();
// 检查浏览器兼容性
if (navigator.clipboard && window.ClipboardItem) {
// 创建剪贴板项目
const clipboardItem = new ClipboardItem({
[blob.type]: blob,
});
// 写入剪贴板
await navigator.clipboard.write([clipboardItem]);
console.log("✅ 图片已复制到剪贴板");
} else {
console.warn("⚠️ 浏览器不支持复制图片功能,请右键保存");
}
} catch (error) {
console.error("❌ 复制图片失败:", error);
console.log("复制失败,请重试");
}
};
/**
* 下载图片到本地
* 创建临时下载链接实现文件保存
*/
const downLoadImage = () => {
if (!imgUrl.value) {
console.warn("请先生成图片");
return;
}
const link = document.createElement("a");
link.download = `screenshot-${Date.now()}.png`; // 添加时间戳避免重名
link.href = imgUrl.value;
link.click();
console.log("📥 图片下载成功");
};
</script>
<style lang="scss" scoped>
.share-box {
/* 截图目标区域样式 */
}
</style>
📝 代码说明
核心配置参数
width/height * 2
: 2倍分辨率输出,确保高清效果transform: scale(2)
: 元素放大2倍,配合高分辨率cacheBust: true
: 避免浏览器缓存导致的问题bgcolor: "#ffffff"
: 设置白色背景,避免透明区域
关键技术点
- Fetch API 处理 base64 : 利用
fetch()
将 data URL 转换为 Blob - Clipboard API: 现代浏览器的剪贴板操作接口
- 错误处理: 完善的异常捕获和用户友好提示
- 兼容性检测: 自动检测浏览器对 Clipboard API 的支持
浏览器兼容性
- 复制功能: 需要 HTTPS 环境和现代浏览器支持
- 下载功能: 所有现代浏览器均支持
- 截图功能: 基于 Canvas API,兼容性良好