electron
main.js
const { BrowserWindow , ipcMain } = require('electron');
const path = require("path")
const CustomWindow = require('./CustomWindow')
const win = new BrowserWindow({
frame: false,
transparent: true,
center: true,
webPreferences: {
preload: path.join(__dirname, `./preload.js`)
}
})
const customWin = new CustomWindow(win)
ipcMain.on('on-custom-win', (_, funName, ...arg) => customWin[funName](...arg));
preload.js
const { contextBridge, ipcRenderer } = require('electron');
const handleWin = {
changeSize: (...args) => ipcRenderer.send('on-custom-win', 'autoMax', ...args),
moveStart: () => ipcRenderer.send('on-custom-win', 'moveStart'),
moveEnd: () => ipcRenderer.send('on-custom-win', 'moveEnd'),
top: () => ipcRenderer.send('on-custom-win', 'top'),
maximize: () => ipcRenderer.send('on-custom-win', 'maximize'),
onStatus: (fun) => ipcRenderer.on('window-status', fun)
};
contextBridge.exposeInMainWorld('ipcApi', {
handleWin
});
CustomWindow.js
const { screen } = require('electron');
/**
* 窗口移动|缩放|置顶
*/
module.exports = class {
constructor(win) {
this.isMove = false;
this.startPosition = [0, 0]
this.oldPosition = [0, 0];
this.maxStatus = false;
this.topStatus = false;
this.nowSize = null;
this.nowPosition = null;
this._initialization(win);
};
_initialization(win) {
this.win = win;
this.defaultSize = win.getSize();
this.defaultPosition = win.getPosition();
if (win.isAlwaysOnTop()) this.top();
this.autoMax(...this.defaultSize);
};
_isWin = () => this.win && !this.win.isDestroyed();
moveStart() {
this.isMove = true;
if (!this._isWin()) return this.moveEnd();
// 获取鼠标按下位置
let { x, y } = screen.getCursorScreenPoint();
const winPosition = this.win.getPosition();
x -= winPosition[0];
y -= winPosition[1];
this.startPosition = [x, y];
this._moveing();
};
_moveing() {
if (!this.isMove) return;
let { x, y } = screen.getCursorScreenPoint();
x -= this.startPosition[0];
y -= this.startPosition[1];
if (x !== this.oldPosition[0] || y !== this.oldPosition[1]) {
this._restoreSize();
this.win.setPosition(x, y);
this.oldPosition = [x, y];
};
setTimeout(() => this._moveing(), 16);
};
moveEnd = () => this.isMove = false;
_restoreSize() {
if (!this.maxStatus || !this.oldPosition[0] || !this.oldPosition[1]) return;
let startPositionX = parseInt(this.nowSize[0] / 2);
const { x: leftBoundary, width: screenWidth } = this._getNowScreenSize();
const rightBoundary = leftBoundary + screenWidth - this.nowSize[0];
let { x: movePosition } = screen.getCursorScreenPoint();
movePosition -= startPositionX;
if (movePosition < leftBoundary) {
startPositionX += movePosition - leftBoundary;
};
if (movePosition > rightBoundary) {
startPositionX += movePosition - rightBoundary;
};
this.startPosition[0] = startPositionX;
this.win.setSize(...this.nowSize);
this.maxStatus = false;
this._sendStatus('max', false);
};
_getNowScreenSize() {
let { x, y } = this.win.getBounds();
if (x < 0) x = 0;
for (const display of screen.getAllDisplays()) {
if (x >= display.bounds.x && x < display.bounds.x + display.bounds.width &&
y >= display.bounds.y && y < display.bounds.y + display.bounds.height) {
return display.bounds;
};
};
};
top() {
if (!this._isWin()) return;
this.topStatus = !this.topStatus;
this.win.setAlwaysOnTop(this.topStatus);
this._sendStatus('top', this.topStatus);
};
autoMax(width, height) {
if (!this._isWin() || !this.win.isResizable() || this.maxStatus) return;
const { width: screenWidth, height: screenHeight } = this._getNowScreenSize();
if (screenWidth - width < 100 && screenHeight - height < 100) {
this.nowSize = this.defaultSize;
this.nowPosition = this.defaultPosition;
this.maxStatus = true;
this._sendStatus('max', true);
this.win.maximize();
this.oldPosition = [0, 0];
};
};
maximize() {
if (!this._isWin() || !this.win.isResizable()) return;
this.maxStatus = !this.maxStatus;
if (this.maxStatus) {
this.nowSize = this.win.getSize();
this.nowPosition = this.win.getPosition();
this.win.maximize();
} else {
this.win.setSize(...this.nowSize);
this.win.setPosition(...this.nowPosition);
};
this.oldPosition = [0, 0];
this._sendStatus('max', this.maxStatus);
};
_sendStatus = (type, value) => this.win.webContents.send('window-status', { type, value });
}
VUE
main.js 注册指令
import { createApp } from 'vue'
import App from '@/App.vue'
import registerDirectives from '@/directives'
const app = createApp(App)
registerDirectives(app)
app.mount('#app')
directives 自定义指令
index.js
import interactWin from './interactWin';
export default function registerDirectives(app) {
app.directive("handle-win", { mounted: (...arg) => interactWin.handle(...arg) })
}
interactWin.js
const { handleWin } = window.ipcApi;
class InteractWin {
constructor() {
this.el = null;
};
handle(el, binding = null) {
if (this.el) return;
this.el = el;
this.el.addEventListener('mousedown', this._mouseDown);
this.el.addEventListener('dblclick', this._mouseDblclick);
window.addEventListener('resize', this._handleResize);
if (binding?.value && typeof binding.value === 'function') {
handleWin.onStatus((_, ...arg) => binding.value(...arg));
};
};
_mouseDblclick = () => handleWin.maximize();
_mouseDown = (e) => {
if (e.button !== 0) return;
handleWin.moveStart();
window.addEventListener('mouseup', this._globalMouseUp);
};
_globalMouseUp = (e) => {
if (e.button !== 0) return;
handleWin.moveEnd();
window.removeEventListener('mouseup', this._globalMouseUp);
};
//此处加防抖可提升性能
_handleResize = () => {
handleWin.changeSize(window.innerWidth, window.innerHeight);
};
};
export default new InteractWin();
vue使用指令操作窗口
在头部DOM上使用 v-handle-win;
1:左键移动窗口;
2:双击最大化窗口与还原窗口;
3:最大化移动窗口自动还原窗口;
4:手动改变窗口尺寸至屏幕最大范围(范围阈值在CustomWindow.js内修改)时自动最大化;
<template>
<div v-handle-win="onWinHandle">
<!-- 自定义窗口头部,使用指令并监听使用反馈 -->
</div>
<div @click="winTop">
是否置顶:{{ topStatus }}
</div>
<div @click="winMax">
是否最大化:{{ maxStatus }}
</div>
</template>
<script setup>
import { ref } from 'vue';
const { handleWin } = window.ipcApi;
const maxStatus = ref(false)
const topStatus = ref(false)
/**
* 监听操作窗口头部的反馈
*/
const onWinHandle = ({ type, value }) => {
switch (type) {
case 'max':
maxStatus.value = value
break;
case 'top':
topStatus.value = value
break;
}
}
/**
* 窗口置顶
*/
const winTop = () => handleWin.top();
/**
* 最大化与还原
*/
const winMax = () => handleWin.maximize();
标签:...,const,自定义,缩放,win,handleWin,._,maxStatus,置顶
From: https://blog.csdn.net/qq_19838177/article/details/139605318