鼠标滑过样式,元素周围炫光

489 阅读3分钟

前言

在掘金逛到这篇文章(一个鼠标滑过的样式~ - 掘金 (juejin.cn)),模拟实现h3 - The Web Framework for Modern JavaScript Era (unjs.io)的鼠标滑动样式,如下。但仔细看,掘金这篇文章和原处的实现的效果不太一致,于是自己研究了一下,大程度上还原了。

无标题视频——使用Clipchamp制作2.gif

我实现的

无标题视频——使用Clipchamp制作.gif

直接上代码

用的vue3模板,自行转换

<template>
  <div class="container">
    <div class="container-item" v-for="item in 8" :key="item">
      <div class="container-item-content"></div>
    </div>
  </div>
</template><script setup>
import { onMounted } from 'vue'// 获取鼠标位置
const calBoxesPosition = e => {
  const { clientX, clientY } = e
  const items = document.querySelectorAll('.container-item')
  items.forEach(i => {
    const { x, y } = i.getBoundingClientRect()
    i.setAttribute('style', `--x: ${clientX - x}px; --y: ${clientY - y}px`)
  })
}
onMounted(() => {
  window.addEventListener('mousemove', calBoxesPosition)
})
</script><style lang="scss" scoped>
.container {
  --color-background: 23 23 23;
  --color-font: #fff;
  --color-border: #222222;
  --bg-color: #2dd4bf;
  --bg-opacity: 1;
  width: 1500px;
  padding: 20px;
  height: 800px;
  background-color: rgb(var(--color-background));
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  grid-gap: 20px;
  .container-item {
    color: var(--color-font);
    border-radius: 12px;
    box-shadow: 0 0 1px 1px var(--color-border);
    position: relative;
    transition: background 0.5s ease-in-out;
    &::before {
      position: absolute;
      display: block;
      content: '';
      z-index: 2;
      width: calc(100% + 4px);
      height: calc(100% + 4px);
      inset: -2px;
      border-radius: 12px;
      background: radial-gradient(250px circle at var(--x) var(--y), var(--bg-color) 0, transparent 100%);
      will-change: background;
    }
    .container-item-content {
      border-radius: 12px;
      background-color: rgb(var(--color-background) / var(--bg-opacity));
      width: 100%;
      position: relative;
      z-index: 3;
      padding: 20px;
      height: 100%;
      &:hover {
        --bg-opacity: 0.9;
      }
    }
  }
}
</style>

重点分析

伪元素:before

&::before {
      position: absolute;
      display: block;
      content: '';
      z-index: 2;
      width: calc(100% + 4px);
      height: calc(100% + 4px);
      inset: -2px;
      border-radius: 12px;
      background: radial-gradient(250px circle at var(--x) var(--y), var(--bg-color) 0, transparent 100%);
      will-change: background;
    }

为了实现container-item元素周围鼠标滑动的炫光,需要用一个比它大的盒子包围它,这里用伪元素,width和height是父元素的100%+4px,再通过inset整体偏移回去2px,则可实现包围container-item,2px的空隙可存放炫光。

炫光形成:

以鼠标为圆心,做一圆,半径为250px,颜色渐变.伪元素背景为radial-gradient,渐变起始点为圆心,终点为透明。当鼠标靠近container-item时,圆在伪元素可视区域内,颜色渐变,形成炫光。

确定圆心:

实时通过鼠标的位置坐标,拿到鼠标到container-item的距离,因为是伪元素是对container-item相对定位的,因此不能直接用鼠标的位置坐标为圆心

will-change 是一个CSS属性,它允许开发者告知浏览器某些元素将要发生的变化,以便浏览器可以提前进行优化,从而在变化实际发生时提供更平滑的动画和过渡效果。

z-index

需注意的是,z-index生效的条件是,元素有定位,且不是static。 container-item下面还有一层container-item-content,该元素撑大充满container-item,并且z-index要比伪元素大,将伪元素与container-item交叉区域覆盖,伪元素的炫光就只在周围出现。当鼠标移入container-item时,可通过:hover将container-item-content的背景颜色opacity降低一点,就会出现淡淡的炫光效果在item内。

参考

一个鼠标滑过的样式~ - 掘金 (juejin.cn)

h3 - The Web Framework for Modern JavaScript Era (unjs.io)