当前位置: 首页 > news >正文

拖拽实现3

import React, { useState, useRef, useEffect } from ‘react’;
import ‘./ImageList.css’;

const ImageList = () => {
const images = [
‘https://picsum.photos/300/200?random=1’,
‘https://picsum.photos/300/200?random=2’,
‘https://picsum.photos/300/200?random=3’,
‘https://picsum.photos/300/200?random=4’,
‘https://picsum.photos/300/200?random=5’,
‘https://picsum.photos/300/200?random=6’,
];

const listRef = useRef(null);
const [isDragging, setIsDragging] = useState(false);
const [startX, setStartX] = useState(0);
const [translateX, setTranslateX] = useState(0);
const [lastTranslateX, setLastTranslateX] = useState(0);
const [isBouncing, setIsBouncing] = useState(false);

// 获取边界值
const getBoundaries = () => {
if (!listRef.current) return { minTranslate: 0, maxTranslate: 0 };
const maxTranslate = 0;
const minTranslate = -(listRef.current.scrollWidth - listRef.current.parentElement.offsetWidth);
return { minTranslate, maxTranslate };
};

// 处理开始拖动
const handleStart = (clientX) => {
setIsDragging(true);
setStartX(clientX - lastTranslateX);
setIsBouncing(false); // 取消回弹状态
};

// 处理拖动移动
const handleMove = (clientX) => {
if (!isDragging) return;
const newTranslateX = clientX - startX;
const { minTranslate, maxTranslate } = getBoundaries();

// 允许稍微越界以模拟拉伸效果
if (newTranslateX > maxTranslate) {
  // 右边界,添加阻力效果
  const overflow = newTranslateX - maxTranslate;
  setTranslateX(maxTranslate + overflow * 0.3); // 0.3为阻力系数
} else if (newTranslateX < minTranslate) {
  // 左边界,添加阻力效果
  const overflow = newTranslateX - minTranslate;
  setTranslateX(minTranslate + overflow * 0.3);
} else {
  setTranslateX(newTranslateX);
}

};

// 处理拖动结束
const handleEnd = () => {
setIsDragging(false);
const { minTranslate, maxTranslate } = getBoundaries();

// 检查是否越界并触发回弹
if (translateX > maxTranslate) {
  setIsBouncing(true);
  setTranslateX(maxTranslate);
  setLastTranslateX(maxTranslate);
} else if (translateX < minTranslate) {
  setIsBouncing(true);
  setTranslateX(minTranslate);
  setLastTranslateX(minTranslate);
} else {
  setLastTranslateX(translateX);
}

};

// 鼠标事件
const handleMouseDown = (e) => handleStart(e.clientX);
const handleMouseMove = (e) => handleMove(e.clientX);
const handleMouseUp = () => handleEnd();

// 触摸事件
const handleTouchStart = (e) => handleStart(e.touches[0].clientX);
const handleTouchMove = (e) => handleMove(e.touches[0].clientX);
const handleTouchEnd = () => handleEnd();

// 添加和清理事件监听器
useEffect(() => {
const ref = listRef.current;
ref.addEventListener(‘mousedown’, handleMouseDown);
ref.addEventListener(‘touchstart’, handleTouchStart);
window.addEventListener(‘mousemove’, handleMouseMove);
window.addEventListener(‘touchmove’, handleTouchMove);
window.addEventListener(‘mouseup’, handleMouseUp);
window.addEventListener(‘touchend’, handleTouchEnd);

return () => {
  ref.removeEventListener('mousedown', handleMouseDown);
  ref.removeEventListener('touchstart', handleTouchStart);
  window.removeEventListener('mousemove', handleMouseMove);
  window.removeEventListener('touchmove', handleTouchMove);
  window.removeEventListener('mouseup', handleMouseUp);
  window.removeEventListener('touchend', handleTouchEnd);
};

}, [isDragging, startX, translateX]);

return (


<div
ref={listRef}
className={ image-list ${isDragging ? 'dragging' : ''} ${isBouncing ? 'bouncing' : ''}}
style={{ transform: translateX(${translateX}px) }}
>
{images.map((src, index) => (

<img src={src} alt={ Image ${index + 1}} />

))}


);
};

export default ImageList;

相关文章:

  • Docker 安装redis
  • Docker--利用dockerfile搭建mysql主从集群和redis集群
  • 在MATLAB中使用MPI进行并行编程
  • 特殊定制版,太给力了!
  • MySQL进阶-存储引擎索引
  • 设计模式 Day 9:命令模式(Command Pattern)完整讲解与实战应用
  • MaxPooling层的作用(通俗解释)
  • PyTorch 深度学习实战(36):混合精度训练与梯度缩放
  • python爬取歌曲宝周排行音乐
  • Docker 镜像 的常用命令介绍
  • TCP 如何在网络 “江湖” 立威建交?
  • 【家政平台开发(38)】解锁家政平台国际化密码:多语言支持开发实战
  • 基于AOP+Log4Net+AutoFac日志框架
  • 【AI提示词】金融信息抽取工程师工作流程
  • Python itertools模块的combinations函数介绍
  • 青少年编程考试 CCF GESP图形化编程 二级认证真题 2025年3月
  • 在Altium Designer中,为啥要设置100mil格点防止引脚
  • 【系统分析师---考试题型总结】
  • 移除元素.
  • 【包管理器】主流包管理器_对比_应用场景
  • 三门峡建设环境局网站/账号seo是什么
  • 自我介绍ppt模板免费下载/seo的收费标准
  • 坂田做网站/网站seo推广多少钱
  • 网站优化seo是什么/网站设计制作公司
  • wordpress页眉自定义/seo搜索引擎优化课程总结
  • 金融网站织梦模板免费下载/百度官方网首页