diff --git a/src/views/demo/tuiImageEditor/components/image-editor.vue b/src/views/demo/tuiImageEditor/components/image-editor.vue
index 82f8acc..07c164b 100644
--- a/src/views/demo/tuiImageEditor/components/image-editor.vue
+++ b/src/views/demo/tuiImageEditor/components/image-editor.vue
@@ -31,6 +31,11 @@
@click="changeImage('next')"
>
+
+
@@ -251,6 +256,62 @@ const initTuiImageEditor = () => {
// 针对图片加载首次不显示,必须手动调用一次refreshImageShow方法(个人项目未复现,公司项目有该问题,考虑是返回的图片的加载方式问题或者格式等问题)
// refreshImageShowWithDelay(300, true);
+
+ /**
+ * canvas禁用右键功能
+ * 该组件默认有两层canvas,第一层图片canvas在底部,画布canvas在顶部,需要禁用右键功能(如果不禁用,会导致默认右键复制和保存的图片是画布这一层,空白的图片)
+ * 再自定义右键功能,实现图片下载和复制到剪贴板功能
+ */
+ const canvas = document.querySelector('.upper-canvas');
+ const customContextMenu = document.querySelector('#customContextMenu');
+ canvas.addEventListener('contextmenu', (e) => {
+ console.log(customContextMenu);
+ e.preventDefault();
+
+ // 显示自定义菜单
+ customContextMenu.style.display = 'block';
+ customContextMenu.style.left = e.pageX + 'px';
+ customContextMenu.style.top = e.pageY + 'px';
+ });
+ // 点击其他地方隐藏菜单
+ document.querySelector('.tui-image-editor-wrap').addEventListener('click', () => {
+ customContextMenu.style.display = 'none';
+ });
+};
+
+const saveCanvasAsImage = () => {
+ const canvas = document.querySelector('.lower-canvas');
+ const a = document.createElement('a');
+ a.href = canvas.toDataURL('image/jpeg');
+ a.download = new Date().getTime() + '.jpg';
+ a.click();
+ a.remove();
+};
+
+// 复制图片到剪贴板功能如果是以iframe嵌入,必须要在嵌入加上属性才可以正常使用
+const copyCanvasToClipboard = async () => {
+ const canvas = document.querySelector('.lower-canvas');
+ /**
+ 问题的现象
+ 在使用浏览器的剪贴板API的 write 方法尝试将JPEG图像写入剪贴板时,我们可能会遇到这样的错误:DOMException: Failed to execute 'write' on 'Clipboard': Type image/jpeg not supported on write.
+ 问题的原因
+ 这个错误的产生主要是因为 write 方法目前只支持 text/plain 和 text/html MIME 类型,这意味着你不能直接将JPEG图像写入剪贴板。然而,为什么浏览器的剪贴板API会有这样的限制呢?
+ 在深入浏览器的内部实现之前,我们先来了解一下剪贴板API。剪贴板API是浏览器提供的一种接口,用于访问用户的剪贴板。它的主要目的是为了提供一种简单、一致的方式来读取和写入剪贴板数据。
+ 然而,由于安全和隐私的考虑,浏览器的剪贴板API并不允许直接访问剪贴板中的所有类型的数据。例如,它不允许访问剪贴板中的图像数据,除非用户明确地进行了粘贴操作。这就是为什么我们不能直接将JPEG图像写入剪贴板的原因。
+ 解决方案
+ 那么,我们应该如何解决这个问题呢?一种可能的解决方案是将JPEG图像转换为PNG图像,然后将其写入剪贴板。这个方法可能不适用于所有浏览器,因为不是所有浏览器都支持 clipboard.write 方法或 ClipboardItem 对象。但是,我将提供的代码已经在大多数现代浏览器中进行了测试,并且可以正常工作。
+ */
+ // 这里图片格式只能使用png,原因如上
+ const blob = await new Promise((resolve) => {
+ canvas.toBlob(resolve, 'image/png');
+ });
+ if (navigator.clipboard && navigator.clipboard.write) {
+ await navigator.clipboard.write([
+ new ClipboardItem({
+ 'image/png': blob,
+ }),
+ ]);
+ }
};
const addEventListenerFN = () => {
@@ -266,7 +327,8 @@ const handleClickOutside = (event) => {
if (
getBtnDom('.save-btn').contains(event.target) ||
getBtnDom('.left-btn').contains(event.target) ||
- getBtnDom('.right-btn').contains(event.target)
+ getBtnDom('.right-btn').contains(event.target) ||
+ getBtnDom('#customContextMenu').contains(event.target)
) {
return;
}
@@ -472,4 +534,27 @@ body > svg:last-of-type {
.tui-image-editor-container div.tui-colorpicker-clearfix {
display: none !important;
}
+
+#customContextMenu {
+ position: absolute;
+ display: none;
+ background-color: #fff;
+ padding: 10px 0;
+ border-radius: 5px;
+
+ li {
+ box-sizing: border-box;
+ cursor: pointer;
+ font-size: 14px;
+ color: #666;
+ width: 100%;
+ height: 30px;
+ line-height: 30px;
+ padding: 0 10px;
+ }
+
+ li:hover {
+ background-color: #f5f5f5;
+ }
+}