鄭州專業(yè)網(wǎng)站設(shè)計(jì)商丘網(wǎng)絡(luò)推廣外包
前言
最近,我看到一個(gè)工程師的個(gè)人網(wǎng)站上,采用了拖拽作品集的互動特效,既有趣又吸引眼球。經(jīng)過一些研究,我發(fā)現(xiàn)其實(shí)借助一些現(xiàn)成的套件,就能輕松實(shí)現(xiàn)這樣的效果。今天就帶大家一起看看,如何通過 Framer Motion 來制作這個(gè)特效吧!
安裝 React + Framer Motion
我將使用 React 和 Framer Motion 來實(shí)現(xiàn)這個(gè)特效。首先,用 Vite 來快速搭建一個(gè) React 開發(fā)環(huán)境:
npm create vite@latest my-react-app -- --template react
執(zhí)行完成后就依序執(zhí)行以下指令,分別是:
cd my-react-app
?: 移動到?my-react-app
?資料夾npm install
?: 安裝相關(guān)依賴npm run dev
?: 執(zhí)行
cd my-react-app
npm install
npm run dev
打開瀏覽器,訪問 http://localhost:5173
,你應(yīng)該會看到一個(gè)基礎(chǔ)的 React 應(yīng)用如下圖。
并且也可以看到你的資料夾結(jié)構(gòu),如果只是想練習(xí)這個(gè)特效,直接改 App.jsx 就好
下一步就是安裝 Framer Motion,直接在終端機(jī)打上以下指令就好:
npm install framer-motion
引入圖片 & 創(chuàng)建容器
我們將圖片保存在 ./public/drag-img/
文件夾中,并用數(shù)組來存儲圖片路徑。通過 Array.map()
方法,我們可以輕松地渲染出所有的圖片。
const images = ['/drag-img/image-1.png','/drag-img/image-2.png','/drag-img/image-3.png','/drag-img/image-4.png','/drag-img/image-5.png','/drag-img/image-6.png','/drag-img/image-7.png','/drag-img/image-8.png','/drag-img/image-9.png','/drag-img/image-10.png','/drag-img/image-11.png','/drag-img/image-12.png','/drag-img/image-13.png','/drag-img/image-14.png',
];
然后,我們創(chuàng)建一個(gè)容器來存放這些圖片。為了方便后續(xù)操作,我們使用 useRef
來引用容器,以便后面獲取容器的寬高。
export default function DragImg() {const containerRef = useRef(null);return (<divref={containerRef}className='drag-img__container'>{/* 圖片渲染 */}</div>);
}
接下來,稍微修改一下style樣式
.drag-img__container {position: relative;width: 100vw;height: 100vh;overflow: hidden;background: #f0f0f0;
}
?
渲染圖片 & 隨機(jī)位置
通過剛才定義的 images
數(shù)組來渲染所有圖片。這里使用的是 motion.img
標(biāo)簽,這樣才能使用 Framer Motion 提供的動畫和交互功能。
export default function DragImg() {const containerRef = useRef(null);return (<divref={containerRef}className='drag-img__container'>{images.map((src, index) => (<motion.imgkey={index}src={src}className='drag-img__img'alt={`Image ${index + 1}`}/>))}</div>);
}
.drag-img__img {width: 200px;aspect-ratio: 4/3;object-fit: contain;padding: 4px;position: absolute;background: rgba(255, 255, 255, 0.2);border-radius: 6px;box-shadow: 0 0 2px rgba(0, 0, 0, 0.1);cursor: grab;
}
?稍微調(diào)整圖片的寬度、比例,并讓他的 position 是 absolute,其他就是一些小裝飾,例如 padding、shadow 等等,現(xiàn)在所有的圖片都會在右上角,因?yàn)槲覀冞€沒調(diào)整他們的位置
接著可以利用 JavaScript 來隨機(jī)圖片的位置,順便隨機(jī)旋轉(zhuǎn)的角度,讓他有種散落在整個(gè) container 的感覺。?
{images.map((src, index) => (<motion.imgkey={index}src={src}className='drag-img__img'alt={`Image ${index + 1}`}style={{top: `${Math.random() * (window.innerHeight - 200)}px`,left: `${Math.random() * (window.innerWidth - 150)}px`,rotate: `${Math.random() * 40 - 20}deg`,}}/>
))}
實(shí)現(xiàn)拖拽效果
接下來,重點(diǎn)來了——使用 Framer Motion 來實(shí)現(xiàn)拖拽效果。由于 Framer Motion 內(nèi)置了 drag
屬性,整個(gè)過程非常簡單,只需要在 motion.img
上添加 drag
屬性,并指定拖拽范圍。
{images.map((src, index) => (<motion.imgkey={index}src={src}className="drag-img__img"alt={`Image ${index + 1}`}style={{top: `${Math.random() * (window.innerHeight - 200)}px`,left: `${Math.random() * (window.innerWidth - 150)}px`,rotate: `${Math.random() * 40 - 20}deg`,}}dragdragConstraints={containerRef} // 限制拖拽范圍whileDrag={{ scale: 1.1, rotate: 0 }} // 拖拽時(shí)的樣式調(diào)整/>
))}
這里,我們添加了 dragConstraints
,使圖片只能在容器內(nèi)拖動,不會超出邊界。同時(shí),使用 whileDrag
來調(diào)整拖拽時(shí)圖片的縮放和旋轉(zhuǎn)效果。
完整代碼示例
到此為止就完全搞定了,其實(shí)非常簡單!以下附上全部的代碼:?
import { useRef } from 'react';
import { motion } from 'framer-motion';const images = ['/drag-img/image-1.png','/drag-img/image-2.png','/drag-img/image-3.png','/drag-img/image-4.png','/drag-img/image-5.png','/drag-img/image-6.png','/drag-img/image-7.png','/drag-img/image-8.png','/drag-img/image-9.png','/drag-img/image-10.png','/drag-img/image-11.png','/drag-img/image-12.png','/drag-img/image-13.png','/drag-img/image-14.png',
];export default function DragImg() {const containerRef = useRef(null);return (<divref={containerRef}className='drag-img__container'>{images.map((src, index) => (<motion.imgkey={index}src={src}className='drag-img__img'alt={`Image ${index + 1}`}style={{top: `${Math.random() * (window.innerHeight - 200)}px`,left: `${Math.random() * (window.innerWidth - 150)}px`,rotate: `${Math.random() * 40 - 20}deg`,}}dragdragConstraints={containerRef}whileDrag={{ scale: 1.1, rotate: 0 }}/>))}</div>);
}
.drag-img__container {position: relative;width: 100vw;height: 100vh;overflow: hidden;background: #f0f0f0;
}.drag-img__img {width: 200px;aspect-ratio: 4/3;object-fit: contain;padding: 4px;position: absolute;background: rgba(255, 255, 255, 0.2);border-radius: 6px;box-shadow: 0 0 2px rgba(0, 0, 0, 0.1);cursor: grab;
}
?通過以上步驟就成功創(chuàng)建了一個(gè)可以拖拽的圖片展示特效。操作非常簡單,而且效果十分酷炫!快來試試看吧!