Navigator.clipboard与Canvas实现图片复制粘贴到微信上
前言:之前开发中使用过复制功能,那时候使用的是复制文本功能,然后有次业务需求需要用到右键事件来复制图片。
效果图:
有人说为什么不用原生右键保存图片,但是业务中右键事件不止复制图片,还有其他操作,自定义右键事件就需要阻止浏览器原生的事件。所以原生的右键点击保存图片方法不可取。
让我们先来理下思路,复制功能做过的大家都会先想到一个库clipboard.js
,这是一个专门复制的库。我尝试过这个库来进行复制图片。可能是笔者姿势不对,没成功。所以笔者去查阅了原生的剪切板API——Navigator.clipboard
# Clipboard。
阅读文档可以得知通过Clipboard.write()
来写入图片数据到剪切板。
语法:
var promise = navigator.clipboard.write(data)
参数:
data
ClipboardItem
包含要写入剪贴板的数据的对象数组。(如果是处理文本数据那么直接使用Clipboard.readText()
和Clipboard.writeText()
即可,但是如果是文件或者图片类型则需要用到这个对象。)
ClipboardItem
可以让开发者更好得处理各种文件类型数据。
返回值:
Promise
数据写入剪贴板后解析。如果剪贴板无法完成剪贴板访问,则该承诺将被拒绝。
通过文档说明,就有了大致思路:
代码首先创建一个新ClipboardItem对象
,文本将被放置到该对象中以发送到剪贴板。传递给构造函数的对象的键ClipboardItem
表示内容类型,值表示内容。内容可以是文本
甚至是 Blob
(例如,用于将图像复制到剪贴板)。Then
同时指定一个实现函数和一个错误函数。
代码思路有了,那么再联系实际业务场景,在实际业务场景中,展示出来的图片以网络地址居多,而ClipboardItem
对象需要传入的是Blob
,所以我们需要先把网络图片转换为图片文件,这里笔者用到的是canvas.toBlob()
。
在创建canvas
的时候需要给它设定宽高,这里需要注意,创建的画布宽高是图片的自然宽度和自然高度,也就是naturalWidth
和naturalHeight
,它们是元素的自然宽度,它们永远不会改变。而不是渲染在页面的高宽,如果使用图片在页面的宽高,会导致图片复制不全或者偏小。
思路都差不多了,剩下就是代码了。
<script>
//写在公共方法,暴露出去
/**
* 复制图片至剪切板
* @param htmlDom dom节点
*/
export function clipboardImg(html) {
const testImg = html
//可以使用document.querySelector(),document.getElementById()等来获取需要复制的img标签
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
//创建一个画布,赋予画布宽高为图片的原始宽高
canvas.width = testImg.naturalWidth;
canvas.height = testImg.naturalHeight;
//浏览器在加载图像时要使用匿名身份验证,以允许跨域资源共享(CORS)。
img.crossOrigin = "Anonymous";
img.src = testImg.src;
img.onload = () => {
//防止有缓存,绘制之前先清除画布
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, 0, 0);
// 将canvas转为blob
canvas.toBlob(async (blob) => {
console.log(blob);
const data = [
new ClipboardItem({
[blob.type]: blob,
}),
]
await navigator.clipboard.write(data).then(
() => {
Message({
type: 'success',
message: "复制成功"
})
console.log("Copied to clipboard successfully!");
},
() => {
Message({
type: 'error',
message: "复制失败"
})
console.error("Unable to write to clipboard.");
}
);
});
};
}
</script>
运行效果:
这篇文章分享就到了这,如果觉得对你有所帮助,能否点个赞,激励下笔者创作,感谢您的阅读。
转载自:https://juejin.cn/post/7210212440671518775