【CSS】卡片hover效果跟著鼠標(biāo)動(dòng)

CSS+JS實(shí)現(xiàn)hover效果跟著鼠標(biāo)動(dòng)


實(shí)現(xiàn)效果
// page
// const src = "https://i.pinimg.com/736x/f0/c3/23/f0c323f370acf6cf35973ca5f53ecc89.jpg"; 
const src = "https://oss.aiyuzhou8.com/2023/05/08-.jpg";

<div className="w-full h-full flex items-center bg-[#001] ">
      <RotatingCard src={src} />
</div>
// RotatingCard
'use client';
import "./index.css";
import { useRef } from "react";

interface RotatingCardProps {
  src: string;
}

const RotatingCard = ({ src }: RotatingCardProps) => {
  const container = useRef<HTMLDivElement | null>(null);
  const mask = useRef<HTMLDivElement | null>(null);

  const handleContainerMouseMove = (event) => {
    if (container.current && mask.current) {
      mask.current.style.visibility = "visible";
      const target = event.target;
      const rect = target.getBoundingClientRect();
      const offsetX = event.clientX - rect.left;
      const offsetY = event.clientY - rect.top;

      const percentX = (Math.min(Math.max(offsetX/rect.width, 0), 1) * 100).toFixed(2);
      const percentY = (Math.min(Math.max(offsetY/rect.height, 0), 1) * 100).toFixed(2);

      container.current?.setAttribute(
        'style',
        `--x: ${percentX}%; --y: ${percentY}%;--pic: url(${src});`
      );
    }
  }

  const handleContainerMouseOut = () => {
    if (mask.current) {
      mask.current.style.visibility = "hidden";
    }
  }

  return (
    <div
      className="container"
      ref={container}
      onMouseOut={handleContainerMouseOut}
      onMouseMove={handleContainerMouseMove}
      style={{ "--pic": `url(${src})` }}
    >
      <div className="filter" style={{ "--pic": `url(${src})` }} />
      <div className="mask" ref={mask} />
    </div>
  );
};

export default RotatingCard;
// index.css
:root {
    --x: 0;
    --y: 0;
    --pic: url("https://oss.aiyuzhou8.com/2023/05/08-.jpg");
    --borderRadius: 30px;
}
.container {
    position: relative;
    margin: auto;
    width: 350px;
    height: 500px;
    border-radius: 30px;
    transition: all 0.1s;
    z-index: 3;

    &::after {
        content: "";
        position: absolute;
        inset: 50px;
        background: var(--pic);
        background-size: cover;
        background-position: center;
        border-radius: var(--borderRadius);
        z-index: 10;
    }
}

.filter {
    position: absolute;
    inset: 2px;
    border-radius: var(--borderRadius);
    z-index: 5;
    overflow: hidden;

    &::before {
        content: "";
        position: absolute;
        inset: 0;
        background: var(--pic);
        background-size: cover;
        filter: blur(20px);
    }
}

.mask {
    position: absolute;
    filter: brightness(1.5);
    inset: 0;
    z-index: 1;
    visibility: hidden;
    mask: radial-gradient(
            circle at var(--x) var(--y),
            #000,
            #000,
            transparent,
            transparent,
            transparent
         );

    &::before {
        content: "";
        position: absolute;
        inset: 2px;
        border-radius: var(--borderRadius);
        background: conic-gradient(
            #03a9f4,
            #e91e63,
            #9c27b0,
            #ff5722,
            #03a9f4
        );
    }

    &::after{
        content: "";
        position: absolute;
        inset: 0;
        border-radius: var(--borderRadius);
        background: conic-gradient(
            #03a9f4,
            #e91e63,
            #9c27b0,
            #ff5722,
            #03a9f4
        );
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容