分享一个403界面给大家

news2024/11/24 11:43:13

先看效果图(说明:小鬼影会飘来飘去,长时间停留会有小惊喜,具体大家跑一下就知道):
在这里插入图片描述
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>403页面</title>
  <style>
    @import url('https://fonts.googleapis.com/css?family=Open+Sans|Nova+Mono');
    :root {
      --font-header: 'Nova Mono', monospace;
      --font-text: 'Open Sans', sans-serif;
      --color-theme: #F1EEDB;
      --color-bg: #282B24;

      --animation-sentence: '你知道你应该离开,对吧?';
      --animation-duration: 40s;
    }
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    body {
      width: 100%;
      font-family: var(--font-text);
      color: var(--color-theme);
      background: var(--color-bg);
      overflow: hidden;
    }
    .container {
      text-align: center;
      margin: 1rem 0.5rem 0;
    }
    .container h1 {
      font-family: var(--font-header);
      font-size: calc(4rem + 2vw);
      text-transform: uppercase;
    }
    .container p {
      text-transform: uppercase;
      letter-spacing: 0.2rem;
      font-size: 2rem;
      margin: 1.5rem 0 3rem;
    }
    svg.keyhole {
      height: 82px;
      width: 82px;
      opacity: 0;
      visibility: hidden;
      /* 为钥匙孔定义一个动画,以引入默认情况下暂停的动画,在JavaScript中超时运行*/
      animation: showKey 0.5s 0.5s paused ease-out forwards;
    }
    svg.key {
      height: 164px;
      width: 164px;
      position: absolute;
      opacity: 0;
      visibility: hidden;
      /* 为钥匙孔定义一个动画,以引入默认情况下暂停的动画,在JavaScript中超时运行*/
      animation: showKey 0.5s 0.5s paused ease-out forwards;
    }
    .ghost {
      /* border: 1px solid tomato; */
      position: absolute;
      bottom: 5px;
      left: calc(50% - 100px);
      width: 200px;
      height: 200px;
      /* 让鬼影移动到屏幕的右侧和左侧,转到其中心位置并重复动画两次 */
      animation: hoverGhost calc(var(--animation-duration)/2) ease-in-out 2;

    }
    /* 通过连接到动画div的伪元素引入文本 */
    .ghost:before {
      content: var(--animation-sentence);
      color: var(--color-theme);
      border-radius: 50%;
      position: absolute;
      bottom: 100%;
      text-align: center;
      line-height: 2;
      padding: 1rem;
      visibility: hidden;
      opacity: 0;
      /* 当鬼影从屏幕右边缘返回时,引入每一个文本字符串,以及覆盖中心部分所需的时间长度(第四个字符串,由于动画长度是总持续时间的一半,因此变为八个字符串)
      /* 假设持续时间为40秒的情况下,第一个延迟为7.5秒,第二个延迟为27.5秒,最后一个延迟为40秒,经过运算,可以归结为316、2740和1
      // 记得在钥匙和钥匙孔的动画中加入一点延迟
      */
      animation:
              showText calc(var(--animation-duration)/8) calc(var(--animation-duration)*3/16) ease-out forwards,
              showNewText calc(var(--animation-duration)/8) calc(var(--animation-duration)*27/40) ease-out forwards,
              showFinalText calc(var(--animation-duration)/8) var(--animation-duration) ease-out forwards;

    }

    /* 定义关键帧动画-悬停鬼影使鬼影向右、向左移动,然后返回到其默认位置
    -showKey将钥匙(和钥匙孔)svg引入视图
    -showText、showNewText、showFinalText显示不同的字符串*/
    @keyframes hoverGhost {
      25% {
        transform: translateX(20vw);
      }
      75% {
        transform: translateX(-20vw);
      }
    }

    @keyframes showKey {
      to {
        opacity: 1;
        visibility: visible;
      }
    }

    /* 更改文本,更改自定义属性的值,厌倦了在隐藏伪元素时更改其值,以及在最后一个关键帧中更改其值(因为动画根据填充模式属性的“向前”值给出该值)*/
     @keyframes showText {
      2% {
        opacity: 1;
        visibility: visible;
      }
      98% {

        opacity: 1;
        visibility: visible;
      }
      99% {
        --animation-sentence: '你知道你应该离开,对吧?';
        opacity: 0;
        visibility: hidden;
      }
      100% {
        --animation-sentence: '这么多事情要做,这么少时间...';
      }
    }
    @keyframes showNewText {
      2% {
        --animation-sentence: '这么多事情要做,这么少时间...';
        opacity: 1;
        visibility: visible;
      }
      98% {

        opacity: 1;
        visibility: visible;
      }
      99% {
        --animation-sentence: '这么多事情要做,这么少时间...';
        opacity: 0;
        visibility: hidden;
      }
      100% {
        --animation-sentence: '好吧,你似乎很关心这个.这是一把只给你的钥匙..';
      }
    }
    @keyframes showFinalText {
      2% {
        opacity: 1;
        visibility: visible;
      }
      98% {
        opacity: 1;
        visibility: visible;
      }
      100% {
        opacity: 0;
        visibility: hidden;
      }
    }
  </style>
</head>
<body>
<!-- 包括在项目中使用的svg -->
<svg style="display: none;">
  <symbol id="keyhole" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 26.458333 26.458334"><g transform="translate(0 -270.542)"><circle cx="13.229" cy="279.141" r="8.599" fill="#f1eedb" paint-order="stroke fill markers"/><path d="M10.516 283.271h5.427c1.164 0 1.768.861 2.102 1.802l3.59 10.125c.334.94-.937 1.802-2.102 1.802H6.926c-1.165 0-2.437-.861-2.103-1.802l3.59-10.125c.334-.94.938-1.802 2.103-1.802z" fill="#f1eedb" paint-order="stroke fill markers"/><circle r="6.06" cy="279.141" cx="13.229" fill="#282b24" paint-order="stroke fill markers"/><path d="M11.502 283.76h3.455c.741 0 1.126.733 1.338 1.534l2.286 8.614c.213.8-.597 1.534-1.338 1.534H9.216c-.742 0-1.551-.733-1.339-1.534l2.286-8.614c.212-.8.597-1.534 1.339-1.534z" fill="#282b24" paint-order="stroke fill markers"/></g></symbol>
  <symbol id="key" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 26.458333 26.458334"><circle cx="13.229" cy="279.141" r="8.599" paint-order="stroke fill markers" transform="matrix(0 -.76923 .7499 0 -202.882 23.405)" fill="#f1eedb"/><circle r="8.599" cy="279.141" cx="13.229" paint-order="stroke fill markers" transform="matrix(0 -.5887 .57392 0 -153.756 21.017)" fill="#282b24"/><path fill="#f1eedb" paint-order="stroke fill markers" d="M12.03 12.13h14.428v2.2H12.03z"/><path fill="#f1eedb" paint-order="stroke fill markers" d="M18.147 12.13h2.895v6.772h-2.895zM22.113 12.13h2.716v5.065h-2.716z"/></symbol>
  <symbol id="ghost" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 26.458333 26.458334"><g transform="translate(0 -270.542)"><path d="M4.63 279.293c0-4.833 3.85-8.751 8.6-8.751 4.748 0 8.598 3.918 8.598 8.75H13.23zM4.725 279.293h16.914c.052 0 .19.043.19.096l-.095 14.329c0 .026-.011.05-.028.068a.093.093 0 0 1-.067.028c-.881 0-1.235-1.68-2.114-1.616-.995.072-1.12 2.082-2.114 2.154-.88.064-1.233-1.615-2.115-1.615-.881 0-1.233 1.615-2.114 1.615-.881 0-1.233-1.615-2.114-1.615-.882 0-1.236 1.679-2.115 1.615-.994-.072-1.12-2.082-2.114-2.154-.88-.063-1.41 1.077-2.114 1.616-.021.016-.05-.01-.067-.028a.097.097 0 0 1-.028-.068v-14.33c0-.052.042-.095.095-.095z" fill="#f1eedb" paint-order="stroke fill markers"/><path d="M15.453 281.27a1.987 1.94 0 0 1-.994 1.68 1.987 1.94 0 0 1-1.987 0 1.987 1.94 0 0 1-.994-1.68h1.988z" fill="#282b24" paint-order="stroke fill markers"/><g fill="#282b24" transform="matrix(1 0 0 1.0177 .283 -5.653)"><ellipse cx="10.205" cy="278.668" rx="1.231" ry="1.181" paint-order="stroke fill markers"/><ellipse ry="1.181" rx="1.231" cy="278.668" cx="16.159" paint-order="stroke fill markers"/><ellipse ry=".331" rx=".853" cy="280.936" cx="10.205" opacity=".5" paint-order="stroke fill markers"/><ellipse cx="16.159" cy="280.936" rx=".853" ry=".331" opacity=".5" paint-order="stroke fill markers"/></g><ellipse ry=".614" rx="8.082" cy="296.386" cx="13.229" opacity=".1" fill="#f1eedb" paint-order="stroke fill markers"/></g></symbol>
</svg>

<!-- 在一个容器中包括一个标题、段落和锁眼的svg -->
<div class="container">
  <h1>403</h1>
  <p>access not granted</p>
  <svg class="keyhole">
    <use href="#keyhole"/>
  </svg>
</div>

<!-- 在容器外部,使它们相对于主体绝对定位,包括一个用于钥匙的svg和一个用于鬼影的svg -->
<svg class="key">
  <use href="#key"/>
</svg>

<!--
  将svg嵌套在div中,为svg和div提供相同的类div和svg在通过transform属性转换元素时表现不同,
  从而在文本(包含在div上的伪元素中)和svg之间提供了很好的距离
-->
<div class="ghost">
  <svg class="ghost">
    <use href="#ghost"/>
  </svg>
</div>
</body>
<script>
  // 以项目中使用的DOM中的元素为目标

  /**
   * 钥匙和钥匙孔的svg
   * 标题和段落
   */
  const key = document.querySelector(".key");
  const keyhole = document.querySelector(".keyhole");
  const ghost = document.querySelector(".ghost");

  const heading = document.querySelector("h1");
  const paragraph = document.querySelector("p");

  // 对于timout的长度,请考虑--animation-duration自定义属性,并在根元素上添加一个小延迟检索属性
  const root = document.querySelector(":root");
  const rootStyles = getComputedStyle(root);

  // 检索动画持续时间自定义属性
  // 这被指定为“40s”,以秒为单位,因此解析数字并以毫秒为单位将其包括在内
  const animationDuration = parseInt(rootStyles.getPropertyValue("--animation-duration"))*1000;
  let keyTimer = animationDuration*9/8;

  // 检索钥匙的尺寸(使钥匙正好位于光标所在的位置)
  const keyBox = key.getBoundingClientRect();
  // console.log(keyBox);

  // 钥匙和钥匙孔动画
  // 在指定的时间范围内包括超时
  const timeoutID = setTimeout(() => {
    // 在指定的时间后,将光标更改为似乎抓住了钥匙
    key.parentElement.parentElement.style.cursor = "grab";

    // 通过触发默认情况下暂停的动画,引入钥匙和钥匙孔svg元素
    key.style.animationPlayState = "running";
    keyhole.style.animationPlayState = "running";

    // 将钥匙上的指针事件设置为none,以允许在钥匙孔上发生鼠标悬停事件
    // 钥匙实际上是代替普通光标使用的,并且会重叠在所有内容的顶部
    key.style.pointerEvents = "none";

    // 当光标悬停在窗口中的任何位置时,调用一个函数来更新钥匙的位置并使其与光标匹配
    window.addEventListener("mousemove", updateKeyPosition);

    // 当光标悬停在钥匙孔上时,调用一个函数来授予访问权限并删除当前侦听器
    keyhole.addEventListener("mouseover", grantAccess);

    clearTimeout(timeoutID);
  }, keyTimer);


  // 定义根据鼠标坐标(以及钥匙自身的尺寸)更新绝对定位钥匙的位置的功能
  const updateKeyPosition = (e) => {
    let x = e.clientX;
    let y = e.clientY;
    key.style.left = x - keyBox.width/1.5;
    key.style.top = y - keyBox.height/2;
  };

  // 定义通知用户授予访问权限的功能
  const grantAccess = () => {

    // 恢复光标
    key.parentElement.parentElement.style.cursor = "default";

    // 更改标题和段落元素的文本
    heading.textContent = '🎉 yay 🎉';
    paragraph.textContent = 'access granted';

    // 从文档流中删除钥匙和钥匙孔的svg元素
    keyhole.style.display = "none";
    key.style.display = "none";

    // 删除事件侦听器,尤其是窗口上的侦听器
    window.removeEventListener("mousemove", updateKeyPosition);
    keyhole.removeEventListener("mouseover", grantAccess);
  };

</script>
</html>

PS:发现我用文字写太生硬了,干的噎嗓子,干脆在代码里加注释了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/566869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

depends_on 解决 docker 容器依赖问题

如果你经常使用docker-compose启动服务的话&#xff0c;可能会遇到下面的问题&#xff1a;服务 B 依赖服务 A&#xff0c;需要服务 A 先启动&#xff0c;再启动服务 B 举个例子&#xff0c;在部署 kafka 集群的时候&#xff0c;需要启动两个kafka&#xff0c;并使用zookeeper做…

基于云计算和物联网技术开发的智慧校园云平台源码

智慧校园系统是利用物联网和云计算&#xff0c;强调对教学、科研、校园生活和管理的数据采集、智能处理、为管理者和各个角色按需提供智能化的数据分析、教学、学习的智能化服务环境。它包含“智慧环境、智慧学习、智慧服务、智慧管理”等层面的内容。 文末获取联系 它描绘的是…

准备搞个大动作!

目前我们的会员群的同学越来越多&#xff0c;然后我们提供的内容已经从起步篇&#xff0c;趣味篇&#xff0c;工具篇到高级篇了。但是到了高级篇很多内容都跟编程相关&#xff0c;有一点门槛&#xff0c;如果单单看文字是肯定无法满足大家的需求。为了更好的服务大家&#xff0…

跃升数字生产力,九州云受邀出席闵行国际人才月

5月22日&#xff0c;由闵行人才工作领导小组办公室指导、中共闵行区马桥镇委员会及闵行区马桥镇人民政府主办、上海人工智能研究院协办的首届“大零号湾”国际人才月马桥人工智能周成功召开。 本届大会以“AI才共赢 智敬未来”为主题&#xff0c;探讨科技创新的最新动态和趋势&…

如何使用Linux Top命令

Linux中的top命令允许您监视当前正在运行的进程及其使用的系统资源。作为系统管理员&#xff0c;它可能是工具箱中最有用的工具&#xff0c;特别是如果您知道如何使用它的话。所有Linux发行版都预装了top实用程序。通过这个交互式命令&#xff0c;您可以自定义如何浏览进程列表…

电脑蓝屏该如何给电脑重装系统

电脑蓝屏问题是让人头疼的常见故障之一&#xff0c;而重装系统是解决蓝屏问题的有效方法。本文将为您详细介绍如何在电脑蓝屏的情况下进行系统重装&#xff0c;轻松摆脱蓝屏困扰。 工具/原料&#xff1a; 系统版本&#xff1a;windows10系统 品牌型号&#xff1a;华为MateBoo…

常见的黄金期货交易风险包含哪些内容?

黄金期货交易作为受市场欢迎的投资理财方式&#xff0c;兼具高风险和高收益并存的特性。黄金期货交易风险也同样存在&#xff0c;那常见的黄金期货交易风险包含哪些内容&#xff1f; 黄金期货交易风险一、市场风险 投资者在黄金期货交易中&#xff0c;主要的风险来源于市场价格…

快来试试!免费用上GPT-4 !!!

GPT-4 简介 GPT-4是OpenAI上个月推出的最新人工智能语言模型&#xff0c;它可以根据给定的文本或关键词生成各种类似于人类语言甚至超越人类语言的文本&#xff0c;例如文章、故事、诗歌、代码、对话等。 GPT-4拥有1750亿个参数&#xff0c;是目前最大的语言模型之一&#xf…

红米8a,刷机到安卓调用之路

什么是BL锁&#xff1f; https://baijiahao.baidu.com/s?id1614459630284912892&wfrspider&forpc bl锁简单来说&#xff0c;就是厂商为了自己的目的&#xff0c;为了避免刷机&#xff0c;而人为设置的一道障碍&#xff0c;我的第一步就需要等待168小时&#xff0c;经…

随想011:关于编程

1945 年时&#xff0c;刚开始有计算机&#xff0c;那时候使用二进制数编程到了40年代末期&#xff0c;出现了汇编器&#xff0c;可以自动将汇编程序转换为二进制数序列1951 年 Grace Hopper 发明了编译器1957 年&#xff0c;Fortran&#xff0c;第一个高级语言&#xff0c;首次…

npm 无法下载 win32-x64-72_binding.node

使用npm安装node-sass时&#xff0c;其依赖了win32-x64-72_binding.node&#xff0c;但是一直提示“cannot download http://xxx/win32-x64-72_binding.node”&#xff0c;有两种方案可以解决&#xff0c;一种是在有私服的情况下&#xff0c;可以通过设置 SASS_BINARY_SITE 环境…

百度云原生数据库GaiaDB的HTAP与多地多活技术实践

​摘要&#xff1a;云原生数据库在使用存算分离技术后&#xff0c;可以在完全兼容MYSQL协议和语法的情况下&#xff0c;极大提升单实例所能承载的数据规模与吞吐能力上限。但除了对客户端兼容外&#xff0c;对整个数据生态&#xff08;地域容灾&#xff0c;数据分析&#xff0c…

javaWebssh旅游论坛系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh旅游论坛系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Mye…

机器学习中四类进化算法的详解(遗传算法、差分进化算法、协同进化算法、分布估计算法)

1、遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09; GA算法原理 首先我们来介绍进化算法的先驱遗传算法&#xff0c;遗传算法&#xff08;Genetic Algorithm&#xff0c;简称GA&#xff09;是一种最基本的进化算法&#xff0c;它是模拟达尔文生物进化理论的…

牛牛截图控件与利洽远程控制产品升级-支持证书自动升级

今天我们来聊一聊浏览器控件的一个痛点&#xff01;看看我们是如何解决他的。 背景信息 目前市面上存在多种浏览器&#xff0c;IE、Chrome、Firefox、Edge以及一众国产浏览器&#xff0c;这些浏览器中&#xff0c;IE支持ActiveX&#xff0c;部分国产浏览器支持npapi&#xff…

vscode开发小程序项目并在微信开发者工具运行

需求&#xff1a;vscode开发uniapp之后在微信开发者工具运行&#xff0c;更改的时候微信开发者也同步更改 1.创建小程序命令 这里的uniapp-vue是项目名称&#xff0c;不能大写 vue create -p dcloudio/uni-preset-vue uniapp-vue 2.选择uni-app模版 有几种模版选择&#x…

Ubuntu TDengine 集成 EMQX 通过规则引擎实现设备数据直接入库

背景 曾使用过 IoTDB 自带的 MQTT Broker 实现了设备数据入库&#xff0c;那么使用 TDengine 时&#xff0c;我们可以借助 EMQX &#xff08;一款优秀的国产开源 MQTT Broker &#xff09;的规则引擎结合 TDengine 的 RESTful API 完成设备数据的路由与入库。 用到的工具 TD…

PAI-Diffusion中文模型全面升级,海量高清艺术大图一键生成

作者&#xff1a;段忠杰&#xff08;终劫&#xff09;、刘冰雁&#xff08;伍拾&#xff09;、汪诚愚&#xff08;熊兮&#xff09;、黄俊&#xff08;临在&#xff09; 背景 以Stable Diffusion模型为代表&#xff0c;AI生成内容&#xff08;AI Generated Content&#xff…

鸿蒙Hi3861问题解决-[OHOS ERROR] clang not found, install it please

一、简介 在使用DevEco进行编译时出现[OHOS ERROR] clang not found, install it please问题&#xff0c;导致编译失败&#xff0c;这里做个问题记录。 二、解决 这种问题其实还是工具链安装不全造成的。 安装gn 这里用的是VSCode DevEco组件&#xff0c;里边包含了gn组件的安…

error while loading shared libraries: libc.so.6 误删除libc.so.6急救办法,

故障原因&#xff1a; 在高版本的环境中编译了一个软件&#xff0c;然而在低版本系统中无法使用&#xff0c;缺少libc.so支持,然而在编译过程中误删除了 libc.so.6的软连接&#xff0c;rm /lib64/libc.so.6 删除后发现系统好多命令都无法使用了&#xff0c;悲催&#xff01…