解决方案一

这个拖拽问题导致点击事件失效问题困惑了我好几个晚上,主要还是因为对前端不熟悉。今天问了ChatGPT它给出了一个解决方案「设置一个透明区域」。
主要代码就是<div class="drag-area"></div>该标签,该标签占满了整个视口使得整个其都可以拖拽,然后为不可拖拽的元素指定-webkit-app-region: no-drag; 该class 属性。
其实我没有理解这么做为什么可以响应点击事件,因为我尝试过只给 video 标签设置可拖拽,且将 Setting 标签设置为不可拖拽,层级也修改了,但还是无法响应点击事件。
我感觉最重要的应该就是浏览器到底是如何处理透明区域的事件。

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Setting } from '@icon-park/vue-next'

const router = useRouter()
const route = useRoute()

const toCameraPage = (query) => {
  console.log('toCameraPage...')
  router.push({
    name: 'camera',
    query: {
      ...route.query,
      ...query
    }
  })
}

// 用 ref 引用 video 标签
const video = ref<HTMLVideoElement | null>(null)

const constraints = {
  audio: false,
  video: true
}

onMounted(async () => {
  if (video.value) {
    try {
      const mediaStream = await navigator.mediaDevices.getUserMedia(constraints)
      video.value.srcObject = mediaStream
      video.value.onloadedmetadata = function () {
        video.value?.play()
      }
    } catch (error) {
      console.error('Error accessing media devices.', error)
    }
  }
})
</script>

<template>
  <main class="all">
    <!-- 兼容拖拽 -->
    <div class="drag-area"></div>
    <Setting
      class="setting-icon-wrapper"
      theme="outline"
      size="24"
      fill="#ffffff"
      @click="toCameraPage"
    />
    <video ref="video" class="camera"></video>
  </main>
</template>

<style lang="less" scoped>
.all {
  position: relative;
  /* 确保子元素绝对定位生效 */

  .drag-area {
    position: absolute;
    top: 0;
    left: 0;
    width: 100vh;
    height: 100vh;
    -webkit-app-region: drag; /* 让整个区域可拖动 */
    z-index: 1;
  }

  .setting-icon-wrapper {
    position: absolute;
    cursor: pointer;
    z-index: 2;
    top: 3%;
    left: 50%;
    transform: translateX(-50%);
    -webkit-app-region: no-drag;
  }

  .camera {
    height: 100vh;
    object-fit: cover;
  }
}
</style>

解决方案二(推荐)

当前解决方案其实是换了一种思路去实现拖拽效果。通过自定义鼠标事件实现

  1. 在渲染进程中注册鼠标事件。
    你想让点击哪个元素移动就给哪个元素添加该事件即可;
    可拖拽区域完全由你自己控制,即指定元素的大小就是可拖拽区域。

    <script setup>
      import { ref } from 'vue'
    
      let isKeyDown = ref(false)
      let dinatesX = ref(0)
      let dinatesY = ref(0)
    
      const mousedown = (e) => {
        console.log("mousedown...", e)
    
        isKeyDown.value = true
        dinatesX.value = e.x
        dinatesY.value = e.y
    
        // 鼠标移动事件
        document.onmousemove = (ev) => {
          if (isKeyDown.value) {
            console.log("isKeyDown.value", isKeyDown.value)
            const x = ev.screenX - dinatesX.value
            const y = ev.screenY - dinatesY.value
    
            // 每次鼠标按下的时候发生了移动,就给主进程传入坐标
            // 在主进程中修改当前窗口坐标
            let coordinate = {
              appX: x,
              appY: y,
            }
    
            electron.ipcRenderer.invoke('custom-adsorption', coordinate)
          }
        }
    
        // 鼠标松开事件
        document.onmouseup = (ev) => {
          isKeyDown.value = false
        }
    
      }
    
    </script>
    
    <template>
      <div>
        <div class="drag" @mousedown="mousedown"></div>
      </div>
    </template>
    
    <style scoped>
      .drag {
        width: 100%;
        height: 30px;
        background-color: aqua;
      }
    </style>
    
  2. 在主进程中监听坐标信息并修改窗口坐标

    import { app, shell, BrowserWindow, ipcMain } from 'electron'
    import { join } from 'path'
    import { electronApp, optimizer, is } from '@electron-toolkit/utils'
    import icon from '../../resources/icon.png?asset'
    
    function createWindow(): void {
      const mainWindow = new BrowserWindow({
        width: 900,
        height: 670,
        show: false,
        frame: false, // 无边框窗口
        autoHideMenuBar: true,
        ...(process.platform === 'linux' ? { icon } : {}),
        webPreferences: {
          preload: join(__dirname, '../preload/index.js'),
          sandbox: false
        }
      })
    
      // 监听传入的坐标信息,并实时修改窗口坐标
      ipcMain.handle('custom-adsorption', (_e, coordinate) => {
        mainWindow.setPosition(coordinate.appX, coordinate.appY)
      })
    }
    

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部