likes
comments
collection
share

Vue3实现鼠标hover:类似Nitro首页卡片发光效果Vue3实现鼠标hover:类似Nitro首页卡片发光效果,其

作者站长头像
站长
· 阅读数 38

Vue3实现鼠标hover:类似Nitro首页卡片发光效果Vue3实现鼠标hover:类似Nitro首页卡片发光效果,其

偶然间点开nitro文档时,发现其页面鼠标移动至卡片上效果很有趣,故尝试实现其效果。

其主要使用CSSbackground: radial-gradient(xxx)和JS监听指定元素的鼠标移动mousemove事件来实现的

CSS radial-gradient

radial-gradient其作用是创建一个图像,该图像由从原点辐射的两种或多种颜色之间的渐进过渡组成,其形状可以是圆形或椭圆形。我们所需是创建一个渐变圆形,其效果如同一个手电筒效果。

Vue3实现鼠标hover:类似Nitro首页卡片发光效果Vue3实现鼠标hover:类似Nitro首页卡片发光效果,其

   .card::before {
      background: radial-gradient(
        500px circle at var(--x) var(--y),
        var(--fl-color),
        transparent 40%
      );
      will-change: background;
    }

如上图所示效果,也可进行扩展实现其他有趣的效果

JS监听获取在Cards容器内的位置

  • 页面元素结构

Vue3实现鼠标hover:类似Nitro首页卡片发光效果Vue3实现鼠标hover:类似Nitro首页卡片发光效果,其

  • JS监听Cards容器鼠标移动事件

    JS监听Cards容器内容鼠标的移动,并设置每个子Card的x,y轴方向上的位置,用于设置radial-gradient属性。

    // cardListRef 为外部Cards容器,cardListRef为子card元素集合
    function handleCardElMouseProperty(e){
     if(!cardListRef.value.length) return;
     for (const card of cardListRef.value) {
       const rect = card.getBoundingClientRect(),
         x = e.clientX - rect.left,
         y = e.clientY - rect.top;
       card!.style.setProperty("--x", `${x}px`);
       card!.style.setProperty("--y", `${y}px`);
       // 设置主题色
       card!.style.setProperty("--fl-color", props.color);
     }
   }

以上两步为该效果主要代码,其效果能实现圆形区域跟随鼠标移动,但是还缺少两点:

1、无边框效果 2、文字内容会被遮盖

完善细节

目前只需要解决以上两点即可达成最终效果:

1、无边框效果高亮 上述的圆形手电筒效果也是利用伪元素::before实现的,将每个Card的伪元素进行调整

.card::before{
  content: "";
  height: calc(100% + 4px);
  position: absolute;
  width: calc(100% + 4px);
  display: block;
  inset: -2px;
  z-index:-1;
  background: radial-gradient(
      500px circle at var(--x) var(--y),
      var(--fl-color),
  transparent 40%
  );
  will-change: background;
}

Vue3实现鼠标hover:类似Nitro首页卡片发光效果Vue3实现鼠标hover:类似Nitro首页卡片发光效果,其

经由如上调整,则能够展示完整边框效果,但是由于设置的z-index:-1会导致每个card里面的亮部区域丢失

2、文字内容会被遮盖

如上一步骤调整后,card里面的亮部区域丢失了文字内容就不会被覆盖,但是还是不完善,如果将card的内容区域设置为一个单独的div元素,将其背景颜色与外部设置一致,并且设置起hover上增加背景色的透明度即可达成nitro一致的交互效果。

// card-content 为子card的内容元素
    .card-content{
      background-color: var(--card-bg-color);
      ...
    }
    .card-content:hover{
      opacity: 0.9;
    }
转载自:https://juejin.cn/post/7406279925118976034
评论
请登录