实现一个不规则窗体

这里我们实现一个圆形窗体,实现其他形状的窗体与这个方法类似。

首先,把窗口的高度(height)和宽度(width)值修改为相同的值,使窗口成为一个正方形。

其次,把窗口的透明属性(transparent)设置为true,这样设置之后窗口还是正方形的,但只要我们控制好内容区域的Dom元素的形状,就可以让窗口看起来像一个不规则形状一样。

不规则窗口往往需要自定义边框和标题栏,所以frame也设置为false。

另外,透明的窗口不可调整大小。所以将resizable属性设置为false。

窗口显示后,为了防止双击窗口可拖拽区触发最大化事件,我们把maximizable属性也设置为false。

最终创建窗口的代码如下:

win = new BrowserWindow({
width: 380,
height: 380,
transparent: true,
frame: false,
resizable: false,
maximizable: false,
//...
})

接下来再修改样式,使内容区域的Dom元素呈现一个圆形:

html,body {
margin: 0px;
padding: 0px;
pointer-events: none;
}
#app {
box-sizing: border-box;
width: 380px;
height: 380px;
border-radius: 190px;
border: 1px solid green;
background: #fff;
overflow: hidden;
pointer-events: auto;
}

上面样式代码中通过border-radius样式把#app元素设置成了圆形。border-radius负责定义一个元素的圆角样式,如果圆角足够大,整个DIV就变成了一个圆形。

pointer-events样式,在后面会有讲解。

最终实现的窗口界面如图5-7:

如果你略微了解CSS,你会知道除了圆形,你还可以通过CSS样式控制这个窗口成为任意其他形状。

点击穿透透明区域

上面这个应用会有一点小问题,虽然窗口看起来是圆形的,但它其实还是一个正方形窗口,只不过正方形四个角是透明的,所以看起来像一个圆形的窗口。

当我点击下图中的①区域内的文本文件时,鼠标的点击事件还是发生在本窗口内,而不会点击到那个文件上。

作为开发者,我们知晓其中的道理,但作为用户来说,这就显得很诡异。为了达到更好的用户体验,我们需要让鼠标在这4个区域发生点击动作时,点击动作可以穿透本窗口,落在窗口后面的内容上。

Electron官方文档明确说“不能点击穿透透明区域”,这并没有难倒我们,有一个小trick来解决这个问题。

首先,需要用到窗口对象的setIgnoreMouseEvents方法,该方法可以使窗口忽略窗口内的所有鼠标事件,并且在此窗口中发生的所有鼠标事件都将被传递到此窗口背后的内容。

如果调用该方法时传递了forward参数,如:

setIgnoreMouseEvents(true, { forward: true }),

则只有点击事件会穿透窗口,鼠标移动事件仍会触发。

基于此,我们在页面中执行如下代码:

  const remote = require("electron").remote;
let win = remote.getCurrentWindow();
window.addEventListener("mousemove", event => {
let flag = event.target === document.documentElement;
if (flag){
win.setIgnoreMouseEvents(true, { forward: true });
}
else {
win.setIgnoreMouseEvents(false);
}
});
win.setIgnoreMouseEvents(true, { forward: true });

注意,这是实验代码,所以用了remote模块,关于remote模块的一些问题,我在“Electron团队为什么要干掉remote模块“有详细描述。

上面的代码中,设置窗口对象监听mousemove事件,当鼠标移入窗口圆形内容区的时候,不允许鼠标事件穿透。当鼠标移入透明区时,允许鼠标事件穿透。

接着我们为html,body元素增加样式:pointer-events: none,为#app元素增加样式pointer-events: auto。

设定pointer-events: none后,其所标志的元素就永远不会成为鼠标事件的target了。

为子元素#app设置了pointer-events: auto,说明子元素#app还是可以成为鼠标事件的target的。

也就是说除了圆形区域内可以接收鼠标事件外,其他部分将不再接收鼠标事件。

当鼠标在圆形区域外移动时,窗口对象的mousemove事件触发,event.target为document.documentElement对象(这个事件并不是在html或body元素上触发的,而是在窗口对象上触发的,document.documentElement就是DOM树中的根元素,也就是html节点所代表的元素)。

至此,上文代码中的判断成立,当鼠标在前文所述四个区域移动时,鼠标事件允许穿透。鼠标在圆形区域移动时,鼠标事件不允许穿透。

至此,上文所述判断成立,运行程序,鼠标在正方形四角区域内点击,鼠标事件具备了穿透效果。

如何点击穿透Electron不规则窗体的透明区域的更多相关文章

  1. Qt 不规则窗体 – 鼠标点击穿透(Linux也可以,有对x11的配置的方法)

    之前写过如何用 Qt 现成的方法写出无边框半透明的不规则窗体:<Qt 不规则窗体 – 无边框半透明> 其实有一个很特殊的窗体属性一直以来都伴随着不规则窗体出现,这就是本文要介绍的鼠标点击穿 ...

  2. WPF界面设计技巧(1)—不规则窗体图文指南

    原文:WPF界面设计技巧(1)-不规则窗体图文指南 初到园子,奉上第一篇入门级教程,请勿见笑. 以往WinForm编程中,实现不规则窗体是有一定难度的,更难的是不规则窗体的边缘抗锯齿及局部透明处理.而 ...

  3. WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案

    首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如  WPF中不规则窗体与WebBrowser控件的兼 ...

  4. 移动开发之fastclick 点击穿透

    穿透(点穿)是在mobile各种浏览器上发生的常见的bug.可能是由click事件的延迟(300ms)或者事件冒泡导致 现象:在A页面中有个 btn1<或a标签>,在B页面中有个 btn2 ...

  5. QT实现不规则窗体

    看到网上有很多不规则窗体的实现,效果很酷.于是使用QT也实现了一个,QT的不规则窗体实现非常简单,只需要设置一个mask(遮掩)图片,这个图片的格式可以使用png或bmp格式,我使用了png格式,默认 ...

  6. WPF中不规则窗体与WebBrowser控件的兼容问题解决办法

    原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...

  7. [小结][N种方法]实现WPF不规则窗体

    原文:[小结][N种方法]实现WPF不规则窗体 WPF实现不规则窗体,方法很多很多多.... 本文总结DebugLZQ认为简洁高效的几种方法 实现WPF不规则窗体的几种常用的方法如下: 1.使用Ble ...

  8. WPF移动Window窗体(鼠标点击左键移动窗体自定义行为)

    XAML代码部分:1.引用System.Windows.Interactivity 2.为指定的控件添加一个拖动的行为 3.很简单的了解行为的作用和用法 <Window xmlns=" ...

  9. 聊聊click延迟和点击穿透

    博客原文地址:Claiyre的个人博客 https://claiyre.github.io/ 如需转载,请在文章开头注明原文地址 移动端click事件被延迟 移动端的开发经常需要监听用户的双击行为,所 ...

随机推荐

  1. awk-05-数组

    数组 数组: 存储一系列相同类型的元素,键/值方式存储,通过下标(键)来访问值 awk 中数组称为关联数组,不仅可以使用数字作为下标,还可以使用字符串作为下标 数组元素的键和值存储在 awk 程序内部 ...

  2. 【笔记】偏差方差权衡 Bias Variance Trade off

    偏差方差权衡 Bias Variance Trade off 什么叫偏差,什么叫方差 根据下图来说 偏差可以看作为左下角的图片,意思就是目标为红点,但是没有一个命中,所有的点都偏离了 方差可以看作为右 ...

  3. 000 PCI Express协议入门指南目录

    一.001 PCI Express体系结构(一)

  4. CPU 指令环 ring0,ring1,ring2,ring3

    Intel的CPU将特权级别分为4个级别:RING0,RING1,RING2,RING3. Windows只使用其中的两个级别RING0和RING3,RING0只给操作系统用,RING3谁都能用.如果 ...

  5. Python成员运算,身份运算和流程控制

    成员运算 in #判断--在--里面 print('a' in 'abcd') # 字符串判断a是否在abcd里面 print('you' in 'how are you') # 这种整体也可以判断 ...

  6. 内存吞金兽(Elasticsearch)的那些事儿 -- 常见问题痛点及解决方案

    1.大数据量的查询效率如何保证: 查询的流程:往 ES 里写的数据,实际上都写到磁盘文件里去了,查询的时候,操作系统会将磁盘文件里的数据自动缓存到 Filesystem Cache 里面去 最佳的情况 ...

  7. Docker运行PostgreSQL

    docker-compose.yml version: '3.1' services: db: image: postgres restart: always ports: - 5432:5432 e ...

  8. Win10下安装SVN出现2503/2502解决方法

    出现错误的原因是权限不够 在win10的开始按钮上,右键点击,选择"命令提示符(管理员)(A)",弹出管理员身份运行模式的命令行的窗口,输入如下的命令: msiexec /pack ...

  9. C++多态中虚函数表合并与继承问题

    多态: C++的多态是通过一张虚函数表(Virtual Table)来实现的,简称为 V-Table.在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承.覆写的问题,保证其真实反应实际的函数. ...

  10. 二、vue组件化开发(轻松入门vue)

    轻松入门vue系列 Vue组件化开发 五.组件化开发 1. 组件注册 组件命名规范 组件注册注意事项 全局组件注册 局部组件注册 2. Vue调试工具下载 3. 组件间数据交互 父组件向子组件传值 p ...