Electron無(wú)邊框自定義窗口拖動(dòng)的問(wèn)題小結(jié)
最近使用了electron框架,發(fā)現(xiàn)如果自定義拖動(dòng)是比較實(shí)用的;特別是定制化比較高的項(xiàng)目,如果單純的使用-webkit-app-region: drag;會(huì)讓鼠標(biāo)事件無(wú)法觸發(fā);
過(guò)程中發(fā)現(xiàn)問(wèn)題:
1.windows縮放不是100%后設(shè)置偏移界面會(huì)縮放,感覺(jué)像吹起的氣球;
2.單純的添加css;-webkit-app-region: drag; 會(huì)讓鼠標(biāo)事件無(wú)法觸發(fā);
封裝核心方法
import { screen } from 'electron'
/* 自定義窗口移動(dòng) */
export class AzCustomWindowMove {
// 是否開(kāi)啟
isOpen: boolean;
// 傳入要處理的窗口
win: any;
// 窗口偏移
winStartPosition: {
x: number, y: number, width: number, height: number,
}
// 現(xiàn)在鼠標(biāo)所在位置
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;
// 獲取當(dāng)前窗口偏移[x, y]
const winPosition = this.win.getPosition();
// 獲取當(dāng)前縮放[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];
// 獲取鼠標(biāo)絕對(duì)位置
const mouseStartPosition = screen.getCursorScreenPoint();
this.startPosition.x = mouseStartPosition.x;
this.startPosition.y = mouseStartPosition.y;
// 開(kāi)啟刷新
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})
// 更新位置的同時(shí)設(shè)置窗口原大小, windows上設(shè)置=>顯示設(shè)置=>文本縮放 不是100%時(shí),窗口會(huì)拖拽放大
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 自定義窗口移動(dòng) */
const CustomWindowMove = new AzCustomWindowMove();
// 創(chuàng)建一個(gè)窗口
const mainWindow = new BrowserWindow({
frame: false,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false
}
})
// 將窗口傳進(jìn)去
CustomWindowMove.init(mainWindow)
// 通信監(jiān)聽(tīng)
ipcMain.on("Main_Window_Operate", (event, info) => {
const operateEvent = info.event || '';
switch(operateEvent) {
// 拖拽窗口-開(kāi)始
case 'homeDragWindowStart':
{
/*
如果別的窗口也想復(fù)用這個(gè)自定義拖拽方法可以這么用;
const webContents = event.sender;
const win = BrowserWindow.fromWebContents(webContents);
CustomWindowMove.init(win);
CustomWindowMove.start();
*/
CustomWindowMove.start();
}
break;
// 拖拽窗口-結(jié)束
case 'homeDragWindowEnd':
{
CustomWindowMove.end();
}
break;
default:
break;
}
})preload.ts 預(yù)加載腳本
import { contextBridge, ipcRenderer } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
...
contextBridge.exposeInMainWorld('customAPI', {
/**
* 發(fā)布main窗口操作消息
* @param info {type: 操作類型, data: 參數(shù)}
*/
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'});
}
/*第二個(gè)思路, 當(dāng)按下后監(jiān)聽(tīng)document的事件*/
const handleMouseDown = (e) => {
// 通知開(kāi)始
(window as any).customAPI.publishMainWindowOperateMessage({event: 'homeDragWindowStart'});
// 鼠標(biāo)抬起
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
document.onselectstart = null;
// 通知結(jié)束
(window as any).customAPI.publishMainWindowOperateMessage({event: 'homeDragWindowEnd'});
}
}
<div
onMouseDown={handleMouseDown} onMouseUp={handleMouseUp}
>自定義窗口移動(dòng)</div>到此這篇關(guān)于Electron無(wú)邊框自定義窗口拖動(dòng)的文章就介紹到這了,更多相關(guān)Electron自定義窗口拖動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js點(diǎn)擊button按鈕跳轉(zhuǎn)到另一個(gè)新頁(yè)面
點(diǎn)擊按鈕怎么跳轉(zhuǎn)到另外一個(gè)頁(yè)面呢?點(diǎn)擊圖片要跳轉(zhuǎn)到新的頁(yè)面時(shí),怎么做到呢?可以使用onclick=window.location=新頁(yè)面來(lái)實(shí)現(xiàn)2014-10-10
解析javascript瀑布流原理實(shí)現(xiàn)圖片滾動(dòng)加載
這篇文章主要幫助大家解析javascript瀑布流原理,實(shí)現(xiàn)js圖片滾動(dòng)加載2016-03-03
js對(duì)象合并的4種方式與數(shù)組合并的4種方式
這篇文章主要介紹了js對(duì)象合并的4種方式與數(shù)組合并的4種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
setTimeout自動(dòng)觸發(fā)一個(gè)js的方法
本文為大家介紹下使用setTimeout自動(dòng)觸發(fā)一個(gè)js,具體實(shí)現(xiàn)如下,喜歡的朋友可以學(xué)習(xí)下2014-01-01
js簡(jiǎn)單實(shí)現(xiàn)豎向tab選項(xiàng)卡的方法
這篇文章主要介紹了js簡(jiǎn)單實(shí)現(xiàn)豎向tab選項(xiàng)卡的方法,涉及javascript實(shí)現(xiàn)tab切換效果的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-05-05
JS實(shí)現(xiàn)canvas仿ps橡皮擦刮卡效果詳解
這篇文章主要為大家詳細(xì)介紹了使用js中的Canvas實(shí)現(xiàn)橡皮擦效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11

