仿macOS Dock栏源码

旺东

文章最后更新时间:2024年08月27日

仿macOS Dock栏源码

使用 CSS 和 JavaScript 来实现类似于 macOS Dock 的放大效果,当鼠标移动到表情图标上时,会产生相应的缩放效果。鼠标移动事件会根据鼠标位置计算偏移量,并根据偏移量调整当前元素以及前后元素的缩放比例。通过设置 --scale 自定义属性来实现缩放效果,然后在 resetScale 函数中重置缩放比例。该源码非常适合用于导航菜单,美观丝滑且流畅。

作者:https://youtu.be/ULMksUfcUsk

演示:

gif-2024-08-20 at 18.40.23.gif

<div class="glass">
  <ul class="dock">
    <li>😃</li>
    <li>😊</li>
    <li>😜</li>
    <li>😍</li>
    <li>🤩</li>
    <li>🥳</li>
    <li>🥶</li>
  </ul>
</div>
html {
  font-size: 15px;
}

body {
  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 .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);
  }
}
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()
})

function resetScale() {
  document.querySelectorAll('.dock li').forEach(li => {
    li.style.setProperty('--scale', 1)
  })
}

发表评论

快捷回复:表情:
AddoilApplauseBadlaughBombCoffeeFabulousFacepalmFecesFrownHeyhaInsidiousKeepFightingNoProbPigHeadShockedSinistersmileSlapSocialSweatTolaughWatermelonWittyWowYeahYellowdog
验证码
评论列表 (暂无评论,298人围观)

还没有评论,来说两句吧...

取消
微信二维码
微信二维码
支付宝二维码