起飞咯!

Published on
/
/趣玩前端
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>起飞咯!</title>
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"
    />
    <style>
      * {
        box-sizing: border-box;
      }
      body {
        --hue: 12;
        --star: #f7c655;
        --bg: #262626;
        --strap: #212121;
        --red: #ed685e;
        --orange: #ed975e;
        --lime: #e4ed5e;
        --green: #84ed5e;
        --turquoise: #5ee4ed;
        --purple: #685eed;
        --indigo: #975eed;
        --violet: #ed5eb4;
        --tail: hsl(var(--hue), 27%, 62%);
        --stroke: #1a1a1a;
        --muzzle: hsl(var(--hue), 43%, 89%);
        --dark: hsl(var(--hue), 33%, 67%);
        --light: hsl(var(--hue), 65%, 79%);
        --strap: #333;
        background: var(--bg);
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 100vh;
        overflow: hidden;
      }
      svg {
        height: 100vmin;
        display: none;
      }
      .stars path {
        fill: var(--star);
      }
      .kitty__light {
        fill: var(--light);
      }
      .kitty__dark {
        fill: var(--dark);
      }
      .kitty__dark-stroke {
        stroke: var(--dark);
      }
      .kitty__stroke {
        stroke: var(--stroke);
      }
      .kitty__fill {
        fill: var(--stroke);
      }
      .kitty__muzzle {
        fill: var(--muzzle);
      }
      .kitty__tail {
        stroke: var(--tail);
      }
      .rocket__strap {
        fill: var(--strap);
      }
      .rocket__body path:nth-of-type(1) {
        fill: #a6a6a6;
      }
      .rocket__body path:nth-of-type(2) {
        fill: #333;
      }
      .rocket__body path:nth-of-type(3) {
        fill: #d9d9d9;
      }
      .rocket__body path:nth-of-type(4) {
        fill: #4d4d4d;
      }
      .rocket__stream path:nth-of-type(1),
      .rocket__bubbles path:nth-of-type(1),
      .rocket__stream path:nth-of-type(8),
      .rocket__bubbles path:nth-of-type(8) {
        fill: var(--red);
      }
      .rocket__stream path:nth-of-type(2),
      .rocket__bubbles path:nth-of-type(2),
      .rocket__stream path:nth-of-type(9),
      .rocket__bubbles path:nth-of-type(9) {
        fill: var(--orange);
      }
      .rocket__stream path:nth-of-type(3),
      .rocket__bubbles path:nth-of-type(3),
      .rocket__stream path:nth-of-type(10),
      .rocket__bubbles path:nth-of-type(10) {
        fill: var(--lime);
      }
      .rocket__stream path:nth-of-type(4),
      .rocket__bubbles path:nth-of-type(4),
      .rocket__stream path:nth-of-type(11),
      .rocket__bubbles path:nth-of-type(11) {
        fill: var(--green);
      }
      .rocket__stream path:nth-of-type(5),
      .rocket__bubbles path:nth-of-type(5),
      .rocket__stream path:nth-of-type(12),
      .rocket__bubbles path:nth-of-type(12) {
        fill: var(--turquoise);
      }
      .rocket__stream path:nth-of-type(6),
      .rocket__bubbles path:nth-of-type(6),
      .rocket__stream path:nth-of-type(13),
      .rocket__bubbles path:nth-of-type(13) {
        fill: var(--purple);
      }
      .rocket__stream path:nth-of-type(7),
      .rocket__bubbles path:nth-of-type(7),
      .rocket__stream path:nth-of-type(14),
      .rocket__bubbles path:nth-of-type(14) {
        fill: var(--indigo);
      }
      .rocket__stream path:nth-of-type(8),
      .rocket__bubbles path:nth-of-type(8),
      .rocket__stream path:nth-of-type(15),
      .rocket__bubbles path:nth-of-type(15) {
        fill: var(--violet);
      }
    </style>
  </head>
  <body>
    <!-- partial:index.partial.html -->
    <svg
      class="scene"
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 1258 1186"
      clip-rule="evenodd"
      fill-rule="evenodd"
      stroke-linecap="round"
      stroke-linejoin="round"
    >
      <g class="rocket">
        <g class="rocket__stream">
          <path d="M745 608h6v263h-6z" />
          <path d="M761 608h6v263h-6z" />
          <path d="M755 608h6v263h-6z" />
          <path d="M749 608h6v263h-6z" />
          <path d="M778 608h6v263h-6z" />
          <path d="M772 608h6v263h-6z" />
          <path d="M767 608h6v263h-6z" />
        </g>
        <g class="rocket__bubbles">
          <path d="M717 869a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M704 873a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M736 863a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M774 865a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M720 884a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M719 876a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M765 879a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M738 884a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M721 851a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M716 876a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M747 881a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M764 882a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M766 852a25 25 0 1150 0 25 25 0 01-50 0z" />
          <path d="M735 847a25 25 0 1150 0 25 25 0 01-50 0z" />
        </g>
        <g class="rocket__body">
          <path d="M743 602h43v9h-43z" />
          <path d="M776 601h10v10h-10z" />
          <path d="M764 442c-17 0-31 15-31 33v129h63V475c0-18-14-33-32-33z" />
          <path
            d="M764 442c18 0 32 15 32 33v129h-8V475c0-16-12-30-27-32l3-1z"
          />
        </g>
      </g>
      <g class="kitty">
        <g class="kitty__tails">
          <path
            class="kitty__tail"
            d="M698 618c-2 16-9 38-6 53 3 12 14 22 15 35 1 16-6 32-8 46"
            fill="none"
            stroke-width="20"
          />
          <path
            class="kitty__tail"
            d="M701 619c2 16 9 38 5 53-2 12-13 21-14 34-2 17 6 33 7 47"
            fill="none"
            stroke-width="20"
          />
        </g>
        <g class="kitty__leg kitty__leg--right">
          <path
            class="kitty__light"
            d="M670 588c8 0 15 7 15 15v93c0 8-7 15-15 15s-14-7-14-15v-93c0-8 6-15 14-15z"
          />
          <path
            class="kitty__dark"
            d="M677 590l2 7v94c0 8-6 14-14 14l-7-2c2 5 7 8 12 8 8 0 15-7 15-15v-93c0-6-3-10-8-13z"
          />
        </g>
        <g class="kitty__leg kitty__leg--left">
          <path
            class="kitty__light"
            d="M730 591c8 0 14 6 14 14v94c0 8-6 14-14 14s-15-6-15-14v-94c0-8 7-14 15-14z"
          />
          <path
            class="kitty__dark"
            d="M737 593l2 6v94c0 8-7 15-15 15-3 0-5-1-7-3 2 5 7 8 13 8 8 0 14-6 14-14v-94c0-5-3-10-7-12z"
          />
        </g>
        <g class="kitty__body">
          <path
            class="kitty__light"
            d="M699 446c27 0 49 22 49 48v97c0 27-22 48-49 48s-49-21-49-48v-97c0-26 22-48 49-48z"
          />
          <path
            class="kitty__dark"
            d="M699 639c27 0 49-22 49-48l1-98c-1-15-10-28-21-37 5 8 9 17 9 27v97c1 27-21 48-48 49-12 0-22-4-30-10 9 12 24 20 40 20z"
          />
        </g>
        <path
          class="rocket__strap"
          d="M652 509l91-11c5-1 9 3 10 7v1c0 5-3 9-8 10l-91 11c-5 0-9-3-10-8v-1c0-5 3-9 8-9z"
        />
        <g class="kitty__arm kitty__arm--right">
          <path
            class="kitty__light"
            d="M734 468c8 2 13 10 11 18l-20 91c-2 8-10 13-18 11s-13-10-11-17l21-92c2-8 9-13 17-11z"
          />
          <path
            class="kitty__dark"
            d="M741 471v8l-21 91c-1 8-9 13-17 11l-7-4c2 5 6 10 11 11 8 2 16-3 18-11l21-92c1-5-1-10-5-14z"
          />
        </g>
        <g class="kitty__arm kitty__arm--left">
          <path
            class="kitty__light"
            d="M659 475c8 2 13 10 11 18l-22 91c-2 8-10 13-18 11s-13-10-11-18l23-91c1-8 9-13 17-11z"
          />
          <path
            class="kitty__dark"
            d="M665 479l1 7-23 91c-1 8-9 13-17 11l-7-4c2 5 6 9 11 11 8 2 16-3 18-11l22-91c1-5-1-10-5-14z"
          />
        </g>
        <g class="kitty__head">
          <g class="kitty__stroke" fill="none" stroke-width="5">
            <path d="M548 467c-18 10-38 13-54 26" />
            <path d="M560 485l-48 31" />
            <path d="M574 495c-9 7-14 19-17 30" />
            <path d="M745 351c7-13 31-22 43-30" />
            <path d="M757 374c11-8 24-19 38-12" />
            <path d="M760 390c10-6 38 4 47 9" />
          </g>
          <path
            class="kitty__light"
            d="M652 326c4-107 90-53 73 8 48 34 64 104-5 155-94 71-188 9-181-68-37-57-22-143 46-67"
          />
          <path
            class="kitty__muzzle"
            d="M616 454c-7-14 5-34 28-46 22-11 46-9 53 5s-5 35-27 46c-23 12-47 9-54-5z"
          />
          <g class="kitty__eye kitty__eye--left">
            <path
              class="kitty__stroke kitty__fill"
              d="M565 444a7 7 0 1112-8 7 7 0 01-12 8z"
              stroke-width="5"
            />
          </g>
          <g class="kitty__eye kitty__eye--right">
            <path
              class="kitty__stroke kitty__fill"
              d="M712 377a7 7 0 1112-7 7 7 0 01-12 7z"
              stroke-width="5"
            />
          </g>
          <path
            class="kitty__light"
            d="M570 369c9-8 15-20 25-27 22-15 47-18 72-16"
          />
          <path
            class="kitty__dark-stroke"
            d="M690 287c-18-22-28 18-25 30v3"
            fill="none"
            stroke-width="4"
          />
          <path
            class="kitty__dark-stroke"
            d="M536 352c-6-8 2-21 11-15 6 5 12 9 17 15 1 2 7 10 8 9"
            fill="none"
            stroke-width="4"
          />
          <path
            class="kitty__stroke"
            d="M631 451c19 7 15-12 26-15 4-2 10 3 16 0 2-2 14-11 11-13"
            fill="none"
            stroke-width="4"
          />
          <path
            class="kitty__stroke"
            d="M644 426c-1-3 1-5 4-7 3-1 7-1 8 1s-1 5-4 7c-4 1-7 1-8-1z"
            stroke-width="2"
          />
          <path
            class="kitty__dark"
            d="M695 267c14 12 23 35 17 59 47 34 63 104-6 155-47 36-94 38-129 21 35 25 89 28 143-13 69-51 53-121 5-155 9-31-10-61-30-67z"
          />
        </g>
      </g>
      <g class="stars">
        <path
          d="M908 657l-10-9-13 4 5-12-8-11h13l8-10 4 13 13 4-11 7z"
          fill-rule="nonzero"
        />
        <path
          d="M1128 89l-10-8-13 3 5-12-8-11 13 1 8-11 4 13 13 4-11 8z"
          fill-rule="nonzero"
        />
        <path
          d="M296 287l-10-9-13 4 5-12-8-11h13l8-10 4 13 12 4-11 7z"
          fill-rule="nonzero"
        />
        <path
          d="M188 991l-10-8-13 4 5-13-8-11 13 1 8-11 4 13 13 4-11 8z"
          fill-rule="nonzero"
        />
        <path
          d="M1227 1137l-10-9-13 4 5-12-8-11h13l8-10 4 13 12 4-11 7z"
          fill-rule="nonzero"
        />
      </g>
    </svg>
    <!-- partial -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.3/gsap.min.js"></script>
    <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin3.min.js"></script>
    <script>
      const {
        gsap: {
          set,
          to,
          timeline,
          utils: { random },
        },
      } = window;

      const TAILS = [...document.querySelectorAll('.kitty__tail')];
      const STARS = [...document.querySelectorAll('.stars path')];
      const BUBBLES = [...document.querySelectorAll('.rocket__bubbles path')];
      const EYES = [...document.querySelectorAll('.kitty__eye')];

      set('.scene', { display: 'block' });

      set(TAILS[1], { display: 'none' });
      to(TAILS[0], {
        duration: 0.1,
        ease: 'none',
        yoyo: true,
        repeat: -1,
        morphSVG: TAILS[1],
      });

      set('.stars path', {
        y: -1185,
        transformOrigin: '50% 50%',
        rotation: 'random(0, 360)',
        scale: 'random(0.2, 1.2)',
      });

      STARS.forEach((star) =>
        to(star, {
          repeat: -1,
          duration: 'random(4, 10)',
          delay: () => 'random(-10, -5)',
          y: 1185,
          ease: 'none',
        })
      );

      set(BUBBLES, { scale: 0, transformOrigin: '50% 50%' });
      BUBBLES.forEach((bubble) =>
        timeline({ repeat: -1, yoyo: true })
          .to(bubble, {
            duration: 0.5,
            scale: 2.5,
          })
          .to(
            bubble,
            {
              duration: 0.2,
              opacity: 0,
            },

            '>-0.2'
          )
          .seek(Math.random())
      );

      set(EYES, { transformOrigin: '50% 50%', rotate: -25 });

      const blink = () => {
        const delay = random(2, 5);
        to(EYES, {
          delay,
          duration: 0.1,
          repeat: 1,
          yoyo: true,
          scaleY: 0,
          onComplete: () => blink(),
        });
      };
      blink();

      to('.kitty__head', {
        repeat: -1,
        yoyo: true,
        rotate: 2,
        duration: 0.1,
        transformOrigin: '75% 75%',
      });

      to('.kitty__arm', {
        repeat: -1,
        yoyo: true,
        rotate: 2,
        duration: 0.1,
        transformOrigin: '75% 15%',
      });

      to('.kitty__leg--left', {
        repeat: -1,
        yoyo: true,
        rotate: 2,
        duration: 0.1,
        transformOrigin: '50% 5%',
      });

      to('.kitty__leg--right', {
        repeat: -1,
        yoyo: true,
        rotate: -2,
        duration: 0.1,
        transformOrigin: '50% 5%',
      });

      const PARTY = timeline({
        paused: true,
      }).fromTo(
        document.body,
        {
          '--hue': 0,
        },

        {
          '--hue': 360,
          repeat: 10,
          ease: 'none',
        }
      );

      const keys = [];
      const shouldWeParty = (e) => {
        keys.push(e.key);
        if (
          keys
            .slice(keys.length - 5, keys.length)
            .join('')
            .toLowerCase() === 'party'
        ) {
          // Let's party
          keys.length = 0;
          PARTY.restart();
        }
      };
      window.addEventListener('keyup', shouldWeParty);
    </script>
  </body>
</html>