UNPKG

jimu-mobile

Version:

积木组件库助力移动端开发

295 lines (265 loc) 7.89 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import Swipe from '../swipe/index'; const { Swipeable } = Swipe; class Focus extends Component { static propTypes = { index: PropTypes.number, duration: PropTypes.number, width: PropTypes.string, direction: PropTypes.string, loop: PropTypes.bool, auto: PropTypes.bool, } static defaultProps = { index: 0, width: '375px', timer: null, loop: true, // 循环 direction: 'left', duration: 200, auto: true, spotShow: false, // 是否显示指示点 back () { }, degree: 0, } constructor(props) { super(props); const { index, children, loop, } = this.props; this.state = { index: index > children.length - 1 ? children.length - 1 : index, len: children.length, // loop : timer ? true : loop loop, }; this.touching = this.touching.bind(this); this.touchLeft = this.touchLeft.bind(this); this.touchRight = this.touchRight.bind(this); this.touchEd = this.touchEd.bind(this); } componentDidMount () { const { index, width, children, loop, timer, } = this.props; const itemsWidthNumber = Number(width.split('px')[0]); // setloop = timer ? true : loop; this.setState({ itemsWidthNumber, translateX: loop ? itemsWidthNumber * children.length : 0, }, () => { this.setStyleInit(); }) } componentWillUnmount () { this.mytimer && clearInterval(this.mytimer); } componentWillReceiveProps (nextprops) { const { index } = nextprops; if (index != this.state.index) { this.setState({ index, }); this.move(index); } } setStyleInit () { const { focusContent } = this; const { index, itemsWidthNumber, len, loop, translateX, } = this.state; if (len > 1) { if (loop) { focusContent.style.width = `${(itemsWidthNumber * len) * 3}px`; focusContent.style.left = `${(-itemsWidthNumber * index) - translateX}px`; } else { focusContent.style.width = `${itemsWidthNumber * len}px`; focusContent.style.left = `${-itemsWidthNumber * index}px`; } this.autoMove(); } } touchRight (e, poaX) { document.body.style.overflow = 'hidden' const { focusContent } = this, { index, itemsWidthNumber, translateX, loop, } = this.state; focusContent.style.WebkitTransition = 'none'; if (index === 0) { if (loop) { focusContent.style.left = `${poaX - translateX}px`; } else { focusContent.style.left = `${poaX / 5}px`; } return false; } focusContent.style.left = `${-((itemsWidthNumber * index) - poaX) - translateX}px`; return true; } touchLeft (e, poaX) { document.body.style.overflow = 'hidden' const { focusContent } = this, { index, itemsWidthNumber, len, loop, translateX, } = this.state; focusContent.style.WebkitTransition = 'none'; if (index === len - 1) { if (loop) { focusContent.style.left = `${-((itemsWidthNumber * index) + poaX) - translateX}px`; } else { focusContent.style.left = `${-((itemsWidthNumber * index) + (poaX / 5))}px`; } } else { focusContent.style.left = `${-((itemsWidthNumber * index) + poaX) - translateX}px`; } } touching () { // 阻止window窗体滚动 /* */ // document.body.style.overflow = 'hidden' const { timer } = this.props; if (timer) { clearInterval(this.mytimer); } } touchEd (e, poaX) { const { index, len, loop, } = this.state; const { degree } = this.props; if (poaX < 0) { if (poaX < -degree) { if (!loop && index === 0) { this.move(index); } else { this.move(index - 1); } } else { this.move(index); } } if (poaX > 0) { if (poaX > degree) { if (!loop && index === len - 1) { this.move(index); } else { this.move(index + 1); } } else { this.move(index); } } document.body.style.overflow = 'auto' this.autoMove(); } autoMove () { const self = this, { direction, timer, auto } = this.props; let dir = 1; if (direction !== 'left') { dir = -1; } if (auto) { clearInterval(self.mytimer); self.mytimer = setInterval(() => { const autoindex = self.state.index + dir; self.move(autoindex); }, timer); } } move (index) { const { itemsWidthNumber, translateX, len, loop, } = this.state, { duration, back } = this.props, { focusContent } = this; let stateIndex = index; focusContent.style.WebkitTransition = `all ${duration / 1000}s ease-in`; if (loop) { focusContent.style.left = `${(-itemsWidthNumber * index) - translateX}px`; if (index < 0) { stateIndex = len - 1; setTimeout(() => { focusContent.style.WebkitTransition = 'none'; focusContent.style.left = `${(-itemsWidthNumber * stateIndex) - translateX}px`; }, duration); } if (index >= len) { stateIndex = 0; setTimeout(() => { focusContent.style.WebkitTransition = 'none'; focusContent.style.left = `${(-itemsWidthNumber * stateIndex) - translateX}px`; }, duration); } } else { if (index < 0) { stateIndex = len - 1; } if (index >= len) { stateIndex = 0; } focusContent.style.left = `${-itemsWidthNumber * stateIndex}px`; } back && back(stateIndex); this.setState({ index: stateIndex, }); } render () { const { className, children, width, spotShow, } = this.props, { index, loop } = this.state; const cls = classNames({ 'jimu-focus-layout': true, [className]: className, }); return ( <div className={cls} style={{ width }}> {children.length > 1 ? ( <Swipeable onSwiping={this.touching} onSwipingLeft={this.touchLeft} onSwipingRight={this.touchRight} onSwiped={this.touchEd} > {loop ? ( <div className="jimu-focus-content" ref={(t) => { this.focusContent = t; }}> {children.map((re, i) => (<div className="jimu-focus-items" style={{ width }} key={i}>{re}</div>))} {children.map((re, i) => (<div className="jimu-focus-items" style={{ width }} key={i}>{re}</div>))} {children.map((re, i) => (<div className="jimu-focus-items" style={{ width }} key={i}>{re}</div>))} </div> ) : ( <div className="jimu-focus-content" ref={(t) => { this.focusContent = t; }}> {children.map((re, i) => (<div className="jimu-focus-items" style={{ width }} key={i}>{re}</div>))} </div> )} <div className="jimu-focus-ft"> {spotShow && children.map((re, i) => { if (i === index) { return (<span className="jimu-focus-ftitems jimu-focus-current" key={i} />); } return (<span className="jimu-focus-ftitems" key={i} />); })} </div> </Swipeable> ) : ( <div className="jimu-focus-content" ref={(t) => { this.focusContent = t; }}> <div className="jimu-focus-items" style={{ width }}> {children} </div> </div> )} </div> ); } } module.exports = Focus;