NW.js开发桌面应用,如何自定义边框

2018-05-10  本文已影响0人  gaoshu883

利用NW.js开发桌面应用时,NW框架的边框可能无法满足我们对产品的要求,这个时候就需要自定义边框,比如无边框、无边框+有圆角、无边框+有边+有圆角等。现在问题来了,该怎么实现自定义效果呢?笔者以最后一种情况(无边框+有边+有圆角),进行简单的设置说明。

package.json配置

"window": {
    "frame": false,   // 去除框架的边框
    "transparent": true  // 窗口透明
  }

起步

<!-- 在html元素上设置软件整体边框和圆角;在body中的div上同样可以设置 -->
<html style="border:8px solid #eeca00;border-radius:8px">
<!-- 设置透明背景 -->
<body style="background-color:rgba(0,0,0,0);">

看看效果:


自定义透明背景的NW.js应用

上图所示的完整HTML代码是:

<!DOCTYPE html>
<html style="border:8px solid #eeca00;border-radius:8px">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>demo</title>
</head>
<body style="background-color:rgba(0,0,0,0);">
  <div style="height:500px;font-size:40px">
    Hello World
  </div>
</body>
</html>

可拖拽

现在,这个软件不能拖动,也没有关闭、最小化、最大化窗口功能,现在我们来给这个软件添加这些功能。

添加拖拽层
想要实现拖拽,关键是使用-webkit-app-region: drag;CSS属性。上图中,蓝色横条上添加了这个属性,现在就能点它进行拖拽了。此外,在可拖拽的元素上双击,可以最大化窗口,再次双击则恢复窗口大小。

完整HTML代码如下:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport"content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible"content="ie=edge">
  <title>demo</title>
  <style>
    *{padding:0;margin:0;}
    html{border:8px solid #eeca00;border-radius:8px;}
    body{background-color:rgba(0,0,0,0);overflow:hidden;}
    .app{height:500px;font-size:40px;background:#fff;}
    .drag{height:36px;line-height:36px;font-size:14px;color:#fff;text-align:center;background:#008cee;-webkit-app-region:drag;}
    .main{height:calc(100% - 36px);display:flex;align-items:center;justify-content:center;}
  </style>
</head>

<body>
  <div class="app">
    <div class="drag">拖拽我吧</div>
    <div class="main">Hello World</div>
  </div>
</body>
</html>

窗口控制(最小化、最大化、关闭)

我们在拖拽层的右上角添加几个按钮,然后给它们注册点击事件。需要注意,因为拖拽层上设置了-webkit-app-region: drag;CSS属性,这个属性会吃掉所有的鼠标事件,比如鼠标悬浮、点击等。为了确保图中的三个按钮可以点击,我们要在被点击的元素上设置-webkit-app-region: no-drag;CSS属性,去掉drag功能,就能点击了。

窗口控制
窗口的最大化等操作,需要用到nw的API,下面是实现代码:
  let min, max, close, win
  min = document.getElementById('min')  // 最小化按钮
  max = document.getElementById('max')  // 最大化按钮
  close = document.getElementById('close')  // 关闭按钮
  win = nw.Window.get()  // 获取当前窗口实例
  min.onclick = () => {
    win.minimize()  // 窗口最小化
  }
  max.onclick = () => {
    win.maximize()  // 窗口最大化
  }
  close.onclick = () => {
    nw.App.quit()  // 关闭软件
  }

最大化窗口,是指最大化到我们设置的窗口最大尺寸。如果我们没有在package.json中设置最大尺寸,而把主页面的html元素的宽高设置为100%, 100%, 最大化时就会撑满电脑桌面的可用区域(windows平台中会排除任务栏)。此外,还有win.enterFullscreen接口可以考虑使用,这个接口使得窗口全屏显示,windows中会覆盖掉任务栏。

窗口恢复操作

之前提到拖拽条双击可以放大、再点击可以恢复,我们希望当点击“最大化”按钮后,再次点击可以恢复窗口大小。(之前的代码只实现了最大化功能)这里需要用到win.restore接口。接下来的问题是,我们该如何确定窗口当前是最大化。
如果使用 win.enterFullscreen全屏显示,那么可以通过win.isFullscreen来判断当前窗口是否全屏。
如果使用win.maximize最大化窗口,是不会触发win.isFullscreen的改变的,但是我们可以监听到窗口实例的maximize事件,而当调用win.restore触发窗口实例的restore事件。结合这两个事件就可以判断当前窗口是否最大化。
现在把窗口控制部分的js代码补充完整,如下所示:

  let min, max, close, win
  let flag = false  // 标识当前的窗口是否最大化
  min = document.getElementById('min')
  max = document.getElementById('max')
  close = document.getElementById('close')
  win = nw.Window.get()
  min.onclick = () => {
    win.minimize()
  }
  max.onclick = () => {
    if (flag) {
      win.restore()  // 如果是最大化,则恢复窗口
    } else {
      win.maximize()  // 否则,最大化窗口
    }
  }
  close.onclick = () => {
    nw.App.quit()
  }
  // 监听窗口最大化事件
  win.on('maximize', () => {
    flag = true
  })
  // 监听窗口恢复事件
  win.on('restore', () => {
    flag = false
  })

拖拽条双击放大触发的是maximize事件,双击恢复触发的是restore事件。和我们上面实现的点击按钮的功能完全兼容,可以随意的操作窗口了。但是如果使用win.isFullscreen,它和拖拽条的双击功能并不兼容。

动态设置窗口最大尺寸

前面提到

如果我们没有在package.json中设置最大尺寸,而把主页面的html元素的宽高设置为100%, 100%, 最大化时就会撑满电脑桌面的可用区域(windows平台中会排除任务栏)。

我们可以使用win.setMaximumSize接口动态设置窗口的最大尺寸,调用的时候把最大宽和最大高的数值传递进去,比如:

let { availHeight, availWidth } = win.window.screen  // 获取电脑桌面的可用高度和可用宽度(排除任务栏)
win.setMaximumSize(availWidth, availHeight)   // 设置窗口的最大尺寸
win.maximize()  // 进行最大化操作

结束。

上一篇下一篇

猜你喜欢

热点阅读