gsap+svg实现火箭发射式tab选项卡导航条动画效果代码

代码语言:html

所属分类:菜单导航

代码描述:gsap+svg实现火箭发射式tab选项卡导航条动画效果代码

代码标签: gsap svg 火箭 发射式 tab 选项卡 导航条 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  
<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/normalize.5.0.css">
<link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/inter.3.19.3.css">
<style>
nav {
  position: relative;
  z-index: 1;
}
nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  gap: 40px;
}
nav ul li button {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: none;
  cursor: pointer;
  background-color: transparent;
  padding: 0;
  margin: 0;
  font-family: "Inter";
  font-weight: 600;
  font-size: 16px;
  list-style: 22px;
  color: #5C5B66;
  transition: color 0.25s;
}
nav ul li.active button {
  color: #fff;
}
nav ul li:not(.active):hover button {
  color: #807E8C;
}
nav .active-element {
  --active-element-scale-x: 1;
  --active-element-scale-y: 1;
  --active-element-show: 0;
  --active-element-opacity: 0;
  --active-element-width: 0px;
  --active-element-strike-x: 0%;
  --active-element-mask-position: 0%;
  position: absolute;
  left: 0;
  top: 34px;
  height: 3px;
  width: 36px;
  border-radius: 2px;
  background-color: #fff;
  opacity: var(--active-element-show);
}
nav .active-element > svg,
nav .active-element .strike {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  opacity: var(--active-element-opacity);
  width: var(--active-element-width);
  mix-blend-mode: multiply;
}
nav .active-element > svg {
  display: block;
  overflow: visible;
  height: 5px;
  filter: blur(0.5px) drop-shadow(2px 0px 8px rgba(0, 117, 255, 0.4)) drop-shadow(1px 0px 2px rgba(0, 128, 255, 0.8)) drop-shadow(0px 0px 3px rgba(153, 204, 255, 0.4)) drop-shadow(2px 0px 8px rgba(137, 196, 255, 0.45)) drop-shadow(8px 0px 16px rgba(153, 204, 255, 0.5));
}
nav .active-element .strike {
  padding: 24px 0;
  -webkit-mask-image: linear-gradient(to right, transparent calc(0% + var(--active-element-mask-position)), black calc(15% + var(--active-element-mask-position)), black 80%, transparent);
  mask-image: linear-gradient(to right, transparent calc(0% + var(--active-element-mask-position)), black calc(15% + var(--active-element-mask-position)), black 80%, transparent);
}
nav .active-element .strike svg {
  display: block;
  overflow: visible;
  height: 12px;
  width: calc(var(--active-element-width) * 2);
  transform: translate(var(--active-element-strike-x), 30%) scale(var(--active-element-scale-x), var(--active-element-scale-y));
}
nav .active-element .strike svg:last-child {
  transform: translate(var(--active-element-strike-x), -30%) scale(-1);
}
nav .active-element .strike svg g path:nth-child(2) {
  filter: blur(2px);
}
nav .active-element .strike svg g path:nth-child(3) {
  filter: blur(4px);
}
nav.before .active-element {
  transform: rotateY(180deg);
}

html {
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
}

* {
  box-sizing: inherit;
}
*:before, *:after {
  box-sizing: inherit;
}

body {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #020112;
  position: relative;
  overflow: hidden;
}
body:before {
  content: "";
  position: absolute;
  inset: 40% -60% 0 -60%;
  background-image: radial-gradient(ellipse at bottom, #152B9D 0%, #020112 50%);
  opacity: 0.3;
  pointer-events: none;
}
body .twitter {
  position: fixed;
  display: block;
  right: 12px;
  bottom: 12px;
}
body .twitter svg {
  width: 32px;
  height: 32px;
  fill: #fff;
}
</style>


  
  
</head>

<body >
  <nav>
  <ul>
    <li class="active">
      <button>Animation</button>
    </li>
    <li>
      <button>Branding</button>
    </li>
    <li>
      <button>Illustration</button>
    </li>
  </ul>

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.11.0.js"></script>
      <script  >
const navElement = document.querySelector("nav");

const activeElement = document.createElement("div");
activeElement.classList.add("active-element");

const getOffsetLeft = element => {
  const elementRect = element.getBoundingClientRect();

  return (
    elementRect.left -
    navElement.getBoundingClientRect().left +
    (elementRect.width - activeElement.offsetWidth) / 2);

};

navElement.appendChild(activeElement);

const activeButton = navElement.querySelector("ul li.active button");

document.fonts.ready.then(() => {
  gsap.set(activeElement, {
    x: getOffsetLeft(activeButton) });

  gsap.to(activeElement, {
    "--active-element-show": "1",
    duration: 0.2 });

});

navElement.querySelectorAll("ul li button").forEach((button, index) => {
  button.addEventListener("click", () => {
    const active = navElement.querySelector("ul li.active");
    const oldIndex = [...active.parentElement.children].indexOf(active);

    if (
    index === oldIndex ||
    navElement.classList.contains("before") ||
    navElement.classList.contains("after"))
    {
      return;
    }

    const x = getOffsetLeft(button);
    const direction = index > oldIndex ? "after" : "before";
    const spacing = Math.abs(x - getOffsetLeft(active));

    navElement.classList.add(direction);
    active.classList.remove("active");
    button.parentElement.classList.add("active");

    gsap.set(activeElement, {
      rotateY: direction === "before" ? "180deg" : "0deg" });


    gsap.to(activeElement, {
      keyframes: [
      {
        "--active-element-width": `${
        spacing > navElement.offsetWidth - 60 ?
        navElement.offsetWidth - 60 :
        spacing
        }px`,
        duration: 0.3,
        ease: "none",
        onStart: () => {
          createSVG(activeElement);

          gsap.to(activeElement, {
            "--active-element-opacity": 1,
            duration: 0.1 });

        } },

      {
        "--active-element-scale-x": "0",
        "--active-element-scale-y": ".25",
        "--active-element-width": "0px",
        duration: 0.3,
        onStart: () => {
          gsap.to(activeElement, {
            "--active-element-mask-position": "40%",
            duration: 0.5 });

          gsap.to(activeElement, {
            "--active-element-opacity": 0,
            delay: 0.45,
            duration: 0.25 });

        },
        onComplete: () => {
          activeElement.innerHTML = "";
          navElement.classList.remove("before", "after");
          activeElement.removeAttribute("style");
          gsap.set(activeElement, {
            x: getOffsetLeft(button),
            "--active-element-show": "1" });

        } }] });




    gsap.to(activeElement, {
      x,
      "--active-element-strike-x": "-50%",
      duration: 0.6,
      ease: "none" });

  });
});

const createSVG = element => {
  element.innerHTML = `
    <svg viewBox="0 0 116 5" preserveAspectRatio="none" class="beam">
      <path d="M0.5 2.5L113 0.534929C114.099 0.515738 115 1.40113 115 2.5C115 3.59887 114.099 4.48426 113 4.46507L0.5 2.5Z" fill="url(#gradient-beam)"/>
      <defs>
        <linearGradient id="gradient-beam" x1="2" y1="2.5" x2="115" y2="2.5" gradientUnits="userSpaceOnUse">
          <stop stop-color="#6AAAFF"/>
          <stop offset="1" stop-color="white"/>
        </linearGradient>
      </defs>
    </svg>
    <div class="strike">
      <svg viewBox="0 0 114 12" preserveAspectRatio="none">
        <g fill="none" stroke="white" stroke-width="0.75" stroke-linecap="round">
          <path d="M113.5 6.5L109.068 8.9621C109.023 8.98721 108.974 9.00516 108.923 9.01531L106.889 9.42219C106.661 9.46776 106.432 9.35034 106.336 9.1388L104.045 4.0986C104.015 4.03362 104 3.96307 104 3.8917V2.12268C104 1.6898 103.487 1.46145 103.166 1.75103L99.2887 5.24019C99.1188 5.39305 98.867 5.41132 98.6768 5.28457L95.0699 2.87996C94.7881 2.69205 94.4049 2.83291 94.3118 3.15862L92.6148 9.09827C92.5483 9.33084 92.3249 9.48249 92.0843 9.45843L87.7087 9.02087C87.5752 9.00752 87.4419 9.04839 87.3389 9.13428L84.9485 11.1263C84.7128 11.3227 84.3575 11.2625 84.1996 10.9994L81.7602 6.93359C81.617 6.69492 81.3064 6.61913 81.0694 6.76501L75.3165 10.3052C75.1286 10.4209 74.8871 10.3997 74.7223 10.2531L70.6678 6.64917C70.5611 6.55429 70.5 6.41829 70.5 6.27547V1.20711C70.5 1.0745 70.4473 0.947322 70.3536 0.853553L70.2185 0.718508C70.0846 0.584592 69.8865 0.537831 69.7068 0.59772L69.2675 0.744166C68.9149 0.861705 68.8092 1.30924 69.0721 1.57206L69.605 2.10499C69.8157 2.31571 69.7965 2.66281 69.5638 2.84897L67.5 4.5L65.2715 6.28282C65.1083 6.41338 64.8811 6.42866 64.7019 6.32113L60.3621 3.71725C60.153 3.59179 59.8839 3.63546 59.7252 3.8206L57.0401 6.95327C57.0135 6.9843 56.9908 7.01849 56.9725 7.05505L55.2533 10.4934C55.1188 10.7624 54.779 10.8526 54.5287 10.6858L50.7686 8.17907C50.6051 8.07006 50.3929 8.06694 50.2263 8.17109L46.7094 10.3691C46.5774 10.4516 46.4145 10.468 46.2688 10.4133L42.6586 9.05949C42.5558 9.02091 42.4684 8.94951 42.4102 8.85633L40.1248 5.1997C40.0458 5.07323 40.0273 4.91808 40.0745 4.77659L40.6374 3.08777C40.7755 2.67359 40.3536 2.29381 39.9562 2.47447L35.5 4.5L32.2657 5.88613C32.1013 5.95658 31.9118 5.93386 31.7687 5.82656L30.1904 4.64279C30.0699 4.55245 29.9152 4.5212 29.7691 4.55772L26.2009 5.44977C26.0723 5.48193 25.9617 5.56388 25.8934 5.67759L23.1949 10.1752C23.0796 10.3673 22.8507 10.4593 22.6346 10.4003L17.6887 9.05148C17.5674 9.01838 17.463 8.94076 17.3963 8.83409L15.3331 5.53299C15.1627 5.26032 14.7829 5.21707 14.5556 5.44443L12.1464 7.85355C12.0527 7.94732 11.9255 8 11.7929 8H8.15139C8.05268 8 7.95617 7.97078 7.87404 7.91603L3.74143 5.16095C3.59214 5.06142 3.40096 5.04952 3.24047 5.12976L0.5 6.5" />
          <path d="M113.5 6.5L109.068 8.9621C109.023 8.98721 108.974 9.00516 108.923 9.01531L106.889 9.42219C106.661 9.46776 106.432 9.35034 106.336 9.1388L104.045 4.0986C104.015 4.03362 104 3.96307 104 3.8.........完整代码请登录后点击上方下载按钮下载查看

网友评论0