import React from 'react';
import PropTypes from 'prop-types'; import {getSwipeWay} from '../utils/swipe'; //imgs : 图片src数组
//playTime : 轮播下一张图片的时间间隔
//notAuto : 是否开启自动轮播 默认开启 false const PropsChecker = {
imgs : PropTypes.array.isRequired,
playTime : PropTypes.number,
notAuto : PropTypes.bool,
}; class Carousel extends React.Component {
static defaultProps = {
playTime : 5000,
notAuto : false,
} constructor(args){
super(args);
this.state = {
};
//缓存各个currIndex的ul之后的标签
this.storeElements = {};
//判断滑动手势
this.swipeWay = getSwipeWay(50);//闸值50
//图片显示的限制
this.limit = 3;
//当前展示的图片
this.currIndex = 0;
//展示的数组
this.showImgs = [];
//手势滑动坐标
this.position = {
x1:0,
x2:0,
y1:0,
y2:0,
};
//<ul>
this.Ul = null;
//禁止在transiton的期间操作
this.isTransition = false;
//定时器
this.timer = 0;
} componentDidMount(){
this.autoPlay();
} componentWillUnmount(){
clearTimeout(this.timer);
} getHead(arr){
if(Array.isArray(arr)){
return arr[0];
}
console.error('非数组');
} getLast(arr){
if(Array.isArray(arr)){
const len = arr.length;
return arr[len-1];
}
console.error('非数组');
} calcIndex(){
const {imgs} = this.props;
const len = imgs.length;
const limit = this.limit;
const currIndex = this.currIndex; if(currIndex == 0){
this.showImgs = imgs.slice(0,limit - 1);
this.showImgs.unshift(this.getLast(imgs));
return;
} if(currIndex == len - 1){
this.showImgs = imgs.slice(len -2 ,len);
this.showImgs.push(this.getHead(imgs));
return;
} this.showImgs = imgs.slice(currIndex -1 , currIndex + limit -1); } changeCurrIndex(flag){
const {imgs} = this.props;
const last = imgs.length -1;
const currIndex = this.currIndex;
if(flag === '-'){
this.currIndex = currIndex == 0 ? last : currIndex -1 ;
return;
} if(flag === '+'){
this.currIndex = currIndex == last ? 0 : currIndex + 1 ;
return;
}
} ulTranslate(value){
const Ul = this.Ul;
if(Ul){ if(Ul.style.webkitTranslate ){
Ul.style.webkitTranslate = value;
}else{
Ul.style.translate = value;
} } } createUl(){
const currIndex = this.currIndex;
const storeElements = this.storeElements; //缓存这些标签,避免多次创建,很有必要
if(!storeElements[currIndex]){
//要保证<ul>key不同 也就是每次轮播后都要是新的标签,有损性能
const Ul = (<ul onTouchEnd={this.touchEnd}
onTouchMove={this.touchMove}
onTouchStart={this.touchStart}
onTransitionEnd={this.transitionEnd} ref={(ele)=>this.Ul=ele} key={currIndex}> {this.createLis()}
</ul>); storeElements[currIndex] = Ul;
} return storeElements[currIndex];
} createLis(){
this.calcIndex();
const imgs = this.showImgs; return imgs.map((src,i)=>{
const liStyle = {
// translate:(-i)+'00%',
translate:( (i+'00') - 100 ) + '%',
WebkitTranslate:( (i+'00') - 100 ) + '%',
}; return <li className='item' key={i} style={liStyle} ><img src={src} /></li>;
}); } touchStart = (e) => {
if(this.isTransition){
return;
} clearTimeout(this.timer); const {clientX,clientY} = e.touches[0];
this.position.x1 = clientX;
this.position.y1 = clientY;
} touchMove = (e) => { } touchEnd = (e) => {
if(this.isTransition){
return;
} const {clientX,clientY} = e.changedTouches[0];
this.position.x2 = clientX;
this.position.y2 = clientY; const {x1,x2,y1,y2} = this.position; const direction = this.swipeWay(x1,x2,y1,y2); if( direction === 'Left'){
this.changeCurrIndex('+');
this.isTransition = true;
this.ulTranslate('-100%');
} if(direction === 'Right'){
this.changeCurrIndex('-');
this.isTransition = true;
this.ulTranslate('100%');
}
} next(){
this.changeCurrIndex('+');
this.isTransition = true;
this.ulTranslate('-100%');
} autoPlay(){
const {playTime,notAuto} = this.props;
if(!notAuto){
this.timer = setTimeout(()=>{
this.next();
},playTime);
}
} transitionEnd = (e) => {
this.forceUpdate(()=>{
this.isTransition = false;
this.autoPlay();
});
} render(){ return (<div className='mm-carousel' >
{this.createUl()}
</div>);
}
} export default Carousel; Carousel.propTypes = PropsChecker;

最新文章

  1. 打开gvim发现菜单栏是乱码
  2. HTML5 十大新特性(六)——地理定位
  3. 7张图片学习VIM教程
  4. 单例模式(Singleton)的6种实现
  5. swfobject.js IE兼容问题
  6. Protocol buffer序列化及其在微信蓝牙协议中的应用
  7. python3-day3(函数-参数)
  8. 阿里巴巴2018届应届生在线编程测验-研发工程师C/C++
  9. Sublime text 3搭建Python开发环境
  10. 【Python 05】Python开发环境搭建
  11. d3里的比例尺
  12. liunx 部署 spring boot
  13. SAP中的ALE, IDOC
  14. docker pure-ftpd
  15. CM+CDH大数据平台
  16. MySQL的binlog操作
  17. Instantclient安装
  18. 41:和为S的两个数
  19. 利用JQuery直接调用asp.net后台的简单方法
  20. Unity判断鼠标是否在UI(UGUI)上

热门文章

  1. 蓝桥杯T42(八数码问题)
  2. 51Nod 1043 幸运号码
  3. 简单的Javascript图片延迟加载库Echo.js
  4. HDU4035(概率期望、树形、数学)
  5. hdu6315( 2018 Multi-University Training Contest 2)
  6. Metasploits之Adobe阅读器漏洞
  7. vs2013缺少Mvc 怎么办?
  8. 随机不重复的取数组元素,并赋值给div使用
  9. 前端经典面试题 不经典不要star!
  10. CSS布局之-高度自适应