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

我实现的

直接上代码
用的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)