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

现在什么都讲究追赶潮流,觉得 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应用

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

时间: 2024-08-25 05:28:45

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

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

上文<使用 VS2017 和 js 进行桌面程序开发 - electron 之 Hello Word>介绍了如何使用 VS2017 开发 electron 桌面程序,今天来点有看头的,但是没什么技术含量,囧~~ 现在什么都讲究追赶潮流,觉得 QQ 登录窗口做的效果不错,既然刚学习 electron ,那么就用 electron 模仿一下.其实主要用到的就是 CSS3 的效果:边框圆角.阴影,3D变换.对,就这么简单.先上效果: 下面是关键代码: app.js 'use strict'; con

iOS开发UI篇—模仿ipad版QQ空间登录界面

一.实现和步骤 1.一般ipad项目在命名的时候可以加一个HD,标明为高清版 2.设置项目的文件结构,分为home和login两个部分 3.登陆界面的设置 (1)设置第一个控制器和自定义的控制器类(登陆)关联 (2)设置控制器的view的颜色,RGB三个值都为42 (3)导入相关的素材图片 关于图片:一般给竖屏用的图片,以portrait名称标识,给横屏用的图片,以Landscape名称标识 修改plist文件,调整图片    提示:在项目中(ipad的使用中)有很多的地方都会用到图标 补充:关

仿QQ锁屏界面效果

现在新版的QQ Android客户端有个新功能,就是在锁屏界面也可以接收消息,并且接收到的消息可以显示在锁屏界面,双击之后可以进入QQ,下面简单实现这个功能. 当然正式项目中的运用还是非常复杂的,这仅仅是一个简单的Demo,可以作为参考. 直接上代码: MainActivity.java public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState)

android内部培训视频_第五节(1)_OA实战之登录界面

第五节(1):OA实战之登录界面  一.登录界面布局 1.背景图片 2.文本框 3.checkbox 4.按钮 暂未实现点击切换图片效果 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent&q

注册表----修改Win7登录界面

在进行操作前,需要准备好背景图片.对背景图片的要求有三点: (1)图片必须是JPG格式: (2)必须将图片命名为backgroundDefault; (3)图片的体积必须小于256KB. 操作子键:[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\Background] 双击OEMBackground键值项,在弹出的对话框中修改其数值数据为1,单击确定按钮. 打开目录C:\Wi

如何更换 Ubuntu 18.04 LTS 的 GDM 登录界面背景

Ubuntu 18.04 LTS 桌面系统在登录.锁屏和解锁状态下,我们会看到一个纯紫色的背景.这篇短文将会告诉你如何更换 Ubuntu 18.04 LTS 的 GDM 登录界面的背景. Ubuntu 18.04 LTS 桌面系统在登录.锁屏和解锁状态下,我们会看到一个纯紫色的背景.它是GDM(GNOME 显示管理器)从 ubuntu 17.04 版本开始使用的默认背景.有一些人可能会不喜欢这个纯色的背景,想换一个酷一点.更吸睛的!如果是这样,你找对地方了. 更换 Ubuntu 的登录界面背景

QQ第三方登录

QQ第三方登录 在Android应用程序的开发过程中,很多时候需要加入用户登录/注册模块.除了自己动手设计登录界面并实现相应功能外,现在还可以借助百度.腾讯等开发者平台提供的第三方账号登录模块.最近研究了友盟的社会化分享组件,对其提供的SDK中第三方登录的QQ模块进行了测试.本篇文章先对友盟用户注册.SDK下载及案例的下载做一个简单的介绍,然后针对测试程序的过程及代码进行详细的描述. 顺便提一点,进入友盟的主页及SDK下载页面之后,会发现其支持Android.IOS等多个环境下的应用程序开发,感

WPF简单模拟QQ登录背景动画(转)

介绍 之所以说是简单模拟,是因为我不知道QQ登录背景动画是怎么实现的.这里是通过一些办法把它简化了,做成了类似的效果 效果图 大体思路 首先把背景看成是一个4行8列的点的阵距,X轴Y轴都是距离70.把点连起来,连成三角形.布局在外层蓝色的里,显示只显示里层绿色框里的部分.这样最外层的点不用动,只让绿框里面的点做随机运动就可以了.然后给三角形的Fill做颜色和时间都随机颜色动画,动画完成后再重新做颜色动画,循环. 在实现上,需要注意一下,每个点都对应多个三角形,要在生成三角形的时候,注册到点上,并

WPF简单模拟QQ登录背景动画

介绍 之所以说是简单模拟,是因为我不知道QQ登录背景动画是怎么实现的.这里是通过一些办法把它简化了,做成了类似的效果 效果图 大体思路 首先把背景看成是一个4行8列的点的阵距,X轴Y轴都是距离70.把点连起来,连成三角形.布局在外层蓝色的里,显示只显示里层绿色框里的部分.这样最外层的点不用动,只让绿框里面的点做随机运动就可以了.然后给三角形的Fill做颜色和时间都随机颜色动画,动画完成后再重新做颜色动画,循环. 在实现上,需要注意一下,每个点都对应多个三角形,要在生成三角形的时候,注册到点上,并