当前位置: 代码网 > it编程>编程语言>Javascript > Electron无边框自定义窗口拖动的问题小结

Electron无边框自定义窗口拖动的问题小结

2024年05月15日 Javascript 我要评论
最近使用了electron框架,发现如果自定义拖动是比较实用的;特别是定制化比较高的项目,如果单纯的使用-webkit-app-region: drag;会让鼠标事件无法触发;过程中发现问题:1.wi

最近使用了electron框架,发现如果自定义拖动是比较实用的;特别是定制化比较高的项目,如果单纯的使用-webkit-app-region: drag;会让鼠标事件无法触发;

过程中发现问题:

1.windows缩放不是100%后设置偏移界面会缩放,感觉像吹起的气球;

2.单纯的添加css;-webkit-app-region: drag; 会让鼠标事件无法触发;

封装核心方法

import { screen  } from 'electron'
/* 自定义窗口移动 */
export class azcustomwindowmove {
    // 是否开启
    isopen: boolean;
    // 传入要处理的窗口
    win: any;
    // 窗口偏移
    winstartposition: {
        x: number, y: number, width: number, height: number,
    }
    // 现在鼠标所在位置
    startposition: {
        x: number, y: number,
    }
    constructor() {
        this.isopen = false;
        this.win = null;
        this.winstartposition = {
            x: 0,
            y: 0,
            width: 0,
            height: 0,
        }
        this.startposition = {
            x: 0,
            y: 0,
        }
    }
    init(win: any) {
        this.win = win;
    }
    start() {
        this.isopen = true;
        // 获取当前窗口偏移[x, y]
        const winposition = this.win.getposition();
        // 获取当前缩放[width, height]
        const winsize = this.win.getsize();
        this.winstartposition.x = winposition[0];
        this.winstartposition.y = winposition[1];
        this.winstartposition.width = winsize[0];
        this.winstartposition.height = winsize[1];
        // 获取鼠标绝对位置
        const mousestartposition = screen.getcursorscreenpoint();
        this.startposition.x = mousestartposition.x;
        this.startposition.y = mousestartposition.y;
        // 开启刷新
        this.move();
    }
    move() {
        if (!this.isopen) {
            return;
        };
        console.log('this.win.isdestroyed()', this.win.isdestroyed(), this.win.isfocused());
        // 如果窗口已销毁
        if (this.win.isdestroyed()) {
            this.end();
            return;
        }
        // 判断窗口是否聚焦
        if (!this.win.isfocused()) {
            this.end();
            return;
        }
        const cursorposition = screen.getcursorscreenpoint();
        const x = this.winstartposition.x + cursorposition.x - this.startposition.x;
        const y = this.winstartposition.y + cursorposition.y - this.startposition.y;
        // this.win.setposition(120, 120, false);
        // this.win.setbounds({x: 120, y: 120})
        // 更新位置的同时设置窗口原大小, windows上设置=>显示设置=>文本缩放 不是100%时,窗口会拖拽放大
        this.win.setbounds({
            x: x,
            y: y,
            width: this.winstartposition.width,
            height: this.winstartposition.height,
        })
        settimeout(() => {
            this.move();
        }, 20)
    }
    end() {
        this.isopen = false;
    }
}

在main.js中引入

import { azcustomwindowmove } from './util';
/* new 自定义窗口移动 */
const customwindowmove = new azcustomwindowmove();
// 创建一个窗口
const mainwindow = new browserwindow({
    frame: false,
    webpreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
})
// 将窗口传进去
customwindowmove.init(mainwindow)
// 通信监听
ipcmain.on("main_window_operate", (event, info) => {    
    const operateevent = info.event || '';
    switch(operateevent) {
        // 拖拽窗口-开始
        case 'homedragwindowstart':
            {
                /*
                    如果别的窗口也想复用这个自定义拖拽方法可以这么用;
                    const webcontents = event.sender;
                    const win = browserwindow.fromwebcontents(webcontents);
                    customwindowmove.init(win);
                    customwindowmove.start();
                */
               customwindowmove.start();
            }
            break;
        // 拖拽窗口-结束
        case 'homedragwindowend':
            {
                customwindowmove.end();
            }
            break;
      default:
        break;
    }
  })

preload.ts 预加载脚本

import { contextbridge, ipcrenderer } from 'electron'
import { electronapi } from '@electron-toolkit/preload'
...
 contextbridge.exposeinmainworld('customapi', {
      /**
       *  发布main窗口操作消息
       * @param info {type: 操作类型, data: 参数}
       */
      publishmainwindowoperatemessage: (info: {event: string, data: {}}) => {
        ipcrenderer.send("main_window_operate", info);
      } 
})
...

react绑定事件

 const handlemousedown = (e) => {
        (window as any).customapi.publishmainwindowoperatemessage({event: 'homedragwindowstart'});
}
const handlemouseup = (e) => {
        (window as any).customapi.publishmainwindowoperatemessage({event: 'homedragwindowend'});
}
/*第二个思路, 当按下后监听document的事件*/
const handlemousedown = (e) => {
    // 通知开始
    (window as any).customapi.publishmainwindowoperatemessage({event: 'homedragwindowstart'});
    // 鼠标抬起
    document.onmouseup = function () {
        document.onmousemove = null;
        document.onmouseup = null;
        document.onselectstart = null;
        // 通知结束
        (window as any).customapi.publishmainwindowoperatemessage({event: 'homedragwindowend'});
    }
}
<div
    onmousedown={handlemousedown} onmouseup={handlemouseup} 
>自定义窗口移动</div>

到此这篇关于electron无边框自定义窗口拖动的文章就介绍到这了,更多相关electron自定义窗口拖动内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com