UNPKG

eg-imageview

Version:
347 lines (290 loc) 12.5 kB
/** * inspiration by https://github.com/mzabriskie/react-draggable * Created by genffy on 16/7/18. */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactLibReactDOM = require('react/lib/ReactDOM'); var _reactLibReactDOM2 = _interopRequireDefault(_reactLibReactDOM); var _eagleUiLibUtilsComponent = require('eagle-ui/lib/utils/Component'); var _eagleUiLibUtilsComponent2 = _interopRequireDefault(_eagleUiLibUtilsComponent); var _eagleUiLibUtilsDom = require('eagle-ui/lib/utils/Dom'); var _eagleUiLibUtilsDom2 = _interopRequireDefault(_eagleUiLibUtilsDom); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _utils = require('./utils'); var eventsFor = { touch: { start: 'touchstart', move: 'touchmove', stop: 'touchend' }, mouse: { start: 'mousedown', move: 'mousemove', stop: 'mouseup' } }; var dragEventFor = eventsFor.mouse; var Draggable = (function (_Component) { _inherits(Draggable, _Component); _createClass(Draggable, null, [{ key: 'propTypes', value: { bounds: _react.PropTypes.string, defaultPosition: _react.PropTypes.shape({ x: _react.PropTypes.number, y: _react.PropTypes.number }), position: _react.PropTypes.shape({ x: _react.PropTypes.number, y: _react.PropTypes.number }) }, enumerable: true }, { key: 'defaultProps', value: { // default is parent bounds: 'parent', defaultPosition: { x: 0, y: 0 }, position: null }, enumerable: true }]); function Draggable(props) { _classCallCheck(this, Draggable); _Component.call(this, props); // console.dir(props.position); this.state = { dragging: false, dragged: false, x: props.position ? props.position.x : props.defaultPosition.x, y: props.position ? props.position.y : props.defaultPosition.y, slackX: 0, slackY: 0, touchIdentifier: null }; this.id = props.elm; } Draggable.prototype.componentWillMount = function componentWillMount() {}; Draggable.prototype.componentDidMount = function componentDidMount() { // var elm = this.getDElement(); // if(elm){ // setTimeout(()=>{ // this.setState({ // x:elm.offsetWidth, // y:elm.offsetHeight // }) // }) // } }; Draggable.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { // Set x/y if position has changed if (nextProps.position && (!this.props.position || nextProps.position.x !== this.props.position.x || nextProps.position.y !== this.props.position.y)) { this.setState({ x: nextProps.position.x, y: nextProps.position.y }); } }; Draggable.prototype.componentWillUnmount = function componentWillUnmount() { this.setState({ dragging: false }); }; Draggable.prototype.createCoreData = function createCoreData(x, y) { var draggable = this; var state = draggable.state; var isStart = !_utils.isNum(state.lastX); var elm = this.getDElement(); if (isStart) { // first start init data return { node: elm ? elm : _reactLibReactDOM2['default'].findDOMNode(draggable), deltaX: 0, deltaY: 0, lastX: x, lastY: y, x: x, y: y }; } else { // calculate data. return { node: elm ? elm : _reactLibReactDOM2['default'].findDOMNode(draggable), deltaX: x - state.lastX, deltaY: y - state.lastY, lastX: state.lastX, lastY: state.lastY, x: x, y: y }; } }; // factory Draggable.prototype.createDraggableData = function createDraggableData(coreData) { var draggable = this; return { node: coreData.node, x: draggable.state.x + coreData.deltaX, y: draggable.state.y + coreData.deltaY, deltaX: coreData.deltaX, deltaY: coreData.deltaY, lastX: draggable.state.x, lastY: draggable.state.y }; }; Draggable.prototype.getPosition = function getPosition(evt, touchIdentifier) { // 判断 touch var touchObj = typeof touchIdentifier === 'number' ? _utils.getTouch(evt, touchIdentifier) : null; if (typeof touchIdentifier === 'number' && !touchObj) return null; evt = touchObj || evt; var node = _reactLibReactDOM2['default'].findDOMNode(this); var offsetParent = node.offsetParent; var offsetParentRect = _eagleUiLibUtilsDom2['default'](offsetParent).offset(); var x = evt.clientX + offsetParent.scrollLeft - offsetParentRect.left; var y = evt.clientY + offsetParent.scrollTop - offsetParentRect.top; return { x: x, y: y }; }; Draggable.prototype.handleDragStart = function handleDragStart(e) { // Set touch identifier in component state if this is a touch event. This allows us to // distinguish between individual touches on multitouch screens by identifying which // touchpoint was set to this element. var touchIdentifier = _utils.getTouchIdentifier(e); this.setState({ touchIdentifier: touchIdentifier }); var _getPosition = this.getPosition(e, touchIdentifier, this /*node*/); var x = _getPosition.x; var y = _getPosition.y; this.setState({ dragging: true, dragged: true, lastX: x, lastY: y }); _utils.addEvent(document, dragEventFor.move, this.handleDrag.bind(this)); _utils.addEvent(document, dragEventFor.stop, this.handleDragStop.bind(this)); }; Draggable.prototype.handleDrag = function handleDrag(e) { if (!this.state.dragging) return false; var _getPosition2 = this.getPosition(e, this.state.touchIdentifier, this /*node*/); var x = _getPosition2.x; var y = _getPosition2.y; var coreData = this.createCoreData(x, y); var uiData = this.createDraggableData(coreData); var newState = { x: uiData.x, y: uiData.y }; // TODO Keep within bounds. newState.lastX = x; newState.lastY = y; this.setState(newState); }; Draggable.prototype.handleDragStop = function handleDragStop(e) { if (!this.state.dragging) return false; var newState = { dragging: false, lastX: NaN, lastY: NaN, slackX: 0, slackY: 0 }; // If this is a controlled component, the result of this operation will be to // revert back to the old position. We expect a handler on `onDragStop`, at the least. var controlled = Boolean(this.props.position); if (controlled) { var _props$position = this.props.position; var _x = _props$position.x; var _y = _props$position.y; newState.x = _x; newState.y = _y; } this.setState(newState); _utils.removeEvent(document, dragEventFor.move, this.handleDrag); _utils.removeEvent(document, dragEventFor.stop, this.handleDragStop); }; // TODO add prefix for browser Draggable.prototype.createCSSTransform = function createCSSTransform(styleObj) { var value = 'translate( ' + styleObj.x + 'px, ' + styleObj.y + 'px)'; if (this.id) { return '-webkit-transform:' + value + ';transform:' + value + ';'; } return { 'WebkitTransform': value, 'MozTransform': value, 'msTransform': value, 'OTransform': value, 'transform': value }; }; // hack event Draggable.prototype.onMouseDown = function onMouseDown(e) { dragEventFor = eventsFor.mouse; return this.handleDragStart(e); }; Draggable.prototype.onTouchStart = function onTouchStart(e) { dragEventFor = eventsFor.touch; return this.handleDragStart(e); }; Draggable.prototype.onMouseUp = function onMouseUp(e) { dragEventFor = eventsFor.mouse; return this.handleDragStop(e); }; Draggable.prototype.onTouchEnd = function onTouchEnd(e) { dragEventFor = eventsFor.touch; return this.handleDragStop(e); }; Draggable.prototype.reset = function reset() { var _this = this; var elm = this.getDElement(); if (elm) { setTimeout(function () { _this.setState({ x: -elm.offsetWidth / 2, y: -elm.offsetHeight / 2 }); }); } else { var newState = { x: 0, y: 0 }; this.setState(newState); } }; Draggable.prototype.getDElement = function getDElement() { if (this.id) { var elm = document.getElementById(this.id); if (elm) { return elm.parentNode.parentNode.parentNode; } } return null; }; Draggable.prototype.render = function render() { var style = this.createCSSTransform(this.state); // add class var className = _classnames2['default'](this.props.children.props.className || '', 'draggable', { 'draggable-dragging': this.state.dragging, 'draggable-dragged': this.state.dragged }); // TODO hack event var elm = this.getDElement(); if (elm) { elm.style.cssText = style; } return _react2['default'].createElement( 'div', _extends({}, this.props, { className: 'img-inner', onMouseDown: this.onMouseDown.bind(this), onTouchStart: this.onTouchStart.bind(this), onMouseUp: this.onMouseUp.bind(this), onTouchEnd: this.onTouchEnd.bind(this), style: this.id ? {} : style }), _react2['default'].cloneElement(_react2['default'].Children.only(this.props.children), { className: className, style: _extends({}, this.props.children.props.style) }) ); }; return Draggable; })(_eagleUiLibUtilsComponent2['default']); exports['default'] = Draggable; module.exports = exports['default'];