React实现拖拽殊效

打印 上一主题 下一主题

主题 1033|帖子 1033|积分 3099

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
媒介

最近,我看到一个工程师的个人网站上,接纳了拖拽作品集的互动殊效,既风趣又吸引眼球。经过一些研究,我发现实在借助一些现成的套件,就能轻松实现这样的效果。本日就带各人一起看看,如何通过 Framer Motion 来制作这个殊效吧!
安装 React + Framer Motion

我将使用 ReactFramer Motion 来实现这个殊效。首先,用 Vite 来快速搭建一个 React 开发环境:
  1. npm create vite@latest my-react-app -- --template react
复制代码
实行完成后就依序实行以下指令,分别是:

  • cd my-react-app : 移动到 my-react-app 资料夹
  • npm install : 安装相关依赖
  • npm run dev : 实行
  1. cd my-react-app
  2. npm install
  3. npm run dev
复制代码
打开欣赏器,访问 http://localhost:5173,你应该会看到一个基础的 React 应用如下图。
并且也可以看到你的资料夹结构,假如只是想练习这个殊效,直接改 App.jsx 就好
下一步就是安装 Framer Motion,直接在终端机打上以下指令就好:
  1. npm install framer-motion
复制代码
引入图片 & 创建容器

我们将图片保存在 ./public/drag-img/ 文件夹中,并用数组来存储图片路径。通过 Array.map() 方法,我们可以轻松地渲染出所有的图片。
  1. const images = [
  2.   '/drag-img/image-1.png',
  3.   '/drag-img/image-2.png',
  4.   '/drag-img/image-3.png',
  5.   '/drag-img/image-4.png',
  6.   '/drag-img/image-5.png',
  7.   '/drag-img/image-6.png',
  8.   '/drag-img/image-7.png',
  9.   '/drag-img/image-8.png',
  10.   '/drag-img/image-9.png',
  11.   '/drag-img/image-10.png',
  12.   '/drag-img/image-11.png',
  13.   '/drag-img/image-12.png',
  14.   '/drag-img/image-13.png',
  15.   '/drag-img/image-14.png',
  16. ];
复制代码
然后,我们创建一个容器来存放这些图片。为了方便后续操纵,我们使用 useRef 来引用容器,以便背面获取容器的宽高。
  1. export default function DragImg() {
  2.   const containerRef = useRef(null);
  3.   return (
  4.     <div
  5.       ref={containerRef}
  6.       className='drag-img__container'
  7.     >
  8.        {/* 图片渲染 */}
  9.     </div>
  10.   );
  11. }
复制代码
接下来,稍微修改一下style样式
  1. .drag-img__container {
  2.   position: relative;
  3.   width: 100vw;
  4.   height: 100vh;
  5.   overflow: hidden;
  6.   background: #f0f0f0;
  7. }
复制代码
 

渲染图片 & 随机位置

通过刚才定义的 images 数组来渲染所有图片。这里使用的是 motion.img 标签,这样才能使用 Framer Motion 提供的动画和交互功能。
  1. export default function DragImg() {
  2.   const containerRef = useRef(null);
  3.   return (
  4.     <div
  5.       ref={containerRef}
  6.       className='drag-img__container'
  7.     >
  8.       {images.map((src, index) => (
  9.         <motion.img
  10.           key={index}
  11.           src={src}
  12.           className='drag-img__img'
  13.           alt={`Image ${index + 1}`}
  14.         />
  15.       ))}
  16.     </div>
  17.   );
  18. }
复制代码
  1. .drag-img__img {
  2.   width: 200px;
  3.   aspect-ratio: 4/3;
  4.   object-fit: contain;
  5.   padding: 4px;
  6.   position: absolute;
  7.   background: rgba(255, 255, 255, 0.2);
  8.   border-radius: 6px;
  9.   box-shadow: 0 0 2px rgba(0, 0, 0, 0.1);
  10.   cursor: grab;
  11. }
复制代码
 稍微调解图片的宽度、比例,并让他的 position 是 absolute,其他就是一些小装饰,比方 padding、shadow 等等,现在所有的图片都会在右上角,因为我们还没调解他们的位置

接著可以使用 JavaScript 来随机图片的位置,顺便随机旋转的角度,让他有种散落在整个 container 的感觉。 
  1. {images.map((src, index) => (
  2.   <motion.img
  3.     key={index}
  4.     src={src}
  5.     className='drag-img__img'
  6.     alt={`Image ${index + 1}`}
  7.     style={
  8.   
  9.   {
  10.       top: `${Math.random() * (window.innerHeight - 200)}px`,
  11.       left: `${Math.random() * (window.innerWidth - 150)}px`,
  12.       rotate: `${Math.random() * 40 - 20}deg`,
  13.     }}
  14.   />
  15. ))}
复制代码

实现拖拽效果

接下来,重点来了——使用 Framer Motion 来实现拖拽效果。由于 Framer Motion 内置了 drag 属性,整个过程非常简朴,只必要在 motion.img 上添加 drag 属性,并指定拖拽范围。
  1. {images.map((src, index) => (
  2.   <motion.img
  3.     key={index}
  4.     src={src}
  5.     className="drag-img__img"
  6.     alt={`Image ${index + 1}`}
  7.     style={
  8.   
  9.   {
  10.       top: `${Math.random() * (window.innerHeight - 200)}px`,
  11.       left: `${Math.random() * (window.innerWidth - 150)}px`,
  12.       rotate: `${Math.random() * 40 - 20}deg`,
  13.     }}
  14.     drag
  15.     dragConstraints={containerRef}  // 限制拖拽范围
  16.     whileDrag={
  17.   
  18.   { scale: 1.1, rotate: 0 }}  // 拖拽时的样式调整
  19.   />
  20. ))}
复制代码
这里,我们添加了 dragConstraints,使图片只能在容器内拖动,不会超出边界。同时,使用 whileDrag 来调解拖拽时图片的缩放和旋转效果。
完整代码示例

到此为止就完全搞定了,实在非常简朴!以下附上全部的代码: 
  1. import { useRef } from 'react';import { motion } from 'framer-motion';const images = [
  2.   '/drag-img/image-1.png',
  3.   '/drag-img/image-2.png',
  4.   '/drag-img/image-3.png',
  5.   '/drag-img/image-4.png',
  6.   '/drag-img/image-5.png',
  7.   '/drag-img/image-6.png',
  8.   '/drag-img/image-7.png',
  9.   '/drag-img/image-8.png',
  10.   '/drag-img/image-9.png',
  11.   '/drag-img/image-10.png',
  12.   '/drag-img/image-11.png',
  13.   '/drag-img/image-12.png',
  14.   '/drag-img/image-13.png',
  15.   '/drag-img/image-14.png',
  16. ];export default function DragImg() {  const containerRef = useRef(null);  return (    <div      ref={containerRef}      className='drag-img__container'    >      {images.map((src, index) => (        <motion.img          key={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`,          }}          drag          dragConstraints={containerRef}          whileDrag={    { scale: 1.1, rotate: 0 }}        />      ))}    </div>  );}
复制代码
  1. .drag-img__container {
  2.   position: relative;
  3.   width: 100vw;
  4.   height: 100vh;
  5.   overflow: hidden;
  6.   background: #f0f0f0;
  7. }.drag-img__img {
  8.   width: 200px;
  9.   aspect-ratio: 4/3;
  10.   object-fit: contain;
  11.   padding: 4px;
  12.   position: absolute;
  13.   background: rgba(255, 255, 255, 0.2);
  14.   border-radius: 6px;
  15.   box-shadow: 0 0 2px rgba(0, 0, 0, 0.1);
  16.   cursor: grab;
  17. }
复制代码
 通过以上步调就成功创建了一个可以拖拽的图片展示殊效。操纵非常简朴,而且效果非常酷炫!快来试试看吧!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大号在练葵花宝典

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表