实现mac的docker栏效果

349 阅读1分钟

完整代码

<template>
  <div class="dockBox">
    <div class="glass">
      <ul class="dock">
        <li>😃</li>
        <li>😊</li>
        <li>😜</li>
        <li>😍</li>
        <li>🤩</li>
        <li>🥳</li>
        <li>🥶</li>
        <li>😃</li>
        <li>😊</li>
        <li>😜</li>
        <li>😍</li>
        <li>🤩</li>
        <li>🥳</li>
        <li>🥶</li>
      </ul>
    </div>
  </div>

</template>

<script lang="ts" setup>
import { defineComponent, ref } from "vue";
function resetScale() {
  document.querySelectorAll(".dock li").forEach((li) => {
    li.style.setProperty("--scale", 1);
  });
}
onMounted(() => {
  document.querySelectorAll(".dock li").forEach((li) => {
    li.addEventListener("click", (e) => {
      e.currentTarget.classList.add("loading");
    });
    li.addEventListener("mousemove", (e) => {
      // 当事件被触发时,获取目标元素
      let item = e.target;
      // 获取目标元素的矩形信息
      let itemRect = item.getBoundingClientRect();
      // 计算鼠标指针在目标元素内的偏移量
      let offset = Math.abs(e.clientX - itemRect.left) / itemRect.width;
      // 获取目标元素的前一个兄弟元素(如果存在)
      let prev = item.previousElementSibling || null;
      // 获取目标元素的后一个兄弟元素(如果存在)
      let next = item.nextElementSibling || null;
      // 设置缩放的基准比例
      let scale = 0.6;
      // 重置所有元素的缩放比例
      resetScale();
      // 如果前一个元素存在,根据偏移量调整其缩放比例
      if (prev) {
        prev.style.setProperty("--scale", 1 + scale * Math.abs(offset - 1));
      }
      // 设置当前元素的缩放比例
      item.style.setProperty("--scale", 1 + scale);
      // 如果后一个元素存在,根据偏移量调整其缩放比例
      if (next) {
        next.style.setProperty("--scale", 1 + scale * offset);
      }
    });
  });
  document.querySelector(".dock").addEventListener("mouseleave", (e) => {
    resetScale();
  });
});
</script>

<style scoped>
html {
  font-size: 15px;
}

.dockBox {
  margin: 0;
  padding: 0;
  display: flex;
  width: 100%;
  min-height: 100vh;
  overflow: hidden;
  align-items: flex-end;
  background-image: linear-gradient(
    109.6deg,
    rgba(25, 170, 209, 1) 11.3%,
    rgba(21, 65, 249, 1) 69.9%
  );
}

.glass {
  width: 100%;
  height: 8rem;
  background: rgba(255, 255, 255, 0.25);
  box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  border: 1px solid rgba(255, 255, 255, 0.18);
  display: flex;
  justify-content: center;
}

.dock {
  --scale: 1;

  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.dock li {
  font-size: calc(6rem * var(--scale));
  padding: 0 0.5rem;
  cursor: default;

  position: relative;
  top: calc((6rem * var(--scale) - 6rem) / 2 * -1);

  transition: 15ms all ease-out;
}

.dock li.loading {
  animation: 1s loading ease-in infinite;
}

@keyframes loading {
  0%,
  100% {
    transform: translateY(0px);
  }
  60% {
    transform: translateY(-40px);
  }
}
</style>


原理就是监听鼠标的移入移除,给鼠标位置、鼠标的前后元素进行设置一个scale,以及添加动画过度