码迷,mamicode.com
首页 > Windows程序 > 详细

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

时间:2018-12-23 13:55:38      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:ase   -o   length   架构   UNC   name   float   .sh   get   

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

技术分享图片

下面是关键代码:

app.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
‘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

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
<!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;
       padding: 0px 0px 0px 5px; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; border-left: 3px solid rgb(108, 226, 108); line-height: 20px; width: 640px; clear: both; outline: 0px !important; border-radius: 0px !important; border-top: 0px !important; border-right: 0px !important; border-bottom: 0px !important; border-image: initial !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; overflow: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; box-sizing: content-box !important; font-family: Consolas, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; min-height: auto !important; color: gray !important;">#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

 

   
技术分享图片 珠峰Node.js全栈开发  ...2
技术分享图片 彻底征服 React.js 技术分享图片
技术分享图片 腾讯大牛亲授 Web 前后端漏洞分析与防御技巧 技术分享图片  ...2
技术分享图片 前端JavaScript面试技巧
技术分享图片 2017最新apicloud全集(从基础到实战 6个实战项目) 技术分享图片
技术分享图片 WEB 开发 LoadRunner使用指南 学习资料
技术分享图片 让你惊叹不已的HTML5画布Canvas绘图技术应用详解  ...2
技术分享图片 GPS车辆监控系统开发必备技术之WebGIS架构技术入门到实践
技术分享图片 深入浅出JavaScript入门到精通实战式教学视频全套教程  ...2
技术分享图片 老司机带你深入webpack原理与实战  ...2
技术分享图片 AngularJS的移动端解决方案,Ionic和AngularJS完美融合开发原生iOS或安卓App
技术分享图片 MUI APP全接触 MUI基础+交互原理深入解读MUI 开发APP视频教程
技术分享图片 AngularJS的移动端解决方案,Ionic和AngularJS完美融合开发原生iOS或安卓App
技术分享图片 Angular企业协作平台视频教程下载  ...2
技术分享图片 2017年Web前端开发整站模块化布局项目实战视频教程html5/CSS3/js
技术分享图片 基于 Vue.js 2.0 的 UI 组件库快速开发一个 Vue.js Web 应用 Element UI 视频教程
技术分享图片 vue.js2.0基于MVVM框架(Vuex+Vue Router+axios+jsonp+webpack 2.0+es6)全家桶技...  ...2
技术分享图片 2017年最权威的1000集大型web前端视频教程
技术分享图片 零基础轻松学好Bootstrap 兄弟连+云知梦+番茄课堂+其他Bootstrap 视频教程合集 技术分享图片
技术分享图片 基于Nodejs的Meteor全栈开发平台实时Web APP开发框架从零开始快速开一个Web APP应用

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

标签:ase   -o   length   架构   UNC   name   float   .sh   get   

原文地址:https://www.cnblogs.com/xanthedsf/p/10163936.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!