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

使用 Electron 实现类似新版 QQ 的登录界面效果,需要注意以下几点:

1. 创建 Electron 项目

使用命令行创建一个新的 Electron 项目,进入项目文件夹后安装必要的依赖:

# 初始化项目
npm init
# 安装 electron
npm install electron --save
# 安装 jquery 和 bootstrap
npm install jquery bootstrap --save

为了实现窗体的旋转效果,我们使用 CSS 3D Transform 这个特性。这里我们还需要引入一个元素,使得窗体可以进行翻转。我使用的是 Flipster,一个 jQuery 插件。安装 Flipster:

npm install flipster --save

2. 编写登录窗口的 HTML 和 CSS

在项目的根目录下,创建一个名为 index.html 的文件,并添加下面的 html 代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>QQ Login</title>
    <!-- 引入 bootstrap 样式文件 -->
    <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css">
    <!-- 引入 flipster 样式文件 -->
    <link rel="stylesheet" href="./node_modules/flipster/dist/jquery.flipster.min.css">
    <!-- 引入自己的样式文件 -->
    <link rel="stylesheet" href="./src/style.css">
</head>
<body>
    <div class="container">
        <div class="login-form-wrapper">
            <form class="login-form">
                <h3>Please Login</h3>
                <div class="form-group">
                    <input type="text" placeholder="Username" class="form-control">
                </div>
                <div class="form-group">
                    <input type="password" placeholder="Password" class="form-control">
                </div>
                <button type="submit" class="btn btn-primary">Login</button>
            </form>
            <!-- 构建翻转窗体 -->
            <ul id="flipster-wrapper">
                <li><img src="./res/1.jpg"></li>
                <li><img src="./res/2.jpg"></li>
                <li><img src="./res/3.jpg"></li>
                <li><img src="./res/4.jpg"></li>
            </ul>
        </div>
    </div>
    <!-- 引入 jQuery -->
    <script src="./node_modules/jquery/dist/jquery.min.js"></script>
    <!-- 引入 bootstrap.js -->
    <script src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- 引入 flipster.js -->
    <script src="./node_modules/flipster/dist/jquery.flipster.min.js"></script>
    <!-- 引入自己的脚本文件 -->
    <script src="./src/main.js"></script>
</body>
</html>

接下来在项目的根目录下,创建一个名为 style.css 的样式文件,并添加下列代码:

body {
    margin: 0;
    background-color: #f3f3f3;
    font-family: 'Roboto', sans-serif;
}

.container {
    background-color: transparent;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}

.login-form-wrapper {
    position: absolute;
    width: 450px;
    height: 400px;
    background-color: #fff;
    box-shadow: 0 2px 8px rgba(102, 119, 136, 0.1);
    border-radius: 3px;
    overflow: hidden;
}

.login-form-wrapper .login-form {
    padding: 30px;
}

.login-form-wrapper h3 {
    margin-top: 0;
    margin-bottom: 20px;
    font-size: 24px;
    font-weight: 400;
    color: #333;
}

.form-group {
    margin-bottom: 20px;
}

.form-control {
    box-shadow: none;
    border-radius: 2px;
    border-color: #dcdcdc;
    height: 50px;
    font-size: 16px;
}

.btn-primary {
    background-color: #007bff;
    border-color: #007bff;
    padding: 12px 18px;
    font-size: 16px;
    border-radius: 2px;
}

.btn-primary:hover {
    background-color: #0069d9;
}

/* 翻转窗体相关 */
#flipster-wrapper {
    margin: 70px auto 0;
}

#flipster-wrapper li {
    margin-bottom: 20px;
    border-radius: 2px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

#flipster-wrapper img {
    display: block;
    width: 100%;
    border-radius: 2px;
}

3. 编写 Electron 主进程代码和渲染进程代码

需要注意的是,我们需要使用 这个标签来开启和禁用部分 Electron 特性来达到最佳的运行效果。

在根目录下,创建一个名为 main.js 的文件,添加如下代码:

const { app, BrowserWindow } = require('electron')

let mainWindow = null

app.on('ready', function() {
    mainWindow = new BrowserWindow({
        width: 450,
        height: 400,
        frame: false, // 隐藏默认窗口栏
        resizable: false, // 禁止窗口大小缩放
        transparent: true, // 窗口透明
        show: false, // 创建窗口时先不显示
        webPreferences: {
            nodeIntegration: true // 开启 Node.js
        }
    })

    // 加载 HTML 文件
    mainWindow.loadFile('./index.html')

    // 当最初的 html 文件加载完成时触发
    mainWindow.once('ready-to-show', () => {
        mainWindow.show() // 显示窗口
    })

    // 监听渲染器进程发来的 ipc 消息
    const { ipcMain } = require('electron')
    ipcMain.on('window-close', () => {
        if (mainWindow !== null) {
            mainWindow.close()
        }
    })
})

在根目录下,创建一个名为 renderer.js 的文件,添加如下代码:

$(function () {
    // 初始化 flipster
    $('#flipster-wrapper').flipster({
        style: 'carousel',
        spacing: -0.5,
        buttons: true,
        nav: false,
        start: 1,
        loop: true
    })

    // 窗口拖动
    var _electron = require('electron')
    var remote = _electron.remote
    var win = remote.getCurrentWindow()
    var drag = document.querySelector('.login-form-wrapper')

    drag.addEventListener('mousedown', function (e) {
        if (e.button !== 0) {
            return
        }

        win.setIgnoreMouseEvents(true)
        var mousePos = null

        document.addEventListener('mousemove', moveCallback, true)
        document.addEventListener('mouseup', mouseupCallback, true)

        function moveCallback (e) {
            e.preventDefault()

            var pos
            if (mousePos === null) {
                mousePos = {
                    x: e.screenX,
                    y: e.screenY
                }
            } else {
                pos = {
                    x: e.screenX - mousePos.x,
                    y: e.screenY - mousePos.y
                }

                win.setPosition(remote.screen.getCursorScreenPoint().x - pos.x, remote.screen.getCursorScreenPoint().y - pos.y)
            }

            mousePos = {
                x: e.screenX,
                y: e.screenY
            }
        }

        function mouseupCallback () {
            win.setIgnoreMouseEvents(false)
            document.removeEventListener('mousemove', moveCallback, true)
            document.removeEventListener('mouseup', mouseupCallback, true)
        }
    })
})

4. 编写菜单和 ipc 监听器

const { Menu, MenuItem } = require('electron')
const { app, BrowserWindow, ipcMain } = require('electron')

app.on('ready', function() {
    const mainWindow = new BrowserWindow({
        width: 700,
        height: 500,
        webPreferences: {
            nodeIntegration: true
        }
    })

    mainWindow.loadFile('index.html')

    mainWindow.webContents.on('did-finish-load', () => {
        const menu = Menu.buildFromTemplate([
            {
                label: 'File',
                submenu: [
                    {
                        label: 'Close',
                        accelerator: 'CmdOrCtrl+W',
                        click() {
                            mainWindow.close()
                        }
                    }
                ]
            },
            {
                label: 'Edit',
                submenu: [
                    {
                        label: 'Undo',
                        accelerator: 'CmdOrCtrl+Z',
                        selector: 'undo:'
                    },
                    {
                        label: 'Redo',
                        accelerator: 'Shift+CmdOrCtrl+Z',
                        selector: 'redo:'
                    },
                    {
                        type: 'separator'
                    },
                    {
                        label: 'Copy',
                        accelerator: 'CmdOrCtrl+C',
                        selector: 'copy:'
                    },
                    {
                        label: 'Cut',
                        accelerator: 'CmdOrCtrl+X',
                        selector: 'cut:'
                    },
                    {
                        label: 'Paste',
                        accelerator: 'CmdOrCtrl+V',
                        selector: 'paste:'
                    },
                    {
                        label: 'Select All',
                        accelerator: 'CmdOrCtrl+A',
                        selector: 'selectAll:'
                    }
                ]
            }
        ])

        ipcMain.on('show-context-menu', (event) => {
            event.preventDefault()
            menu.popup({ window: mainWindow })
        })

        mainWindow.webContents.on('context-menu', (event) => {
            event.preventDefault()
            ipcMain.emit('show-context-menu', event)
        })
    })
})

5. 运行

最后,打开终端,进入项目根目录下,运行以下命令启动应用:

npm start

应用启动后,可以看到类似 QQ 登录界面的效果,窗体可以旋转,同时支持菜单和 ipc 监听器。

示例1: 参考代码

示例2: 参考代码

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转) - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 利用jQuery实现可输入搜索文字的下拉框

    实现可输入搜索文字的下拉框是前端开发中常见的需求,下面我将分享一份利用jQuery实现该功能的攻略。 步骤一:编写HTML结构 首先,我们需要在HTML中定义一个搜索输入框和一个下拉框,具体的结构如下: <input id="search-input" type="text" placeholder="…

    css 2023年6月10日
    00
  • Vue-cli 移动端布局和动画使用详解

    Vue-cli 是一个专门为Vue.js 框架开发的脚手架工具,它可以方便快捷地创建和管理 Vue 项目。本文将详细讲解如何在 Vue 项目中进行移动端布局和动画的使用。 移动端布局 使用 vw/vh CSS3 中为我们提供了两种新的单位:vw 和 vh。其中,vw 为视口宽度的百分比单位,vh 为视口高度的百分比单位。通过使用这两个单位来实现布局时,可以避…

    css 2023年6月10日
    00
  • div+css纵向导航如何实现且为导航添加超链接

    在网页前端开发中,纵向导航是非常常见的一种导航方式。下面是一个完整的攻略,包含了如何使用 div+css 实现纵向导航以及如何为导航添加超链接的过程和两个示例说明。 使用 div+css 实现纵向导航 1. 创建 HTML 结构 首先,我们需要创建一个 HTML 结构,用于容纳纵向导航。下面是一个简单的 HTML 结构示例: <div class=&q…

    css 2023年5月18日
    00
  • 前端开发工程师和美工对于网站开发所掌握的知识的区别

    前端开发工程师和美工在网站开发中扮演的角色不同,因此他们所掌握的知识也有所区别。 前端开发工程师 岗位职责 前端开发工程师负责制作网站的前端页面效果,在网站前端开发过程中,需要掌握 HTML、CSS、JavaScript 等技术,能够开发响应式网站,并与后端工程师协作,实现网站的页面交互效果。 相关技能 HTML技能:熟悉基本的HTML5语法,并能够熟练使用…

    css 2023年6月10日
    00
  • 深入理解CSS中的line-height的使用

    深入理解CSS中的line-height的使用 在CSS中,line-height是一个非常重要的属性,它用于设置行高。本攻略将详细讲解line-height的使用,包括基本原理、使用方法和示例说明。 1. 基本原理 line-height属性用于设置行高,它可以接受以下值: normal:默认值,使用浏览器的默认行高。 数字:设置行高为字体大小的倍数。 长…

    css 2023年5月18日
    00
  • CSS几步实现赛博朋克2077风格视觉效果

    下面是详细讲解“CSS几步实现赛博朋克2077风格视觉效果”的完整攻略: 一、准备工作 在实现赛博朋克2077风格的视觉效果之前,我们需要做一些准备工作: 在HTML文档中引入CSS文件。 html <link rel=”stylesheet” href=”style.css”> 添加一些示例内容,便于我们观察效果。 html <div c…

    css 2023年6月9日
    00
  • css中padding和margin的异同点介绍

    CSS中padding和margin的异同点介绍 概念介绍 被称为“内边距”,padding是指元素内容边界与元素边框之间的距离。它会影响到元素的大小及内容与边框之间的间距。 被称为“外边距”,margin是指元素边框与相邻元素边框之间的距离。它会影响到元素与其他元素之间的间距。 使用方式 padding和margin可以通过简写属性和分别指定属性的方式进行…

    css 2023年6月9日
    00
  • 基于Bootstrap3表格插件和分页插件实例详解

    关于“基于Bootstrap3表格插件和分页插件实例详解”的攻略,可以按照以下步骤进行: 1. 确认所需库文件 在使用Bootstrap3表格插件和分页插件之前,需要在网页中引入相关的库文件,包括Bootstrap、jQuery和bootstrap-table等,可使用CDN或下载到本地引用。 示例引入CDN文件的代码如下: <!DOCTYPE htm…

    css 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部