日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

使用 React Hooks 實現鼠標懸浮卡片發光的動畫效果

來源: 責編: 時間:2024-06-05 17:43:48 235觀看
導讀有趣的動畫效果前幾天在網上看到了一個很有趣的動畫效果,如下,光會跟隨鼠標在卡片上進行移動,并且卡片會有視差的效果,那么在 React 中應該如何去實現這個效果呢?基本實現思路其實實現思路很簡單,無非就是分幾步:首先,卡片是

有趣的動畫效果

前幾天在網上看到了一個很有趣的動畫效果,如下,光會跟隨鼠標在卡片上進行移動,并且卡片會有視差的效果,那么在 React 中應該如何去實現這個效果呢?7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

基本實現思路

其實實現思路很簡單,無非就是分幾步:7br28資訊網——每日最新資訊28at.com

  • 首先,卡片是相對定位,光是絕對定位
  • 監聽卡片的鼠標移入事件mouseenter,當鼠標進入時顯示光
  • 監聽卡片的鼠標移動事件mouseover,鼠標移動時修改光的left、top,讓光跟隨鼠標移動
  • 監聽卡片的鼠標移出事件mouseleave,鼠標移出時,隱藏光

我們先在 Index.tsx 中準備一個卡片頁面,光的CSS效果可以使用filter: blur() 來實現:7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

卡片視差效果

卡片的視差效果需要用到樣式中 transform 樣式,主要是配置四個東西:7br28資訊網——每日最新資訊28at.com

  • perspective:定義元素在 3D 變換時的透視效果
  • rotateX:X 軸旋轉角度
  • rotateY:Y 軸旋轉角度
  • scale3d:X/Y/Z 軸上的縮放比例

7br28資訊網——每日最新資訊28at.com

給所有卡片添加光源

上面只是給一個卡片增加光源,接下來可以給每一個卡片都增加光源啦!!!7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

讓光源變成可配置

上面的代碼,總感覺這個 hooks 耦合度太高不太通用,所以我們可以讓光源變成可配置化,這樣每個卡片就可以展示不同大小、顏色的光源了~像下面一樣:7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

既然是配置化,那我們希望是這么去使用 hooks 的,我們并不需要自己在頁面中去寫光源的dom節點,也不需要自己去寫光源的樣式,而是通過配置傳入 hooks 中:7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

所以 hooks 內部要自己通過操作 DOM 的方式,去添加、刪除光源,可以使用createElement、appendChild、removeChild 去做這些事~7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

7br28資訊網——每日最新資訊28at.com

完整源碼

// use-light-card.tsimport { useEffect, useRef } from 'react';interface IOptions {  light?: {    width?: number; // 寬    height?: number; // 高    color?: string; // 顏色    blur?: number; // filter: blur()  };}export const useLightCard = (option: IOptions = {}) => {  // 獲取卡片的dom節點  const cardRef = useRef<HTMLDivElement | null>(null);  let cardOverflow = '';  // 光的dom節點  const lightRef = useRef<HTMLDivElement>(document.createElement('div'));  // 設置光源的樣式  const setLightStyle = () => {    const { width = 60, height = 60, color = '#ff4132', blur = 40 } = option.light ?? {};    const lightDom = lightRef.current;    lightDom.style.position = 'absolute';    lightDom.style.width = `${width}px`;    lightDom.style.height = `${height}px`;    lightDom.style.background = color;    lightDom.style.filter = `blur(${blur}px)`;  };  // 設置卡片的 overflow 為 hidden  const setCardOverflowHidden = () => {    const cardDom = cardRef.current;    if (cardDom) {      cardOverflow = cardDom.style.overflow;      cardDom.style.overflow = 'hidden';    }  };  // 還原卡片的 overflow  const restoreCardOverflow = () => {    const cardDom = cardRef.current;    if (cardDom) {      cardDom.style.overflow = cardOverflow;    }  };  // 往卡片添加光源  const addLight = () => {    const cardDom = cardRef.current;    if (cardDom) {      cardDom.appendChild(lightRef.current);    }  };  // 刪除光源  const removeLight = () => {    const cardDom = cardRef.current;    if (cardDom) {      cardDom.removeChild(lightRef.current);    }  };  // 監聽卡片的鼠標移入  const onMouseEnter = () => {    // 添加光源    addLight();    setCardOverflowHidden();  };  // use-light-card.ts  // 監聽卡片的鼠標移動  const onMouseMove = (e: MouseEvent) => {    // 獲取鼠標的坐標    const { clientX, clientY } = e;    // 讓光跟隨鼠標    const cardDom = cardRef.current;    const lightDom = lightRef.current;    if (cardDom) {      // 獲取卡片相對于窗口的x和y坐標      const { x, y } = cardDom.getBoundingClientRect();      // 獲取光的寬高      const { width, height } = lightDom.getBoundingClientRect();      lightDom.style.left = `${clientX - x - width / 2}px`;      lightDom.style.top = `${clientY - y - height / 2}px`;      //   設置動畫效果      const maxXRotation = 10; // X 軸旋轉角度      const maxYRotation = 10; // Y 軸旋轉角度      const rangeX = 200 / 2; // X 軸旋轉的范圍      const rangeY = 200 / 2; // Y 軸旋轉的范圍      const rotateX = ((clientX - x - rangeY) / rangeY) * maxXRotation; // 根據鼠標在 Y 軸上的位置計算繞 X 軸的旋轉角度      const rotateY = -1 * ((clientY - y - rangeX) / rangeX) * maxYRotation; // 根據鼠標在 X 軸上的位置計算繞 Y 軸的旋轉角度      cardDom.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; //設置 3D 透視    }  };  // 監聽卡片鼠標移出  const onMouseLeave = () => {    // 鼠標離開移出光源    removeLight();    restoreCardOverflow();  };  useEffect(() => {    // 設置光源樣式    setLightStyle();    // 綁定事件    cardRef.current?.addEventListener('mouseenter', onMouseEnter);    cardRef.current?.addEventListener('mousemove', onMouseMove);    cardRef.current?.addEventListener('mouseleave', onMouseLeave);    return () => {        // 解綁事件        cardRef.current?.removeEventListener('mouseenter', onMouseEnter);        cardRef.current?.removeEventListener('mousemove', onMouseMove);        cardRef.current?.removeEventListener('mouseleave', onMouseLeave);    }  })  return {    cardRef,  };};// Index.tsximport './Index.less'import { useLightCard } from './use-light-card'const Index = () => {    const { cardRef: cardRef1 } = useLightCard()    const { cardRef: cardRef2 } = useLightCard({        light: {            color: '#ffffff',            width: 100        }    })    const { cardRef: cardRef3 } = useLightCard({        light: {            color: 'yellow'        }    })    return <div className='light-card-container'>        {/* 方塊盒子 */}        <div className='item' ref={cardRef1}></div>        {/* 方塊盒子 */}        <div className='item' ref={cardRef2}></div>        {/* 方塊盒子 */}        <div className='item' ref={cardRef3}></div>    </div>}export default Index// Index.less.light-card-container {    background: black;    width: 100%;    height: 100%;    padding: 200px;    display: flex;    justify-content: space-between;      .item {      position: relative;      width: 125px;      height: 125px;      background: #1c1c1f;      border: 1px solid rgba(255, 255, 255, 0.1);      // 不需要了      // .light {      //   width: 60px;      //   height: 60px;      //   background: #ff4132;      //   filter: blur(40px);      //   position: absolute;      // }    }}

結語

7br28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-92131-0.html使用 React Hooks 實現鼠標懸浮卡片發光的動畫效果

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 25個每個開發人員都應該知道的CSS 技巧

下一篇: C# 異常處理:每個 .NET 開發者都應掌握的核心知識點

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
国产精品欧美激情| 日韩一级欧洲| 国产毛片一区二区| 国产毛片一区二区| 激情欧美一区二区三区| 亚洲精品网站在线播放gif| 亚洲桃色在线一区| 久久精品在线观看| 欧美了一区在线观看| 国产精品99免费看 | 亚洲精品一区二区网址| 中文一区字幕| 久久久久久久国产| 欧美日韩精品免费看| 国产亚洲精品久久久久久| 最新国产成人在线观看| 亚洲桃色在线一区| 久久久久久一区二区三区| 欧美日韩ab片| 韩国成人精品a∨在线观看| 亚洲精品免费看| 销魂美女一区二区三区视频在线| 免费一级欧美在线大片| 国产精品videosex极品| 在线看片一区| 亚洲综合不卡| 欧美国产精品| 国产一区二区主播在线| 宅男噜噜噜66一区二区| 美日韩丰满少妇在线观看| 国产精品三级视频| 亚洲人成精品久久久久| 久久精品女人天堂| 国产精品久久久久毛片软件 | 国产亚洲网站| 在线一区日本视频| 麻豆精品在线视频| 国产日产欧美一区| 亚洲手机成人高清视频| 欧美电影免费观看| 狠狠色伊人亚洲综合成人| 欧美a一区二区| 国产亚洲一级| 亚洲性视频网站| 欧美激情第10页| 黄色一区三区| 性色一区二区三区| 欧美三级在线视频| 亚洲黑丝一区二区| 久久久国产精品一区二区三区| 国产精品vvv| 亚洲精品麻豆| 久久久国产精品一区二区中文| 国产精品久久久久久影视| 日韩午夜一区| 欧美韩日亚洲| 亚洲电影下载| 久久在线免费| 狠狠干成人综合网| 欧美一区二区在线| 国产精品一区一区三区| 亚洲自啪免费| 国产精品免费看| 亚洲一区二区三区精品在线| 欧美日韩大片一区二区三区| 亚洲激情影院| 欧美成人黑人xx视频免费观看| 韩国精品主播一区二区在线观看| 午夜日韩av| 国产精品一二三视频| 亚洲深夜福利视频| 欧美视频免费看| 一区二区三区www| 欧美精品久久一区| 亚洲国产一区二区三区a毛片| 久久三级福利| 在线看成人片| 欧美va天堂| 亚洲人线精品午夜| 欧美精品偷拍| 一区二区国产日产| 欧美视频在线播放| 亚洲尤物影院| 国产精品自拍在线| 欧美在线精品一区| 黄色成人片子| 免费观看不卡av| 亚洲精品国产欧美| 欧美日韩免费高清一区色橹橹| 在线一区欧美| 国产伦精品一区二区三区| 欧美中文字幕不卡| 伊人婷婷欧美激情| 欧美高清视频在线播放| 99精品欧美一区| 国产精品久在线观看| 欧美一区二区免费视频| 国产综合色产在线精品| 另类春色校园亚洲| 亚洲人线精品午夜| 欧美午夜片欧美片在线观看| 亚洲一区3d动漫同人无遮挡| 国产精品普通话对白| 欧美专区日韩专区| 一区二区在线看| 欧美国产国产综合| 亚洲午夜久久久| 国产日韩一区二区三区| 久久综合999| 亚洲激情一区二区| 国产精品成人在线观看| 欧美中在线观看| 亚洲国产精品专区久久| 欧美视频1区| 久久久久久999| 亚洲欧洲在线免费| 国产精品v欧美精品v日韩精品 | 国产精品色网| 久久网站免费| 夜夜狂射影院欧美极品| 国产农村妇女精品一二区| 久久综合中文色婷婷| 99在线|亚洲一区二区| 国产毛片一区| 美女性感视频久久久| 中日韩男男gay无套| 国产亚洲日本欧美韩国| 欧美喷水视频| 久久都是精品| 亚洲精品在线三区| 国产欧美日韩一区二区三区在线观看| 麻豆精品视频在线| 亚洲一区二区在线免费观看| 今天的高清视频免费播放成人 | 亚洲视频一区二区在线观看| 国产一区自拍视频| 欧美日韩国产首页| 久久久国产成人精品| 一区二区三区精品| 一区二区三区在线视频免费观看| 欧美日韩你懂的| 久久久久久999| 亚洲视频视频在线| 亚洲国产精品99久久久久久久久| 国产精品高潮粉嫩av| 巨乳诱惑日韩免费av| 亚洲欧美精品中文字幕在线| 亚洲国产老妈| 国产一区二区精品| 欧美性猛交视频| 欧美不卡高清| 久久精品99| 亚洲自拍偷拍色片视频| 亚洲另类视频| 一区精品在线播放| 国产精品欧美日韩久久| 欧美精品一区二| 久久日韩粉嫩一区二区三区| 亚洲在线国产日韩欧美| 亚洲精品久久久久久久久久久久久| 国产日本亚洲高清| 欧美亚洲成人网| 欧美精品久久久久久久免费观看 | 国产精品99久久99久久久二8| 亚洲高清在线精品| 国模吧视频一区| 国产精品免费网站在线观看| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲第一在线| 国产视频久久久久久久| 欧美性开放视频| 欧美美女bb生活片| 免费日本视频一区| 久久理论片午夜琪琪电影网| 午夜欧美不卡精品aaaaa| 亚洲一区二区三区国产| 一区二区黄色| 亚洲精品在线一区二区| 亚洲国产精品成人综合| 国内精品**久久毛片app| 国产女优一区| 国产精品视频观看| 欧美性猛交xxxx乱大交蜜桃| 欧美日韩国产首页| 欧美精品一区二区三区视频| 蜜臀久久99精品久久久久久9| 久久精品毛片| 久久激情婷婷| 久久精品国产96久久久香蕉| 欧美一区二区三区视频在线观看| 亚洲欧美日韩国产一区二区三区 | 亚洲一区免费网站| 亚洲午夜激情免费视频| 99国产一区| 野花国产精品入口| 一本色道久久综合狠狠躁篇怎么玩| 亚洲精品视频一区| 亚洲伦理一区| 日韩一二三区视频| 一本一道久久综合狠狠老精东影业| 99re66热这里只有精品4| 一本大道久久a久久精品综合| 一本色道**综合亚洲精品蜜桃冫| 99热在线精品观看|