react-mapfilter
Version:
A React Component for viewing and filtering GeoJSON
510 lines (435 loc) • 15.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _objectAssign = require('object-assign');
var _objectAssign2 = _interopRequireDefault(_objectAssign);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var styles = {
wrapper: {
width: '100%',
height: '100%',
overflow: 'hidden',
position: 'relative'
},
frame: {
top: 0,
width: '100%',
height: '100%',
position: 'absolute'
}
};
var wrapper = void 0;
var frames = {};
var Carousel = function (_React$Component) {
(0, _inherits3.default)(Carousel, _React$Component);
function Carousel(props) {
(0, _classCallCheck3.default)(this, Carousel);
var _this = (0, _possibleConstructorReturn3.default)(this, (Carousel.__proto__ || (0, _getPrototypeOf2.default)(Carousel)).call(this, props));
_this.state = {
current: 0
};
_this.mounted = false;
_this.onTouchStart = _this.onTouchStart.bind(_this);
_this.onTouchMove = _this.onTouchMove.bind(_this);
_this.onTouchEnd = _this.onTouchEnd.bind(_this);
_this.autoSlide = _this.autoSlide.bind(_this);
_this.prev = _this.prev.bind(_this);
_this.next = _this.next.bind(_this);
if (props.loop === false && props.auto) {
console.warn('[re-carousel] Auto-slide only works in loop mode.');
}
return _this;
}
(0, _createClass3.default)(Carousel, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.mounted = true;
this.prepareAutoSlide();
var childCount = _react.Children.count(this.props.children);
// Hide all frames
for (var i = 1; i < childCount; i++) {
frames['f' + i].style.opacity = 0;
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.mounted = false;
this.clearAutoTimeout();
}
}, {
key: 'onTouchStart',
value: function onTouchStart(e) {
var childCount = _react.Children.count(this.props.children);
if (childCount < 2) return;
this.clearAutoTimeout();
this.updateFrameSize();
this.prepareSiblingFrames();
var _ref = e.touches && e.touches[0] || e,
pageX = _ref.pageX,
pageY = _ref.pageY;
this.setState({
startX: pageX,
startY: pageY,
deltaX: 0,
deltaY: 0
});
wrapper.addEventListener('touchmove', this.onTouchMove, { passive: true });
wrapper.addEventListener('mousemove', this.onTouchMove, { passive: true });
wrapper.addEventListener('touchend', this.onTouchEnd, true);
wrapper.addEventListener('mouseup', this.onTouchEnd, true);
}
}, {
key: 'onTouchMove',
value: function onTouchMove(e) {
if (e.touches && e.touches.length > 1) return;
this.clearAutoTimeout();
var _ref2 = e.touches && e.touches[0] || e,
pageX = _ref2.pageX,
pageY = _ref2.pageY;
var deltaX = pageX - this.state.startX;
var deltaY = pageY - this.state.startY;
this.setState({
deltaX: deltaX,
deltaY: deltaY
});
var childCount = _react.Children.count(this.props.children);
// when reach frames edge in non-loop mode, reduce drag effect.
if (!this.props.loop) {
if (this.state.current === childCount - 1) {
deltaX < 0 && (deltaX /= 3);
deltaY < 0 && (deltaY /= 3);
}
if (this.state.current === 0) {
deltaX > 0 && (deltaX /= 3);
deltaY > 0 && (deltaY /= 3);
}
}
this.moveFramesBy(deltaX, deltaY);
}
}, {
key: 'onTouchEnd',
value: function onTouchEnd() {
var _this2 = this;
var direction = this.decideEndPosition();
direction && this.transitFramesTowards(direction);
// cleanup
wrapper.removeEventListener('touchmove', this.onTouchMove);
wrapper.removeEventListener('mousemove', this.onTouchMove);
wrapper.removeEventListener('touchend', this.onTouchEnd, true);
wrapper.removeEventListener('mouseup', this.onTouchEnd, true);
setTimeout(function () {
return _this2.prepareAutoSlide();
}, this.props.duration);
}
}, {
key: 'decideEndPosition',
value: function decideEndPosition() {
var _state = this.state,
_state$deltaX = _state.deltaX,
deltaX = _state$deltaX === undefined ? 0 : _state$deltaX,
_state$deltaY = _state.deltaY,
deltaY = _state$deltaY === undefined ? 0 : _state$deltaY,
current = _state.current;
var _props = this.props,
axis = _props.axis,
loop = _props.loop,
minMove = _props.minMove,
children = _props.children;
var childLength = _react.Children.count(children);
switch (axis) {
case 'x':
if (loop === false) {
if (current === 0 && deltaX > 0) return 'origin';
if (current === childLength - 1 && deltaX < 0) return 'origin';
}
if (Math.abs(deltaX) < minMove) return 'origin';
return deltaX > 0 ? 'right' : 'left';
case 'y':
if (loop === false) {
if (current === 0 && deltaY > 0) return 'origin';
if (current === childLength - 1 && deltaY < 0) return 'origin';
}
if (Math.abs(deltaY) < minMove) return 'origin';
return deltaY > 0 ? 'down' : 'up';
default:
}
}
}, {
key: 'moveFramesBy',
value: function moveFramesBy(deltaX, deltaY) {
var _state$movingFrames = this.state.movingFrames,
prev = _state$movingFrames.prev,
current = _state$movingFrames.current,
next = _state$movingFrames.next;
var _state2 = this.state,
frameWidth = _state2.frameWidth,
frameHeight = _state2.frameHeight;
switch (this.props.axis) {
case 'x':
translateXY(current, deltaX, 0);
if (deltaX < 0) {
translateXY(next, deltaX + frameWidth, 0);
} else {
translateXY(prev, deltaX - frameWidth, 0);
}
break;
case 'y':
translateXY(current, 0, deltaY);
if (deltaY < 0) {
translateXY(next, 0, deltaY + frameHeight);
} else {
translateXY(prev, 0, deltaY - frameHeight);
}
break;
default:
}
}
}, {
key: 'prepareAutoSlide',
value: function prepareAutoSlide() {
var _this3 = this;
if (_react.Children.count(this.props.children) < 2) return;
this.clearAutoTimeout();
this.updateFrameSize(function () {
_this3.prepareSiblingFrames();
});
// auto slide only avalible in loop mode
if (this.mounted && this.props.loop && this.props.auto) {
var slideTimeoutID = setTimeout(this.autoSlide, this.props.interval);
this.setState({ slider: slideTimeoutID });
}
}
// auto slide to 'next' or 'prev'
}, {
key: 'autoSlide',
value: function autoSlide(rel) {
var _this4 = this;
this.clearAutoTimeout();
switch (rel) {
case 'prev':
this.transitFramesTowards(this.props.axis === 'x' ? 'right' : 'down');
break;
case 'next':
default:
this.transitFramesTowards(this.props.axis === 'x' ? 'left' : 'up');
}
// prepare next move after animation
setTimeout(function () {
return _this4.prepareAutoSlide();
}, this.props.duration);
}
}, {
key: 'next',
value: function next() {
var current = this.state.current;
var childCount = _react.Children.count(this.props.children);
if (!this.props.loop && current === childCount - 1) return false;
this.autoSlide('next');
}
}, {
key: 'prev',
value: function prev() {
if (!this.props.loop && this.state.current === 0) return false;
this.autoSlide('prev');
}
}, {
key: 'clearAutoTimeout',
value: function clearAutoTimeout() {
clearTimeout(this.state.slider);
}
}, {
key: 'updateFrameSize',
value: function updateFrameSize(cb) {
var _window$getComputedSt = window.getComputedStyle(wrapper),
width = _window$getComputedSt.width,
height = _window$getComputedSt.height;
this.setState({
frameWidth: parseFloat(width.split('px')[0]),
frameHeight: parseFloat(height.split('px')[0])
}, cb);
}
}, {
key: 'prepareSiblingFrames',
value: function prepareSiblingFrames() {
var siblings = {
current: frames['f' + this.getFrameId()],
prev: frames['f' + this.getFrameId('prev')],
next: frames['f' + this.getFrameId('next')]
};
if (!this.props.loop) {
this.state.current === 0 && (siblings.prev = undefined);
this.state.current === _react.Children.count(this.props.children) - 1 && (siblings.next = undefined);
}
this.setState({ movingFrames: siblings });
// prepare frames position
translateXY(siblings.current, 0, 0);
if (this.props.axis === 'x') {
translateXY(siblings.prev, -this.state.frameWidth, 0);
translateXY(siblings.next, this.state.frameWidth, 0);
} else {
translateXY(siblings.prev, 0, -this.state.frameHeight);
translateXY(siblings.next, 0, this.state.frameHeight);
}
return siblings;
}
}, {
key: 'getFrameId',
value: function getFrameId(pos) {
var children = this.props.children;
var current = this.state.current;
var total = _react.Children.count(children);
switch (pos) {
case 'prev':
return (current - 1 + total) % total;
case 'next':
return (current + 1) % total;
default:
return current;
}
}
}, {
key: 'transitFramesTowards',
value: function transitFramesTowards(direction) {
var _state$movingFrames2 = this.state.movingFrames,
prev = _state$movingFrames2.prev,
current = _state$movingFrames2.current,
next = _state$movingFrames2.next;
var _props2 = this.props,
duration = _props2.duration,
axis = _props2.axis;
var newCurrentId = this.state.current;
switch (direction) {
case 'up':
translateXY(current, 0, -this.state.frameHeight, duration);
translateXY(next, 0, 0, duration);
newCurrentId = this.getFrameId('next');
break;
case 'down':
translateXY(current, 0, this.state.frameHeight, duration);
translateXY(prev, 0, 0, duration);
newCurrentId = this.getFrameId('prev');
break;
case 'left':
translateXY(current, -this.state.frameWidth, 0, duration);
translateXY(next, 0, 0, duration);
newCurrentId = this.getFrameId('next');
break;
case 'right':
translateXY(current, this.state.frameWidth, 0, duration);
translateXY(prev, 0, 0, duration);
newCurrentId = this.getFrameId('prev');
break;
default:
// back to origin
translateXY(current, 0, 0, duration);
if (axis === 'x') {
translateXY(prev, -this.state.frameWidth, 0, duration);
translateXY(next, this.state.frameWidth, 0, duration);
} else if (axis === 'y') {
translateXY(prev, 0, -this.state.frameHeight, duration);
translateXY(next, 0, this.state.frameHeight, duration);
}
}
this.setState({ current: newCurrentId });
}
// debugFrames () {
// console.log('>>> DEBUG-FRAMES: current', this.state.current)
// const len = this.state.frames.length
// for (let i = 0; i < len; ++i) {
// const ref = this.refs['f' + i]
// console.info(ref.innerText.trim(), ref.style.transform)
// }
// }
}, {
key: 'render',
value: function render() {
var _this5 = this;
var current = this.state.current;
var _props3 = this.props,
children = _props3.children,
widgets = _props3.widgets,
axis = _props3.axis,
loop = _props3.loop,
auto = _props3.auto,
interval = _props3.interval,
className = _props3.className;
return _react2.default.createElement(
'div',
{
ref: function ref(_wrapper) {
wrapper = _wrapper;
},
className: className,
style: (0, _objectAssign2.default)({}, styles.wrapper, this.props.style),
onTouchStart: this.onTouchStart,
onMouseDown: this.onTouchStart },
_react.Children.map(children, function (child, i) {
var frameStyle = (0, _objectAssign2.default)({ zIndex: 99 - i }, styles.frame);
return _react2.default.createElement(
'div',
{ ref: function ref(_f) {
frames['f' + i] = _f;
}, key: i, style: frameStyle },
child
);
}),
widgets && [].concat(widgets).map(function (Widget, i) {
return _react2.default.createElement(Widget, {
key: i,
index: current,
total: _react.Children.count(children),
prevHandler: _this5.prev,
nextHandler: _this5.next,
axis: axis, loop: loop, auto: auto, interval: interval });
})
);
}
}]);
return Carousel;
}(_react2.default.Component);
Carousel.propTypes = {
axis: _propTypes2.default.oneOf(['x', 'y']),
auto: _propTypes2.default.bool,
loop: _propTypes2.default.bool,
interval: _propTypes2.default.number,
duration: _propTypes2.default.number,
widgets: _propTypes2.default.arrayOf(_propTypes2.default.func),
style: _propTypes2.default.object,
minMove: _propTypes2.default.number
};
Carousel.defaultProps = {
axis: 'x',
auto: false,
loop: false,
interval: 5000,
duration: 300,
minMove: 42
};
function translateXY(el, x, y) {
var duration = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
if (!el) return;
el.style.opacity = '1';
// animation
el.style.transitionDuration = duration + 'ms';
el.style.webkitTransitionDuration = duration + 'ms';
el.style.transfrom = 'translate(' + x + 'px, ' + y + 'px)';
el.style.webkitTransform = 'translate(' + x + 'px, ' + y + 'px) translateZ(0)';
}
exports.default = Carousel;
//# sourceMappingURL=Carousel.js.map