【electron】复制粘贴图片 && 拖拽文件

需求:

对话详情页 图片 类信息,单机右键弹出的操作栏中增加【复制】功能,复制后将该内容以图片形式保存在本地剪切板中,可直接粘贴到PC端输入栏中或文字内容编辑区(例如微信,飞书等其他IM会话软件内容输入区)

在这里插入图片描述

1. 复制比较简单,代码:

	/***
    @params
	copyImgDom = {
	  src: img.image_elem_large_url,
	  width: img.image_elem_large_pic_width,
	  height: img.image_elem_large_pic_height
	}
	***/
    handleCopyImg(copyImgDom){
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      const img = new Image();

      canvas.width = copyImgDom.width;
      canvas.height = copyImgDom.height;
      img.crossOrigin = "Anonymous";
      img.src = copyImgDom.src;

      img.onload = () => {
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        ctx.drawImage(img, 0, 0);
        canvas.toBlob(async blob => {
          const data = [
            new ClipboardItem({
              [blob.type]: blob,
            }),
          ];

          await navigator.clipboard.write(data).then(
            () => {
              this.$message({
                text: '复制图片'
              })
            },
            () => {
              console.error("Unable to write to clipboard.");
            });
          });
      }
    },

2. 粘贴图片
粘贴图片有一个问题就是 从粘贴板获取到的File对象中没有 path 也就是文件路径, 需要我们自己保存下来获取到路径才能发送,腾讯IM的Electron SDK 目前只能这么操作。

2.1 粘贴

    async onPaste (e) {
      let _this = this
      e.preventDefault();
      let text = '';
      // let imgUrlList = [];
      text = e.clipboardData.getData('text')
      if (text) {
        this.insert(text);
      }
      let files = []
      let promiseList = []
      for(var i = 0; i < e.clipboardData.files.length; i++) {
        let file = e.clipboardData.files[i];
        if (file && i != 'length') {
          let fileSrc = ''
          let fileType = 'file'
          let blob = e.clipboardData.items[i].getAsFile();
          let j = i
          while(!blob) {
            j++
            blob = e.clipboardData.items[j].getAsFile()
          }
          if (/\.(png|jpg|jpeg|gif|svg)(\?.*)?$/.test(file.name)) {
            // 图片 获取一下缩略图
            let reader = new FileReader();
            reader.readAsDataURL(blob);
            fileType = 'image'
            let promise = new Promise((resolve,reject)=>{
              reader.onload = function (e) {  
                fileSrc = e.target.result;
                files.push({
                  name: file.name,
                  type: fileType,
                  src: fileSrc,
                  file: blob
                })
                resolve()
              }
            })
            promiseList.push(promise)
            
          } else {
            files.push({
              name: file.name,
              type: fileType,
              src: fileSrc,
              file: blob
            })
          }
          
        }
      }
      if (promiseList.length > 0) {
        Promise.all(promiseList).then(()=>{
          _this.$emit('pasteFile', files)
        })
      }
    },

2.2 发送时候 发现没有PATH 发送不了 调用Electron controller 保存到本地 拿到本地路径

// 从微信输入框复制的图片是没有这个路径的 发送不了 需要保存在本地获取到一个路径
      let filePath = ''
      if (!file.file.path) {
        filePath = await this.$ipcInvoke(ipcApiRoute.downloadFileToFolder, { name: file.name,
          src: file.src})
      }
  // 其中Buffer 这样取  const { Buffer } = require("node:buffer");
  downloadFileToFolder (file) {
    let base64Src = file.src.slice(file.src.indexOf(',') + 1)
    const _fileBuffer = Buffer.from(base64Src, 'base64');
    const filePath = path.join(electronApp.getAppPath(), '/temp', `${file.name.replace('image', getUUID())}`);
    let folderName = path.join(electronApp.getAppPath(), '/temp')
    if (!fs.existsSync(folderName)) {
      fs.mkdir(folderName, ()=>{});
    }
    fs.writeFile(filePath, _fileBuffer, err => console.log(err, Date.now()));
    return filePath
  }
  1. 拖拽文件 这个 简单 先拖拽拿到文件以后和粘贴的动作一样
    initDrag () {
      let dropTarget = this.$refs['conversationBody'] // 拖拽主题只负责进入  然后显示拖拽框
      let dropTargetHover = this.$refs['conversationBodyHover']  // 拖拽框负责接收文件和离开事件
      // 拖拽事件绑定
      dropTarget.addEventListener("dragenter", this.handleDropTargetEvent);
      dropTargetHover.addEventListener("dragover", this.handleDropTargetEvent);
      dropTargetHover.addEventListener("drop", this.handleDropTargetEvent);
      dropTargetHover.addEventListener("dragleave", this.handleDropTargetEvent);
    },
    handleDropTargetEvent(event) {
      // 阻止事件的默认行为
      event.preventDefault();
      if (event.type === 'drop') {
        // 文件进入并松开鼠标,文件边框恢复正常
        // this.dragHoverShow = false
        let files = []
        let promiseList = []
        for(let file of event.dataTransfer.files) {
          if (file) {
            let fileSrc = ''
            let fileType = 'file'
            if (/\.(png|jpg|jpeg|gif|svg)(\?.*)?$/.test(file.name)) {
              // 图片 获取一下缩略图
              let reader = new FileReader();
              reader.readAsDataURL(file);
              fileType = 'image'
              let promise = new Promise((resolve,reject)=>{
                reader.onload = function (e) {  
                  fileSrc = e.target.result;
                  files.push({
                    name: file.name,
                    type: fileType,
                    src: fileSrc,
                    file: file
                  })
                  resolve()
                }
              })
              promiseList.push(promise)
              
            } else {
              files.push({
                name: file.name,
                type: fileType,
                src: fileSrc,
                file: file
              })
            }
            
          }
        }
        // 有图片
        if (promiseList.length > 0) {
          Promise.all(promiseList).then(()=>{
            this.dragHoverShow = false
            this.pasteFile(files)
          })
        } else {
          this.dragHoverShow = false
          this.pasteFile(files)
        }
      } else if (event.type === 'dragleave') {
        // 离开
        console.log('dragleave',event.type)
        this.dragHoverShow = false
      } else {
        // 进入
        console.log('进入',event.type)
        this.dragHoverShow = true
      }
    },

效果图:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

左钦杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值