electron取消原生菜单后自定义拖拽:方法一(动态设置位置)

一般用electron开发应用都不会使用原生的菜单栏。取消原生菜单栏后就会自定义自己的菜单栏,实现自定义菜单栏的拖拽目前有两种方案。一个是css直接设置(这个推荐,很稳定),第二个是用原生js实现的动态设置窗口的坐标,今天就来测试了一下第二种方法。结论是,可以用但是有很大的局限性,而且拖动过程中还容易卡顿,是不是因为没有防抖节流的原因没有测试。

实现步骤如下:

第一步:渲染层界面设置监听事件,并把实时的窗口位置发送到主进程

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>electron</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      .header {
        width: 100%;
        height: 30px;
        background-color: lightslategrey;
      }
    </style>
  </head>

  <body>
    <div class="header"></div>
    <button id="btn">发送</button>
  </body>
  <script>
    const { ipcRenderer } = require("electron");
    const btn = document.querySelector("#btn");
    const header = document.querySelector(".header");
    let isDown = false;
    let baseX = 0,
      baseY = 0;
    header.addEventListener("mousedown", (e) => {
      isDown = true;
      baseX=e.x
      baseY=e.y
      // console.log(e.x, e.y);
    });

    document.addEventListener("mousemove", (e) => {
      if(isDown){
        const x=e.screenX-baseX
        const y=e.screenY-baseY

        ipcRenderer.send('move-app',{
          postX:x,
          postY:y
        })
      }
    });
    document.addEventListener("mouseup", (e) => {
      isDown=false
    });



    btn.addEventListener("click", function () {
      console.log("btn");
      ipcRenderer.send("message", "我是渲染层的信息!");
    });
    ipcRenderer.on("toRenderer", (e, v) => {
      console.log(v);
    });
  </script>
</html>

第二步:主进程监听事件,并实时设置窗口的位置

const { app, BrowserWindow, ipcMain } = require("electron");

let win = null;
app.on("ready", function () {
  console.log("app:ready");
  win = new BrowserWindow({
    width: 300,
    height: 300,
    maxWidth: 300,
    maxHeight: 300,
    minHeight: 300,
    minWidth: 300,
    show: false,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
    frame: false,
    // alwaysOnTop:true
  });
  // win.setBounds({
  //   x:10,
  //   y:100
  // })
  win.setPosition(10, 10);

  win.loadFile("./index.html");
  win.once("ready-to-show", function () {
    win.show();
  });
});

ipcMain.on("message", (e, v) => {
  console.log(v);
  e.reply("toRenderer", "我是主进程发送回来的信息");
});

ipcMain.on("move-app", (e, v) => {
  console.log(v);
  const [width,height]=win.getSize()
  // win.setPosition(v.postX, v.postY);
  // win.setSize(w,h)
  win.setBounds({
    x:v.postX,
    y:v.postY,
    width,
    height
  })
});

需要注意的事项:

必须要在主进程创建窗口设置设置窗口的以下6个属性完全一样。不然会出现拖动时窗口大小会自动变大的情况,出现这一问题的原因是:windows的屏幕设置了“缩放与布局”,经测试,如果不缩放的情况下,不会在拖动时自动放大窗口。实时获取屏幕的dpi再等比例缩放没有测试。总之这种方法还是不建议使用。直接使用css设置会更方便。

width: 300,
height: 300,
maxWidth: 300,
maxHeight: 300,
minHeight: 300,
minWidth: 300,

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注