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

需求:

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

【electron】复制粘贴图片 && 拖拽文件_第1张图片

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
      }
    },

效果图:
【electron】复制粘贴图片 && 拖拽文件_第2张图片
【electron】复制粘贴图片 && 拖拽文件_第3张图片

你可能感兴趣的:(Electron,electron,javascript,前端)