文章最后更新时间:2024年08月27日
仿macOS Dock栏源码
使用 CSS 和 JavaScript 来实现类似于 macOS Dock 的放大效果,当鼠标移动到表情图标上时,会产生相应的缩放效果。鼠标移动事件会根据鼠标位置计算偏移量,并根据偏移量调整当前元素以及前后元素的缩放比例。通过设置 --scale 自定义属性来实现缩放效果,然后在 resetScale 函数中重置缩放比例。该源码非常适合用于导航菜单,美观丝滑且流畅。
作者:https://youtu.be/ULMksUfcUsk
演示:
<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) }) }
还没有评论,来说两句吧...