使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转)


Posted in Javascript onOctober 23, 2018

现在什么都讲究追赶潮流,觉得 QQ 登录窗口做的效果不错,既然刚学习 electron ,那么就用 electron 模仿一下。其实主要用到的就是 CSS3 的效果:边框圆角、阴影,3D变换。对,就这么简单。先上效果:

使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转)

下面是关键代码:

app.js

'use strict';
const { app, BrowserWindow } = require('electron')
const path = require('path')
const url = require('url')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
function createWindow() {
  // Create the browser window.
  win = new BrowserWindow({
    width: 495, height: 470, /*skipTaskbar: true,*/ frame: false,
    resizable: false, transparent: true, show: false, alwaysOnTop: true
  })
  win.once('ready-to-show', () => {
    win.show()
  })
  // and load the index.html of the app.
  win.loadURL(url.format({
    pathname: path.join(__dirname, '/app/index.html'),
    protocol: 'file:',
    slashes: true
  }))
  // Open the DevTools.
  //win.webContents.openDevTools()
  // Emitted when the window is closed.
  win.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    win = null
  })
}
//app.disableHardwareAcceleration();
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) {
    createWindow()
  }
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

index.html

<!DOCTYPE html>
<html style="margin:0; padding:0;height:100%;">
<head>
  <meta charset="UTF-8">
  <title>QQ Login</title>
  <style>
    html, body {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
    }

    body {
      perspective: 800px;
      -webkit-app-region: drag;
      -webkit-user-select: none;
    }

    input[type="submit"],
    input[type="reset"],
    input[type="button"],
    input[type="text"],
    button,
    textarea {
      -webkit-app-region: no-drag;
    }

    .shadow {
      box-shadow: 0 0 10px rgba(0, 0, 0, 1);
      position: absolute;
      width: 100%;
      height: 100%;
      border-radius: 4px;
    }

    #login-back {
      position: relative;
      border-radius: 3px 3px 0 0;
      left: 0;
      right: 0;
      height: 180px;
    }

    #card {
      left: 33px;
      top: 70px;
      right: 33px;
      bottom: 70px;
      background-color: #ebf2f9;
      position: absolute;
      -webkit-transition: -webkit-transform .6s ease-in-out;
      transition: transform .6s ease-in-out;
      -webkit-transform-style: preserve-3d;
      transform-style: preserve-3d;
      border-radius: 4px;
    }

      #card.flipped {
        -webkit-transform: rotateY( 180deg );
        transform: rotateY( 180deg );
      }

      #card .front {
        background: url(imgs/login-back.gif) no-repeat;
        background-size: 100% 180px;
        position: absolute;
        transform: rotateY(0deg);
      }

      #card .back {
        position: absolute;
        background: url(imgs/login-back.gif) no-repeat;
        background-size: 100% 180px;
        -webkit-transform: rotateY( -180deg );
        transform: rotateY( -180deg );
        -webkit-backface-visibility: hidden;
        backface-visibility: hidden;
        z-index:2;
      }

    .sys-control-box {
      float:right;
      width:84px;
      border-radius: 0 3px 0 0;
    }

    .sys-btn {
      width: 28px;
      height: 28px;
      border: none;
      outline: none;
      margin: 0;
    }

    .sys-btn-mini {
      background: url(imgs/btn_mini_normal.png) no-repeat;
    }

      .sys-btn-mini:hover {
        background: url(imgs/btn_mini_highlight.png) no-repeat;
      }

      .sys-btn-mini:active {
        background: url(imgs/btn_mini_down.png) no-repeat;
      }

    .sys-btn-close {
      border-radius: 0 3px 0 0;
      background: url(imgs/btn_close_normal.png) no-repeat;
    }

      .sys-btn-close:hover {
        background: url(imgs/btn_close_highlight.png) no-repeat;
      }

      .sys-btn-close:active {
        background: url(imgs/btn_close_down.png) no-repeat;
      }

    .sys-btn-set {
      background: url(imgs/btn_set_normal.png) 1px 0 no-repeat;
    }

      .sys-btn-set:hover {
        background: url(imgs/btn_set_hover.png) 1px 0 no-repeat;
      }

      .sys-btn-set:active {
        background: url(imgs/btn_set_press.png) 1px 0 no-repeat;
      }

    .btn {
      width: 78px;
      height: 28px;
      background: url(imgs/setting_btn_normal.png) no-repeat;
      background-size: 100% 100%;
      border: none;
      outline: none;
      margin: 0;
    }

      .btn:hover, .btn:active {
        background: url(imgs/setting_btn_hover.png) no-repeat;
        background-size: 100% 100%;
      }

      .btn:focus {
        background: url(imgs/setting_btn_hover.png) no-repeat;
        background-size: 100% 100%;
      }
  </style>
</head>
<body>
  <div id="card">
    <div id="front" class="front shadow">
      <div class="sys-control-box">
        <button id="btn-set" class="sys-btn sys-btn-set" title="设置"></button><button class="sys-btn sys-btn-mini" title="最小化"></button><button class="sys-btn sys-btn-close" title="关闭"></button>
      </div>
    </div>
    <div id="back" class="back shadow">
      <div style="width:100%;height:100%; border-radius: 4px;background:-webkit-linear-gradient(top, rgba(0, 0, 0, 0.00) 0%, rgba(0, 0, 0, 0.00) 6%, #ebf2f9 12%, #ebf2f9 90%, #cde2f2 90%, #cde2f2 100%);">
        <div class="sys-control-box" style="width:56px;">
          <button class="sys-btn sys-btn-mini" title="最小化"></button><button class="sys-btn sys-btn-close" title="关闭"></button>
        </div>
        <button id="btn-ok" style="position:absolute; right:91px; bottom:2px;" class="btn">确定</button>
        <button id="btn-cancel" style="position:absolute; right:10px; bottom:2px;" class="btn">取消</button>
      </div>
    </div>
  </div>
  <script>
    Element.prototype.hasClassName = function (a) {
      return new RegExp("(?:^|\\s+)" + a + "(?:\\s+|$)").test(this.className);
    };

    Element.prototype.addClassName = function (a) {
      if (!this.hasClassName(a)) {
        this.className = [this.className, a].join(" ");
      }
    };

    Element.prototype.removeClassName = function (b) {
      if (this.hasClassName(b)) {
        var a = this.className;
        this.className = a.replace(new RegExp("(?:^|\\s+)" + b + "(?:\\s+|$)", "g"), " ");
      }
    };

    Element.prototype.toggleClassName = function (a) {
      this[this.hasClassName(a) ? "removeClassName" : "addClassName"](a);
    };

    //var init = function () {
    //  var card = document.getElementById('card');

    //  document.getElementById('front').addEventListener('click', function () {
    //    card.toggleClassName('flipped');
    //  }, false);

    //  document.getElementById('back').addEventListener('click', function () {
    //    card.toggleClassName('flipped');
    //  }, false);
    //};

    //window.addEventListener('DOMContentLoaded', init, false);
    (function () {

      const remote = require('electron').remote;

      function init() {

        function flip() {
          if (frontShow == 2) {
            document.getElementById('front').style.display = 'block';
          }
          else {
            document.getElementById('back').style.display = 'block';
          }
          card.toggleClassName('flipped');
        };

        var btn_minis = document.getElementsByClassName("sys-btn-mini");
        for (var i = 0; i < btn_minis.length; i++) {
          btn_minis[i].addEventListener("click", function (e) {
            const window = remote.getCurrentWindow();
            window.minimize();
          });
        }

        //document.getElementById("sys-btn-maxi").addEventListener("click", function (e) {
        //  const window = remote.getCurrentWindow();
        //  if (!window.isMaximized()) {
        //    window.maximize();
        //  } else {
        //    window.unmaximize();
        //  }
        //});

        var btn_closes = document.getElementsByClassName("sys-btn-close");
        for (var i = 0; i < btn_closes.length; i++) {
          btn_closes[i].addEventListener("click", function (e) {
            const window = remote.getCurrentWindow();
            window.close();
          });
        }   

        var card = document.getElementById('card');
        var frontShow = 1;

        var btn_sets = document.getElementsByClassName("sys-btn-set");
        for (var i = 0; i < btn_sets.length; i++) {
          btn_sets[i].addEventListener('click', function () { flip(); }, false);
        } 

        card.addEventListener('transitionend', function () {
          if (frontShow == 1) {
            frontShow = 2;
            document.getElementById('front').style.display = 'none';
          }
          else {
            document.getElementById('back').style.display = 'none';
            frontShow = 1;
          }
        }, false);

        document.getElementById('btn-ok').addEventListener('click', function () { flip(); }, false);
        document.getElementById('btn-cancel').addEventListener('click', function () { flip(); }, false);
      };

      document.onreadystatechange = function () {
        if (document.readyState == "complete") {
          init();
        }
      };
    })();
  </script>
</body>
</html>

最后整个项目的源代码:https://github.com/starts2000/ElectronQQLogin

总结

以上所述是小编给大家介绍的使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js创建对象的几种常用方式小结(推荐)
Oct 24 Javascript
JavaScript:Div层拖动效果实例代码
Aug 06 Javascript
js实现局部页面打印预览原理及示例代码
Jul 03 Javascript
javascript学习笔记(七)Ajax和Http状态码
Oct 08 Javascript
基于jquery实现页面滚动到底自动加载数据的功能
Dec 19 Javascript
JavaScript接口的实现三种方式(推荐)
Jun 14 Javascript
AngularJS 在同一个界面启动多个ng-app应用模块详解
Dec 20 Javascript
深入学习jQuery中的data()
Dec 22 Javascript
ajax实现加载页面、删除、查看详细信息 bootstrap美化页面!
Mar 14 Javascript
详解AngularJS1.6版本中ui-router路由中/#!/的解决方法
May 22 Javascript
vue-cli项目如何使用vue-resource获取本地的json数据(模拟服务端返回数据)
Aug 04 Javascript
BootStrap实现文件上传并带有进度条效果
Sep 11 Javascript
解决JavaScript中0.1+0.2不等于0.3问题
Oct 23 #Javascript
React 路由懒加载的几种实现方案
Oct 23 #Javascript
react 兄弟组件如何调用对方的方法示例
Oct 23 #Javascript
详解React 的几种条件渲染以及选择
Oct 23 #Javascript
详解create-react-app 2.0版本如何启用装饰器语法
Oct 23 #Javascript
彻底弄懂 JavaScript 执行机制
Oct 23 #Javascript
深入理解JavaScript 中的执行上下文和执行栈
Oct 23 #Javascript
You might like
PHP session会话的安全性分析
2011/09/08 PHP
基于PHP array数组的教程详解
2013/06/05 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
php实现图片等比例缩放代码
2015/07/23 PHP
详解PHP执行定时任务的实现思路
2015/12/21 PHP
PHP控制反转(IOC)和依赖注入(DI)
2017/03/13 PHP
php读取本地json文件的实例
2018/03/07 PHP
关于Javascript 的 prototype问题。
2007/01/03 Javascript
Javascript 模式实例 观察者模式
2009/10/24 Javascript
jquery插件制作简单示例说明
2012/02/03 Javascript
JQuery操作表格(隔行着色,高亮显示,筛选数据)
2012/02/23 Javascript
如何使用Jquery获取Form表单中被选中的radio值
2013/08/09 Javascript
jquery解析JSON数据示例代码
2014/03/17 Javascript
jQuery select表单提交省市区城市三级联动核心代码
2014/06/09 Javascript
JavaScript设计模式之装饰者模式介绍
2014/12/28 Javascript
JQuery分屏指示器图片轮换效果实例
2015/05/21 Javascript
jQuery点击按钮弹出遮罩层且内容居中特效
2015/12/14 Javascript
在JavaScript中模拟类(class)及类的继承关系
2016/05/20 Javascript
JavaScript实现经典排序算法之插入排序
2016/12/28 Javascript
IScroll5实现下拉刷新上拉加载的功能实例
2017/08/11 Javascript
详解JSON和JSONP劫持以及解决方法
2019/03/08 Javascript
基于html+css+js实现简易计算器代码实例
2020/02/28 Javascript
在centos7中分布式部署pyspider
2017/05/03 Python
python方向键控制上下左右代码
2018/01/20 Python
spark: RDD与DataFrame之间的相互转换方法
2018/06/07 Python
tensorflow实现加载mnist数据集
2018/09/08 Python
Python_查看sqlite3表结构,查询语句的示例代码
2019/07/17 Python
Python requests设置代理的方法步骤
2020/02/23 Python
KEETSA环保床垫:更好的睡眠,更好的生活!
2016/11/24 全球购物
复古服装:RetroStage
2019/05/10 全球购物
UNIX文件系统分类
2014/11/11 面试题
李敖北大演讲稿
2014/05/24 职场文书
党员自我对照检查材料
2014/08/19 职场文书
社会体育专业大学生职业生涯规划书
2014/09/17 职场文书
学会掌握自己命运的十条黄金法则:
2019/08/08 职场文书
Valheim服务器 Mod修改安装教程 【ValheimPlus】
2022/12/24 Servers