分享一个下载按钮

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

<!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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

timi先生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值