UNPKG

element-react-codish

Version:
150 lines (126 loc) 3.96 kB
/* @flow */ import React from 'react'; import ReactDOM from 'react-dom'; import { Component, PropTypes, View } from '../../libs'; type State = { hover: boolean, translate: number, scale: number, active: boolean, ready: boolean, inStage: boolean }; export default class CarouselItem extends Component { state: State; constructor(props: Object) { super(props); this.state = { hover: false, translate: 0, scale: 1, active: false, ready: false, inStage: false }; } componentWillMount(): void { this.parent().addItem(this); } componentWillUnmount(): void { this.parent().removeItem(this); } get isFlat(): boolean { return this.parent().props.type === 'flatcard'; } get CARD_SCALE(): number { return this.isFlat ? 1 : 0.83; } get calculateWidth(): ?string { if (this.isFlat) { return parseInt(100 / 3) + '%'; } } processIndex(index: number, activeIndex: number, length: number): number { if (activeIndex === 0 && index === length - 1) { return -1; } else if (activeIndex === length - 1 && index === 0) { return length; } else if (index < activeIndex - 1 && activeIndex - index >= length / 2) { return length + 1; } else if (index > activeIndex + 1 && index - activeIndex >= length / 2) { return -2; } return index; } calculateTranslate(index: number, activeIndex: number, parentWidth: number): number { const denominator = this.isFlat ? 3 : 4; if (this.state.inStage) { return parentWidth * ((2 - this.CARD_SCALE) * (index - activeIndex) + 1) / denominator; } else if (index < activeIndex) { return -(1 + this.CARD_SCALE) * parentWidth / denominator; } else { return (denominator - 1 + this.CARD_SCALE) * parentWidth / denominator; } } translateItem(index: number, activeIndex: number) { const parent: any = ReactDOM.findDOMNode(this.parent()); const parentWidth = parent.offsetWidth; const length = this.parent().state.items.length; if (index !== activeIndex && length > 2) { index = this.processIndex(index, activeIndex, length); } if (this.parent().iscard) { this.state.inStage = Math.round(Math.abs(index - activeIndex)) <= 1; this.state.active = index === activeIndex; this.state.translate = this.calculateTranslate(index, activeIndex, parentWidth); this.state.scale = this.state.active ? 1 : this.CARD_SCALE; } else { this.state.active = index === activeIndex; this.state.translate = parentWidth * (index - activeIndex); } this.state.ready = true; this.forceUpdate(); } handleItemClick() { if (this.parent().iscard) { const index = this.parent().state.items.indexOf(this); this.parent().setActiveItem(index); } } parent(): Object { return this.context.component; } render() { const { hover, translate, scale, active, ready, inStage } = this.state; return ( <View show={ready}> <div className={this.className('el-carousel__item', { 'is-active': active, 'el-carousel__item--card': this.parent().iscard, 'is-in-stage': inStage, 'is-hover': hover })} onClick={this.handleItemClick.bind(this)} style={{ msTransform: `translateX(${ translate }px) scale(${ scale })`, WebkitTransform: `translateX(${ translate }px) scale(${ scale })`, transform: `translateX(${ translate }px) scale(${ scale })`, width: this.calculateWidth }}> { this.parent().iscard && ( <View show={!active}> <div className="el-carousel__mask" /> </View> ) } {this.props.children} </div> </View> ) } } CarouselItem.contextTypes = { component: PropTypes.any };