分享一个下载按钮

news2024/12/23 22:47:10

先看效果:
在这里插入图片描述
再看代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下载按钮</title>
  <link href="https://fonts.googleapis.com/css2?family=Hind&amp;display=swap" type="text/css" rel="stylesheet">
  <style>
    * {
      border: 0;
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    :root {
      --dur: 3s;
      --arrowA: polygon(33% 0%,67% 0%,67% 60%,100% 60%,50% 100%,0% 60%,33% 60%);
      --arrowB: polygon(0% 37.5%,100% 37.5%,100% 62.5%,100% 62.5%,50% 62.5%,0% 62.5%,0% 62.5%);
      font-size: calc(20px + (40 - 20)*(100vw - 320px)/(2560 - 320));
    }
    body, button {
      display: flex;
      font: 1em/1.5 Hind, sans-serif;
    }
    body {
      background: #e3e4e8;
      height: 100vh;
      overflow: hidden;
    }
    button {
      background: #255ff4;
      border-radius: 0.2em;
      color: #fff;
      cursor: pointer;
      display: flex;
      margin: auto;
      padding: 0.5em 1em;
      position: relative;
      transition: background 0.15s linear;
      width: 10.5em;
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
      -webkit-tap-highlight-color: transparent;
    }
    button:focus {
      outline: transparent;
    }
    button::-moz-focus-inner {
      border: 0;
    }
    button:not(:disabled):focus, button:not(:disabled):hover {
      background: #0b46da;
    }
    button:not(:disabled):active {
      transform: translateY(1px);
    }
    button:disabled {
      cursor: not-allowed;
    }
    button span, button:before, button:after {
      display: inline-block;
      pointer-events: none;
    }
    button:before, button:after {
      border-radius: 0.25em;
      opacity: 0;
      top: 1em;
      left: 1.3em;
      height: 0.5em;
      transform-origin: 0.25em 50%;
      z-index: 2;
    }
    button:before {
      transform: rotate(-180deg);
      width: 0.8em;
    }
    button:after {
      width: 1.2em;
    }
    button:before, button:after, .dl-icon:before, .dl-icon:after {
      content: "";
      display: block;
      position: absolute;
    }
    button:before, button:after, .dl-icon:before {
      background: currentColor;
    }
    button span + span {
      margin: auto;
    }
    .dl-icon {
      margin-right: 0.5em;
      position: relative;
      width: 1.5em;
      height: 1.5em;
    }
    .dl-icon:before {
      clip-path: var(--arrowA);
      -webkit-clip-path: var(--arrowA);
      top: 0;
      left: calc(50% - 0.55em);
      transform-origin: 50% 100%;
      width: 1.1em;
      height: 1em;
      z-index: 1;
    }
    .dl-icon:after {
      background-image: linear-gradient(#0b46da,#0b46da);
      background-position: -1.5em 0;
      background-size: 100% 100%;
      background-repeat: no-repeat;
      box-shadow:
              0.25em 0 0 inset,
              -0.25em 0 0 inset,
              0 -0.25em 0 inset;
      bottom: 0;
      width: 100%;
      height: 0.5em;
    }
    .dl-working:before {
      animation: checkOutA var(--dur) linear forwards;
    }
    .dl-working:after {
      animation: checkOutB var(--dur) linear forwards;
    }
    .dl-working .dl-icon {
      animation: impact var(--dur) linear forwards;
    }
    .dl-working .dl-icon:before {
      animation: arrowToBar var(--dur) linear forwards;
    }
    .dl-working .dl-icon:after {
      animation: trayToBar var(--dur) linear forwards;
    }

    /* Animation */
    @keyframes impact {
      from, 15% {
        transform: translateY(0);
      }
      17.5% {
        transform: translateY(0.25em);
      }
      20%, to {
        transform: translateY(0);
      }
    }
    @keyframes arrowToBar {
      from {
        clip-path: var(--arrowA);
        -webkit-clip-path: var(--arrowA);
      }
      10% {
        clip-path: var(--arrowB);
        -webkit-clip-path: var(--arrowB);
        transform: translateY(0);
      }
      15% {
        clip-path: var(--arrowB);
        -webkit-clip-path: var(--arrowB);
        transform: translateY(0.625em);
      }
      30% {
        clip-path: var(--arrowB);
        -webkit-clip-path: var(--arrowB);
        opacity: 1;
        transform: translateY(0.125em);
      }
      35%, to {
        clip-path: var(--arrowB);
        -webkit-clip-path: var(--arrowB);
        opacity: 0;
        transform: translateY(0.125em);
      }
    }
    @keyframes trayToBar {
      from, 15% {
        background-color: transparent;
        border-radius: 0;
        box-shadow:
                0.25em 0 0 inset,
                -0.25em 0 0 inset,
                0 -0.25em 0 inset;
        transform: translateY(0);
      }
      15.1% {
        background-color: currentColor;
        border-radius: 0;
        box-shadow:
                0 0 0 inset,
                0 0 0 inset,
                0 0 0 0.1em inset;
        transform: translateY(0);
      }
      30% {
        background-color: currentColor;
        background-position: -1.5em 0;
        border-radius: 0.25em;
        box-shadow:
                0 0 0 inset,
                0 0 0 inset,
                0 0 0 0.1em inset;
        transform: translateY(-0.5em);
      }
      90% {
        background-color: currentColor;
        background-position: 0 0;
        border-radius: 0.25em;
        box-shadow:
                0 0 0 inset,
                0 0 0 inset,
                0 0 0 0.1em inset;
        opacity: 1;
        transform: translateY(-0.5em);
      }
      90.1%, to {
        background-color: currentColor;
        background-position: 0 0;
        border-radius: 0.25em;
        box-shadow:
                0 0 0 inset,
                0 0 0 inset,
                0 0 0 0.1em inset;
        opacity: 0;
        transform: translateY(-0.5em);
      }
    }
    @keyframes checkOutA {
      from, 90% {
        opacity: 0;
        transform: translate(0,0) rotate(-180deg);
      }
      90.1% {
        opacity: 1;
        width: 0.8em;
        transform: translate(0,0) rotate(-180deg);
      }
      92.5% {
        opacity: 1;
        width: 1em;
        transform: translate(0,0.5em) rotate(-120deg);
      }
      95%, to {
        opacity: 1;
        width: 1em;
        transform: translate(0,0.375em) rotate(-135deg);
      }
    }
    @keyframes checkOutB {
      from, 90% {
        opacity: 0;
        transform: translate(0,0) rotate(0);
      }
      90.1% {
        opacity: 1;
        width: 1.2em;
        transform: translate(0,0) rotate(0);
      }
      92.5% {
        opacity: 1;
        width: 1.6em;
        transform: translate(0,0.5em) rotate(-60deg);
      }
      95%, to {
        opacity: 1;
        width: 1.6em;
        transform: translate(0,0.375em) rotate(-45deg);
      }
    }

    /* Dark mode */
    @media (prefers-color-scheme: dark) {
      body {
        background: #2e3138;
      }
    }
  </style>
</head>
<body>
<button type="button" data-dl>
  <span class="dl-icon"></span><span>&#x44;&#x6F;&#x77;&#x6E;&#x6C;&#x6F;&#x61;&#x64;</span>
</button>
</body>
<script>
  document.addEventListener("DOMContentLoaded",function(){
    this.addEventListener("click",e => {
      let tar = e.target;
      if (tar.hasAttribute("data-dl")) {
        let dlClass = "dl-working";
        if (!tar.classList.contains(dlClass)) {
          let lastSpan = tar.querySelector("span:last-child"),
                  lastSpanText = lastSpan.textContent,
                  timeout = getMSFromProperty("--dur",":root");

          tar.classList.add(dlClass);
          lastSpan.textContent = "Downloading…";
          tar.disabled = true;

          setTimeout(() => {
            lastSpan.textContent = "Completed!";
          },timeout * 0.9);

          setTimeout(() => {
            tar.classList.remove(dlClass);
            lastSpan.textContent = lastSpanText;
            tar.disabled = false;
          },timeout + 1e3);
        }
      }
    });
  });
  function getMSFromProperty(property,selector) {
    let cs = window.getComputedStyle(document.querySelector(selector)),
            transDur = cs.getPropertyValue(property),
            msLabelPos = transDur.indexOf("ms"),
            sLabelPos = transDur.indexOf("s");

    if (msLabelPos > -1)
      return transDur.substr(0,msLabelPos);
    else if (sLabelPos > -1)
      return transDur.substr(0,sLabelPos) * 1e3;
  }
</script>
</html>

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

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

相关文章

Redisson源码-单线程加解锁流程

Redisson源码-单线程加解锁流程 以下源码分析基于redisson-3.17.6版本&#xff0c;不同版本源码会有些许不同需注意。 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.17.6</version>&l…

推荐5 款好用的 Linux 音乐播放器

目前 Linux 上有几十个音乐播放器&#xff0c;这使得找到一个最好用的变成很困难。之前我们已经回顾了其中的一些播放器&#xff0c;如 Cantata&#xff0c;Exaile&#xff0c;甚至不那么出名的 Clementine&#xff0c;Nightingale 和 Quod Libet。 在本篇文章中我将涵盖更多的…

python学习——pandas数据处理 时间序列案例 matplotlib绘图案例

目录 pandas数据处理1.合并数据1) 堆叠合并2) 主键合并3) 重叠合并 2.分组和聚合3.索引和符合索引4.去除重复值5.处理缺失值6.处理离群值7.标准化数据1) 离差标准化函数2) 标准差标准化函数3) 小数定标差标准化函数 8.转换数据--离散处理9.时间序列【案例】时间序列案例案例1&a…

C++测试

开始对C嘎嘎下手&#xff01; 1.有关char数组 定义长度为5&#xff0c;但是实际长度是定义长度减1 突然就想到计网安全中的栈溢出问题了&#xff0c;C语言是不检查你是否越界的&#xff0c;如果通过让实参溢出覆盖掉原程序的返回地址&#xff0c;通过精心控制是可以让计算机执…

高级数据结构——红黑树

目录 1. 红黑树的概念 2. 红黑树的性质 3. 红黑树 6. 红黑树的验证 7. 红黑树的删除 8. 红黑树与AVL数的比较 9. 红黑树的应用 10. 完整代码 10.1 RBTree.h 10.2 test.cpp 1. 红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存…

49天精通Java,第37天,可变参数列表

目录 一、可变参数列表二、可变参数列表的优缺点1、优点2、缺点 三、可变参数列表的适用场景1、函数重载2、命令行参数解析3、集合操作4、函数式编程 大家好&#xff0c;我是哪吒。 &#x1f3c6;本文收录于&#xff0c;49天精通Java从入门到就业。 全网最细Java零基础手把手…

SpringBoot 如何使用 @ResponseStatus 注解处理异常状态码

SpringBoot 如何使用 ResponseStatus 注解处理异常状态码 在 SpringBoot 应用程序中&#xff0c;异常处理是一个非常重要的话题。当应用程序出现异常时&#xff0c;我们需要对异常进行处理&#xff0c;以保证应用程序的稳定性和可靠性。除了使用异常处理器外&#xff0c;Sprin…

重新理解微服务之终究绕不过这4个坎之(一)

写在前头 大家曾经有没有遇过日常技术交流的时候&#xff0c;会讨论某某技术之间的关系是什么&#xff0c;某些技术是否应该用到微服务。我相信热爱技术交流的您&#xff0c;就算不是在微服务这里领域&#xff0c;或多或少都会跟其他同行会做一些争议话题的探讨&#xff0c;而…

华为OD机试真题B卷 JavaScript 实现【字符串分隔】,附详细解题思路

一、题目描述 输入一个字符串&#xff0c;请按长度为8拆分每个输入字符串并进行输出&#xff0c;长度不是8整数倍的字符串请在后面补数字0&#xff0c;空字符串不处理。 二、输入描述 连续输入字符串(每个字符串长度小于等于100)。 三、输出描述 依次输出所有分割后的长度…

k8s使用ceph存储

文章目录 初始化操作k8s使用ceph rbdvolumePV静态pv动态pv k8s使用cephfsvolume静态pv 初始化操作 ceph创建rbd存储池 ceph osd pool create k8s-data 32 32 replicated ceph osd pool application enable k8s-data rbd rbd pool init -p k8s-dataceph添加授权&#xff0c;需…

指针和数组--指针数组及其应用

目录 一、指针数组用于表示多个字符串 二、指针数组用于表示命令行参数 一、指针数组用于表示多个字符串 一维数组可存储一个字符串&#xff0c;二维数组可存储多个字符串。 二维数组的元素在内存中是连续存放的&#xff0c;存完第一行后&#xff0c;再存第二行&#xff0c;以…

多线程之JUC

写在前面 本文一起看下jdk并发包的相关内容。 1&#xff1a;JUC包提供了哪些功能 先通过包结构看下JUC提供的功能&#xff1a; 接下来分别看下。 1.1&#xff1a;锁 JUC中的锁机制提供了比synchronized&#xff0c;wait/notify更加灵活的同步控制&#xff0c;在java.util.…

大数据基础平台实施及运维进阶

1、完全分布式部署介绍 完全分部式是真正利用多台Linux主机来进行部署Hadoop&#xff0c;对Linux机器集群进行规划&#xff0c;使得Hadoop各个模块分别部署在不同的多台机器上。 2、nameNode HA完全分布式部署 2.1、nameNode切换方法 分别处于Active和Standby中 hadoop可以…

操作系统复习笔记4

1、queueType队列类型 队列中的数据也呈线性排列。虽然与栈有些相似&#xff0c;但队列中添加和删除数据的操作分别是在两端进行的。 线性表有顺序存储和链式存储&#xff0c;队列作为一种特殊的线性表&#xff0c;也同样存在这两种存储方式。 1.1 顺序队列 用数组存储队列…

C语言学习(二十五)---指针练习题(一)

在上一节内容中&#xff0c;我们学习了递归与冒泡排序法的有关内容&#xff0c;今天我们将继续往下学习&#xff0c;主要内容为指针练习题&#xff0c;好了&#xff0c;话不多说&#xff0c;开整&#xff01;&#xff01;&#xff01; 在之前的第18—22的内容中&#xff0c;我…

lnmp框架的应用

目录 应用一 nginx访问状态统计 1.先查看http_stub_status有没有安装 2.进入nginx的配置文件改配置 3.nginx-检查配置 重启服务 最后这个20就是显示的状态统计 应用二 给网站加密 1.首先安装http-tools软软件 2.把nginx设置锁也要有执行权限 3.进入nginx配置文件 4. 检查…

【Windows个性化设置篇】StartAllBack更改win11任务栏设置

【Windows个性化设置篇】StartAllBack更改win11任务栏设置 Windows11目前不支持更改任务栏位置固定的修改&#xff0c;因为想把任务栏固定到旁边&#xff0c;从而充分利用电脑屏幕位置。之前试过TranslucentTB可以把任务栏透明化&#xff0c;很漂亮&#xff0c;但在分屏操作时…

【Vue3】Vue3+Vite+TS使用npm包引入百度地图

文章目录 Vue3ViteTS引入百度地图一、注册二、安装依赖包三、参考文档四、全局注册五、局部导入六、断网地图的使用八、项目使用成功图片九、使用卫星图 Vue3ViteTS引入高德地图npm包查找地图依赖包 Vue3ViteTS引入百度地图 一、注册 官网&#x1f449;百度地图开放平台 注册…

python---案例分析(1)

标准库 python自带的 第三方库 其他人做出来的 例1: 实现一个日期计算器 EG: 计算2012年2月14日和2016年2月3日之间的差值 使用datetime 1.根据日期构造出datetime类型的变量 2.把两个变量进行相减,得到的结果即为所求 1) 2) 3) 例2: 实现单词逆序 翻转单词顺序 i am a s…

MySQL数据库表的操作

创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎; 说明&#xff1a; field 表示列名。 datatype 表示列的类型。 character set 字符集&#xff0c;如果没有指…