{"id":18563617,"url":"https://github.com/younth/react-swipes","last_synced_at":"2025-04-09T16:15:08.256Z","repository":{"id":57346122,"uuid":"72934506","full_name":"younth/react-swipes","owner":"younth","description":":fire: 基于React的移动端卡片滑动组件","archived":false,"fork":false,"pushed_at":"2018-04-13T12:36:52.000Z","size":5086,"stargazers_count":185,"open_issues_count":22,"forks_count":39,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-09T16:15:02.651Z","etag":null,"topics":["react","react-swipes","slider","swipe","swiper"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/younth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-05T15:22:47.000Z","updated_at":"2024-02-23T19:35:02.000Z","dependencies_parsed_at":"2022-09-17T23:12:37.190Z","dependency_job_id":null,"html_url":"https://github.com/younth/react-swipes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younth%2Freact-swipes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younth%2Freact-swipes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younth%2Freact-swipes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younth%2Freact-swipes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/younth","download_url":"https://codeload.github.com/younth/react-swipes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248065282,"owners_count":21041872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","react-swipes","slider","swipe","swiper"],"created_at":"2024-11-06T22:13:02.939Z","updated_at":"2025-04-09T16:15:08.236Z","avatar_url":"https://github.com/younth.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## react-swipes \n\n\u003e 打造最好用的React 移动端卡片滑动 组件。已支持卡片自动播放，配置加入 `autoPlay` 参数即可。\n\n### 为什么要造轮子\n\n目前react component里面 基于移动端轮播/幻灯片 组件，最熟悉应该是`react-swipe`这个库了。且看这个组件的构成：\n\n- react-swipe: 引入swipe-js-iso,创建react组件\n- swipe-js-iso: 基于swipe.js的一个Pull Request\n\n\n也就是说，整个组件是基于几年前的swipe.js的，这个库三四年没更新了，看提问，作者在12年说要发个swipe2，结果不了了之，导致bug修复很慢，功能支持不全。比如我想做这个效果：\n\n![vip](./static/vip.gif)\n\n![newuser](./static/newuser.gif)\n\n\n---\n\n尴尬啊，`react-swipe`现在的能力根本支持不了(因为swipe是针对**焦点图**设计的，写死了子元素宽度是父级的宽度)\n\n\n### 解决方案\n\n不用react的情况下，swiper.js 是个不错的选择，但是考虑这个库太大了(5000行+)，为一个卡片滑动实在不值得。最后还是自己搞了个react-swipes，为的就是快速方便的实现上面这种卡片切换效果。\n\n### 安装\n\n    npm i react-swipes --save\n\n### 使用\n\n#### 原理\n\nswipes不依赖任何css，不会去改变子item的样式，也就是说，css完全控制在自己的代码中。所以有必要了解卡片滑动的原理：\n\n\n```html\n// 三层滑动原理，动的是第二层\n\n// 第一层设置固定宽度 ，超过部分设置为不显示 overflow: hidden;  \n\u003cdiv\u003e  \n    //第二层设置为实际需要的宽度，即子div的n倍，有间距需要算上间距\n    \u003cdiv\u003e  \n        //第三层，实际item 内容的宽度     \n        \u003cdiv\u003e\u003c/div\u003e  \n    \u003c/div\u003e  \n\u003c/div\u003e\n```\n\n这是滑动的基础布局，最终的滑动也就是改变第二层div的`translateX`值。再加上`transition` 过渡效果，即可实现整个区域的运动，而最外层元素设置了溢出隐藏，这样整体效果就是单张卡片在运动了。\n\n#### 具体使用\n\n```js\n    import ReactSwipe from 'react-swipes'\n    \n    // swipes 的配置\n    let opt = {\n    distance: 620, // 每次移动的距离，卡片的真实宽度\n    currentPoint: 1,// 初始位置，默认从0即第一个元素开始\n    autoPlay: true, // 是否开启自动播放\n    swTouchstart: (ev) =\u003e {\n\n    },\n    swTouchmove: (ev) =\u003e {\n\n    },\n    swTouchend: (ev) =\u003e {\n        let data = {\n            moved: ev.moved,\n            originalPoint: ev.originalPoint,\n            newPoint: ev.newPoint,\n            cancelled: ev.cancelled\n        }\n        console.log(data);\n        this.setState({\n            curCard: ev.newPoint\n        })\n    }\n    }\n    \n    // dom 部分\n    // 第一层div\n    \u003cdiv className=\"card-swipe\" \u003e\n        // 第二层div  react-swipes生成一个className为 card-slide的div\n        \u003cReactSwipe className=\"card-slide\" options={opt}\u003e\n            // 第三层，即本身的item\n            this.state.card.length \u0026\u0026 this.state.card.map((item, index) =\u003e \u003cdiv className=\"item\" key={index}\u003e \u003c/div\u003e\n        \u003c/ReactSwipe\u003e\n    \u003c/div\u003e\n```\n\n### demo\n    \n[sandbox demo](https://codesandbox.io/s/6xx1v0xo2z)\n\n### todo\n\n- 现在把css完全暴露给使用者了，这样第二层div的宽度（第三层元素的宽度和）需要大家在代码中计算，不是很方便，后续会把这块逻辑放到组件里面去，开发者只需要配置卡片基础属性即可。\n- 卡片滑动过程想实现类似上面的缩放效果，目前需要在 `swTouchmove` `swTouchend` 钩子里面自己去实现，后面会把这个效果做到组件里面去，开发者选择是否开启。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyounth%2Freact-swipes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyounth%2Freact-swipes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyounth%2Freact-swipes/lists"}