原生JS与CSS实现软件卸载对话框功能


Posted in Javascript onDecember 05, 2019

今天给大家分享一个特别有意思的软件卸载对话框,鼠标在整个对话框里移动时,中间的人脸会作出不同的变化,当鼠标悬停到“保留”按钮上时,人脸的表情会变得开心,当鼠标悬停到“卸载”按钮上面时,人脸的表情会变得不开心。

实现效果如下:

原生JS与CSS实现软件卸载对话框功能

实现代码如下,首先是HTML:

<!DOCTYPE html>
<html lang="en">
<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>原生JS与CSS实现软件卸载对话框</title>
  <link rel="stylesheet" href="css/confirm.css" rel="external nofollow" >
</head>
<body>
  <section class="Confirm">
    <div class="Confirm-Header">
      <a class="Confirm-Header-Button Confirm-Header-Button_Close" href="javascript: void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ></a>
      <a class="Confirm-Header-Button Confirm-Header-Button_Minimize" href="javascript: void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ></a>
      <a class="Confirm-Header-Button Confirm-Header-Button_Maximize" href="javascript: void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ></a>
      <h1 class="Confirm-Header-Title">软件卸载</h1>
    </div>
    
    <div class="Confirm-Body">
      <h2 class="Confirm-Body-Title">是否确实要卸载软件?</h2>
      <figure class="Boi" style="--happiness:0.9; --derp:1; --px:0.5; --py:0.5;">
        <div class="Boi-Blush Boi-Blush_L"></div>
        <div class="Boi-Blush Boi-Blush_R"></div>
        <div class="Boi-Eye Boi-Eye_L"></div>
        <div class="Boi-Eye Boi-Eye_R"></div>
        <div class="Boi-Mouth"></div>
      </figure>
      <a class="Confirm-Body-Button Confirm-Body-Button_Cancel" href="javascript: void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >保留</a>
      <a class="Confirm-Body-Button Confirm-Body-Button_Delete" href="javascript: void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >卸载</a>
    </div>
  </section>
  <script src="js/confirm.js"></script>
</body>
</html>

以下是页面引入的CSS

* {
  box-sizing: border-box;
  font: inherit;
}
 
html {
  color: #333;
  font-size: 62.5%;
}
 
@media screen and (max-width: 480px) {
  html {
    font-size: 50%;
  }
}
 
html body {
  font-size: 2rem;
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  background-image: linear-gradient(to left bottom, #444, #222);
  font-family: 'Rubik', sans-serif;
}
 
.Confirm {
  position: absolute;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 72rem;
  max-width: 100%;
  min-width: 34rem;
  max-height: 100%;
  height: 46rem;
  background-color: #ccc;
  border-radius: 1rem;
  box-shadow: 0px 10px 5px -3px rgba(0, 0, 0, 0.2);
}
 
.Confirm-Header {
  display: flex;
  align-items: center;
  position: relative;
  flex: 0 0 4rem;
  margin: 0 1rem;
  border-bottom: solid 1px rgba(0, 0, 0, 0.1);
  white-space: nowrap;
}
 
.Confirm-Header-Button {
  display: block;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 1rem;
  flex: 0 0 auto;
  transition: background-color 0.3s;
}
 
.Confirm-Header-Button:not(:last-of-type) {
  margin-right: 1rem;
}
 
.Confirm-Header-Button_Close {
  background-color: #a43;
}
 
.Confirm-Header-Button_Close:hover {
  background-color: #c85a48;
}
 
.Confirm-Header-Button_Maximize {
  background-color: #cb3;
}
 
.Confirm-Header-Button_Maximize:hover {
  background-color: #d6c95c;
}
 
.Confirm-Header-Button_Minimize {
  background-color: #6a4;
}
 
.Confirm-Header-Button_Minimize:hover {
  background-color: #81c061;
}
 
.Confirm-Header-Title {
  margin: 0;
  padding: 0;
  transform: translateX(50%);
  margin-right: 50%;
  margin-left: auto;
}
 
.Confirm-Body {
  flex: 1;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  position: relative;
  margin: 2rem 4rem;
}
 
.Confirm-Body-Title {
  margin: 0;
  padding: 0;
  position: absolute;
  transform: translateY(-50%);
  top: 5%;
  text-align: center;
  width: 100%;
}
 
.Confirm-Body-Button,
.Confirm-Body-Button:link,
.Confirm-Body-Button:visited {
  color: #fff;
  border-radius: 1rem;
  text-decoration: none;
  padding: 1rem 2rem;
  margin-bottom: 1rem;
  min-width: 10rem;
  text-align: center;
  transition: background-color 0.3s;
}
 
.Confirm-Body-Button_Delete {
  background-color: #a43;
}
 
.Confirm-Body-Button_Delete:hover {
  background-color: #c85a48;
}
 
.Confirm-Body-Button_Cancel {
  background-color: #6a4;
}
 
.Confirm-Body-Button_Cancel:hover {
  background-color: #81c061;
}
 
.Boi {
  --happiness: 0.9;
  --derp: 1;
  --px: 0.5;
  --py: 0.5;
  width: 22rem;
  max-width: 100%;
  height: 22rem;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-image: radial-gradient(#f7e0b2, #eb5);
  border-radius: 100%;
  overflow: hidden;
  margin: 0;
  align-self: center;
  flex: 0 0 auto;
  border: solid 2px #ecb23e;
  box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
}
 
.Boi,
.Boi * {
  position: absolute;
}
 
.Boi::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background-image: linear-gradient(to bottom, #5a8, rgba(85, 170, 136, 0));
  opacity: calc(1 - var(--happiness));
}
 
.Boi-Blush {
  width: 20%;
  height: 10%;
  background-color: rgba(255, 100, 100, 0.3);
  border: 3px solid rgba(255, 100, 100, 0.3);
  top: calc(45% + var(--py) * 10%);
  border-radius: 100%;
  opacity: calc(var(--happiness) * var(--happiness) * 0.9 + 0.1);
}
 
.Boi-Blush_L {
  left: calc(7% + var(--px) * 2%);
}
 
.Boi-Blush_R {
  right: calc(9% - var(--px) * 2%);
}
 
.Boi-Eye {
  width: calc(26% - var(--happiness) * 2%);
  height: calc(26% - var(--happiness) * 2%);
  background-color: #f6f6f6;
  border-radius: 100%;
  top: calc(25% + var(--py) * 10%);
  overflow: hidden;
}
 
.Boi-Eye_L {
  left: calc(18% + var(--px) * 4%);
}
 
.Boi-Eye_L::after {
  transform: translate(calc((var(--px) + var(--derp) * 0.5) * 100%), calc((var(--py) + var(--derp) * 0.5) * 100%));
}
 
.Boi-Eye_R {
  right: calc(22% - var(--px) * 4%);
}
 
.Boi-Eye_R::after {
  transform: translate(calc((var(--px) + var(--derp) * -0.3) * 100%), calc((var(--py) + var(--derp) * -0.3) * 100%));
}
 
.Boi-Eye::after {
  content: '';
  display: block;
  background-color: #421;
  width: calc(55% - var(--happiness) * 10%);
  height: calc(55% - var(--happiness) * 10%);
  border-radius: 100%;
}
 
.Boi-Mouth {
  width: calc(51% - var(--happiness) * 2%);
  height: calc(26% - var(--happiness) * 2%);
  background-color: #a33;
  border-radius: calc((1 - var(--happiness)) * 10em) calc((1 - var(--happiness)) * 10em) calc(var(--happiness) * 16em) calc(var(--happiness) * 16em);
  top: calc(57.5% + var(--py) * 5%);
  left: calc(47.5% + var(--px) * 5%);
  transform: translateX(-50%);
  overflow: hidden;
  border: 3px solid #962d2d;
  -webkit-mask-image: -webkit-radial-gradient(white, black);
}
 
.Boi-Mouth::before {
  content: '';
  display: block;
  position: absolute;
  width: 20%;
  height: 20%;
  top: 0;
  left: 50%;
  background-color: white;
  border-radius: 0 0 0.5rem 0.5rem;
}
 
.Boi-Mouth::after {
  content: '';
  display: block;
  position: absolute;
  width: 60%;
  height: 50%;
  left: 10%;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 20rem 20rem 0 0;
}

以下是页面引入的JS

const confirm = document.querySelector('.Confirm');
const boi = document.querySelector('.Boi');
const btnDelete = document.querySelector('.Confirm-Body-Button_Delete');
const btnCancel = document.querySelector('.Confirm-Body-Button_Cancel');
const current = {
  happiness: 0.9,
  derp: 1,
  px: 0.5,
  py: 0.5
};
const target = { ...current };
 
confirm.addEventListener('mousemove', onMouseMove);
confirm.addEventListener('mouseleave', onMouseLeave);
 
function onMouseMove({ clientX: x, clientY: y }) {
  let dx1 = x - btnDelete.getBoundingClientRect().x - btnDelete.getBoundingClientRect().width * 0.5;
  let dy1 = y - btnDelete.getBoundingClientRect().y - btnDelete.getBoundingClientRect().height * 0.5;
  let dx2 = x - btnCancel.getBoundingClientRect().x - btnCancel.getBoundingClientRect().width * 0.5;
  let dy2 = y - btnCancel.getBoundingClientRect().y - btnCancel.getBoundingClientRect().height * 0.5;
  let px = (x - confirm.getBoundingClientRect().x) / confirm.getBoundingClientRect().width;
  let py = (y - confirm.getBoundingClientRect().y) / confirm.getBoundingClientRect().height;
  let distDelete = Math.sqrt(dx1 * dx1 + dy1 * dy1);
  let distCancel = Math.sqrt(dx2 * dx2 + dy2 * dy2);
  let happiness = Math.pow(distDelete / (distCancel + distDelete), 0.75);
 
  target.happiness = happiness;
  target.derp = 0;
  target.px = px;
  target.py = py;
}
 
function onMouseLeave() {
  target.happiness = 0.9;
  target.derp = 1;
  target.px = 0.5;
  target.py = 0.5;
}
 
function update() {
  for (let prop in target) {
    if (target[prop] === current[prop]) {
      continue;
    } else if (Math.abs(target[prop] - current[prop]) < 0.01) {
      current[prop] = target[prop];
    } else {
      current[prop] += (target[prop] - current[prop]) * 0.1;
    }
    boi.style.setProperty(`--${prop}`, current[prop]);
  }
  requestAnimationFrame(update);
}
 
update();

总结

以上所述是小编给大家介绍的原生JS与CSS实现软件卸载对话框功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
ajaxControlToolkit AutoCompleteExtender的用法
Oct 30 Javascript
jquery验证表单中的单选与多选实例
Aug 18 Javascript
javascript事件委托的方式绑定详解
Jun 10 Javascript
JavaScript淡入淡出渐变简单实例
Aug 06 Javascript
JavaScript+CSS无限极分类效果完整实现方法
Dec 22 Javascript
jQuery的Read()方法代替原生JS详解
Nov 08 Javascript
jQuery 选择符详细介绍及整理
Dec 02 Javascript
微信小程序微信支付接入开发实例详解
Apr 12 Javascript
vue 权限认证token的实现方法
Jul 17 Javascript
JavaScript生成一个不重复的ID的方法示例
Sep 16 Javascript
iview form清除校验状态的实现
Sep 19 Javascript
详解Javascript实践中的命令模式
May 05 Javascript
Vue快速实现通用表单验证功能
Dec 05 #Javascript
Vue组件通信中非父子组件传值知识点总结
Dec 05 #Javascript
基于javascript实现贪吃蛇经典小游戏
Apr 10 #Javascript
微信小程序登录时如何获取input框中的内容
Dec 04 #Javascript
微信小程序日历插件代码实例
Dec 04 #Javascript
微信小程序request请求封装,验签代码实例
Dec 04 #Javascript
vue中使用极验验证码的方法(附demo)
Dec 04 #Javascript
You might like
PHP在XP下IIS和Apache2服务器上的安装
2006/09/05 PHP
PHP判断网络文件是否存在的方法
2015/03/12 PHP
PHP实现微信对账单处理
2018/10/01 PHP
PHP使用mongoclient简单操作mongodb数据库示例
2019/02/08 PHP
11款新鲜的jQuery插件[附所有demo下载]
2011/01/24 Javascript
Javascript学习笔记之数组的构造函数
2014/11/23 Javascript
浅谈JS原型对象和原型链
2016/03/02 Javascript
详细谈谈javascript的对象
2016/07/31 Javascript
js判断是否是手机页面
2017/03/17 Javascript
详解在vue-cli项目中安装node-sass
2017/06/21 Javascript
关于Vue单页面骨架屏实践记录
2017/12/13 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
JS div匀速移动动画与变速移动动画代码实例
2019/03/26 Javascript
vue-router 前端路由之路由传值的方式详解
2019/04/30 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
js实现无缝滚动双图切换效果
2019/07/09 Javascript
Vue2.0 ES6语法降级ES5的操作
2020/10/30 Javascript
在Python的Django框架的视图中使用Session的方法
2015/07/23 Python
深入解析Python中的__builtins__内建对象
2016/06/21 Python
理论讲解python多进程并发编程
2018/02/09 Python
PyQt5每天必学之布局管理
2018/04/19 Python
python微元法计算函数曲线长度的方法
2018/11/08 Python
浅谈django url请求与数据库连接池的共享问题
2019/08/29 Python
PyCharm搭建Spark开发环境的实现步骤
2019/09/05 Python
Python3利用scapy局域网实现自动多线程arp扫描功能
2021/01/21 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
美的官方商城:Midea
2016/09/14 全球购物
旅游管理专业学生求职信
2013/09/28 职场文书
财务管理专业自荐信范文
2013/12/24 职场文书
如何写好升职自荐信
2014/01/06 职场文书
冬季安全检查方案
2014/05/23 职场文书
店长岗位职责
2015/02/11 职场文书
男生贾里读书笔记
2015/06/30 职场文书
python通配符之glob模块的使用详解
2021/04/24 Python
golang 生成对应的数据表struct定义操作
2021/04/28 Golang
Mysql如何实现不存在则插入,存在则更新
2022/03/25 MySQL