原生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 相关文章推荐
html页面显示年月日时分秒和星期几的两种方式
Aug 20 Javascript
基于jquery实现的文字淡入淡出效果
Nov 14 Javascript
js实现点击左右按钮轮播图片效果实例
Jan 29 Javascript
jQuery基于图层模仿五星星评价功能的方法
May 07 Javascript
Extjs4.0 ComboBox如何实现三级联动
May 11 Javascript
JS实现输入框提示文字点击时消失效果
Jul 19 Javascript
Vue.js结合bootstrap实现分页控件
Mar 10 Javascript
Vue实现购物车场景下的应用
Nov 27 Javascript
Angular2开发环境搭建教程之VS Code
Dec 15 Javascript
React中如何引入Angular组件详解
Aug 09 Javascript
纯js实现无缝滚动功能代码实例
Feb 21 Javascript
vue a标签点击实现赋值方式
Sep 07 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
利用 window_onload 实现select默认选择
2006/10/09 PHP
编写漂亮的代码 - 将后台程序与前端程序分开
2008/04/23 PHP
在同一窗体中使用PHP来处理多个提交任务
2008/05/08 PHP
FastCGI 进程意外退出造成500错误
2015/07/26 PHP
使用PHP进行微信公众平台开发的示例
2015/08/21 PHP
PHP 的Opcache加速的使用方法
2017/12/29 PHP
laravel框架的安装与路由实例分析
2019/10/11 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
2020/08/03 PHP
用javascript实现在小方框中浏览大图的代码
2007/08/14 Javascript
一个很酷的拖动层的js类,兼容IE及Firefox
2009/06/23 Javascript
jQuery对下拉框,单选框,多选框的操作
2014/02/21 Javascript
jQuery插件Elastislide实现响应式的焦点图无缝滚动切换特效
2015/04/12 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
2015/09/27 Javascript
jquery实现定时自动轮播特效
2015/12/10 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
js时间比较 js计算时间差的简单实现方法
2016/08/26 Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
2017/03/04 Javascript
js 获取今天以及过去日期
2017/04/11 Javascript
jquery实现一个全局计时器(商城可用)
2017/06/30 jQuery
BootStrap selectpicker后台动态绑定数据的方法
2017/07/28 Javascript
bootstrap switch开关组件使用方法详解
2017/08/22 Javascript
nodejs 日志模块winston的使用方法
2018/05/02 NodeJs
前端防止用户重复提交js实现代码示例
2018/09/07 Javascript
vue-music 使用better-scroll遇到轮播图不能自动轮播问题
2018/12/03 Javascript
[01:22:42]2014 DOTA2华西杯精英邀请赛 5 24 DK VS LGD
2014/05/26 DOTA
[06:40]2014DOTA2西雅图国际邀请赛 DK战队巡礼
2014/07/07 DOTA
解读Python编程中的命名空间与作用域
2015/10/16 Python
python中defaultdict的用法详解
2017/06/07 Python
Python Pandas分组聚合的实现方法
2019/07/02 Python
python+selenium+Chrome options参数的使用
2020/03/18 Python
Scrapy项目实战之爬取某社区用户详情
2020/09/17 Python
英国领先的电子、技术和办公用品购物网站:Ebuyer
2018/04/04 全球购物
公交公司毕业生求职信
2014/02/15 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
办理护照工作证明
2014/10/10 职场文书
销售员态度差检讨书
2014/10/26 职场文书