分享一个403界面给大家

30 篇文章 1 订阅

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

<!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:发现我用文字写太生硬了,干的噎嗓子,干脆在代码里加注释了。

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Echarts 大屏页面模板是一种用于数据可视化展示的工具。它通过 Echarts 这个强大的 JavaScript 图表库,结合页面模板的搭建,可以快速、简单地建立一个专业的数据大屏展示页面。在模板中,我们可以根据需要插入各种类型的图表,比如折线图、柱状图、饼图、地图等,用于展示各种数据信息。 Echarts 大屏页面模板的优势在于它提供了丰富的数据可视化图表,并且可以灵活的进行定制和调整。同时,Echarts 还支持大规模数据的展示,可以处理数千甚至数十万条数据,无论是实时数据还是历史数据都可以得到清晰直观的展示。另外,Echarts 还提供了丰富的交互功能,比如可以通过点击、拖拽、鼠标悬停等方式实现交互操作,让用户可以更加直观、方便地进行数据的查看和分析。 使用 Echarts 大屏页面模板,能够帮助用户更好地展示数据信息,从而更好地进行数据分析和决策。无论是企业的数据监控大屏、展会的数据展示、还是政府的数据公示,都可以通过 Echarts 大屏页面模板来实现。同时,Echarts 作为一个开放性的工具,也支持各种数据源的接入,比如数据库、接口数据、文件数据等,能够满足不同场景的数据展示需求。 总的来说,Echarts 大屏页面模板是一种功能强大、灵活定制的数据可视化展示工具,可以帮助用户快速、高效地建立自己的数据大屏展示页面

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

timi先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值