123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517 |
- import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
- import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
- import _createClass from 'babel-runtime/helpers/createClass';
- import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
- import _inherits from 'babel-runtime/helpers/inherits';
- import _extends from 'babel-runtime/helpers/extends';
- import _toConsumableArray from 'babel-runtime/helpers/toConsumableArray';
- import React from 'react';
- import PropTypes from 'prop-types';
- import GridItem from './GridItem';
- import './style.css';
- var correctLayout = function correctLayout(layout) {
- var copy = [].concat(_toConsumableArray(layout));
- for (var i = 0; i < layout.length - 1; i++) {
- if (collision(copy[i], copy[i + 1])) {
- copy = layoutCheck(copy, layout[i], layout[i].key, layout[i].key, undefined);
- }
- }
- return copy;
- };
- /**
- * 用key从layout中拿出item
- * @param {*} layout 输入进来的布局
- * @param {*} key
- */
- var layoutItemForkey = function layoutItemForkey(layout, key) {
- for (var i = 0, length = layout.length; i < length; i++) {
- if (key === layout[i].key) {
- return layout[i];
- }
- }
- };
- /**
- * 初始化的时候调用
- * 会把isUserMove和key一起映射到layout中
- * 不用用户设置
- * @param {*} layout
- * @param {*} children
- */
- var MapLayoutTostate = function MapLayoutTostate(layout, children) {
- return layout.map(function (child, index) {
- var newChild = _extends({}, child, { isUserMove: true, key: children[index].key });
- return newChild;
- });
- };
- /**
- * 把用户移动的块,标记为true
- * @param {*} layout
- * @param {*} key
- * @param {*} GridX
- * @param {*} GridY
- * @param {*} isUserMove
- */
- var syncLayout = function syncLayout(layout, key, GridX, GridY, isUserMove) {
- var newlayout = layout.map(function (item) {
- if (item.key === key) {
- item.GridX = GridX;
- item.GridY = GridY;
- item.isUserMove = isUserMove;
- return item;
- }
- return item;
- });
- return newlayout;
- };
- var collision = function collision(a, b) {
- if (a.GridX === b.GridX && a.GridY === b.GridY && a.w === b.w && a.h === b.h) {
- return true;
- }
- if (a.GridX + a.w <= b.GridX) return false;
- if (a.GridX >= b.GridX + b.w) return false;
- if (a.GridY + a.h <= b.GridY) return false;
- if (a.GridY >= b.GridY + b.h) return false;
- return true;
- };
- var sortLayout = function sortLayout(layout) {
- return [].concat(layout).sort(function (a, b) {
- if (a.GridY > b.GridY || a.GridY === b.GridY && a.GridX > b.GridX) {
- return 1;
- } else if (a.GridY === b.GridY && a.GridX === b.GridX) {
- return 0;
- }
- return -1;
- });
- };
- /**获取layout中,item第一个碰撞到的物体 */
- var getFirstCollison = function getFirstCollison(layout, item) {
- for (var i = 0, length = layout.length; i < length; i++) {
- if (collision(layout[i], item)) {
- return layout[i];
- }
- }
- return null;
- };
- /**
- * 压缩单个元素,使得每一个元素都会紧挨着边界或者相邻的元素
- * @param {*} finishedLayout 压缩完的元素会放进这里来,用来对比之后的每一个元素是否需要压缩
- * @param {*} item
- */
- var compactItem = function compactItem(finishedLayout, item) {
- var newItem = _extends({}, item);
- if (finishedLayout.length === 0) {
- return _extends({}, newItem, { GridY: 0 });
- }
- /**
- * 类似一个递归调用
- */
- while (true) {
- var FirstCollison = getFirstCollison(finishedLayout, newItem);
- if (FirstCollison) {
- /**第一次发生碰撞时,就可以返回了 */
- newItem.GridY = FirstCollison.GridY + FirstCollison.h;
- return newItem;
- }
- newItem.GridY--;
- if (newItem.GridY < 0) return _extends({}, newItem, { GridY: 0 /**碰到边界的时候,返回 */
- });
- }
- return newItem;
- };
- /**
- * 压缩layout,使得每一个元素都会紧挨着边界或者相邻的元素
- * @param {*} layout
- */
- var compactLayout = function compactLayout(layout) {
- var sorted = sortLayout(layout);
- var needCompact = Array(layout.length);
- var compareList = [];
- for (var i = 0, length = sorted.length; i < length; i++) {
- var finished = compactItem(compareList, sorted[i]);
- finished.isUserMove = false;
- compareList.push(finished);
- needCompact[i] = finished; //用于输出从小到大的位置
- }
- return sortLayout(needCompact);
- };
- var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, moving) {
- var i = [],
- movedItem = []; /**收集所有移动过的物体 */
- var newlayout = layout.map(function (item, idx) {
- if (item.key !== key) {
- if (collision(item, layoutItem)) {
- i.push(item.key);
- /**
- * 这里就是奇迹发生的地方,如果向上移动,那么必须注意的是
- * 一格一格的移动,而不是一次性移动
- */
- var offsetY = item.GridY + 1;
- /**这一行也非常关键,当向上移动的时候,碰撞的元素必须固定 */
- // if (moving < 0 && layoutItem.GridY > 0) offsetY = item.GridY
- if (layoutItem.GridY > item.GridY && layoutItem.GridY < item.GridY + item.h) {
- /**
- * 元素向上移动时,元素的上面空间不足,则不移动这个元素
- * 当元素移动到GridY>所要向上交换的元素时,就不会进入这里,直接交换元素
- *
- */
- offsetY = item.GridY;
- }
- /**
- * 物体向下移动的时候
- */
- if (moving > 0) {
- if (layoutItem.GridY + layoutItem.h < item.GridY) {
- (function () {
- var collision = void 0;
- var copy = _extends({}, item);
- while (true) {
- var newLayout = layout.filter(function (item) {
- if (item.key !== key && item.key !== copy.key) {
- return item;
- }
- });
- collision = getFirstCollison(newLayout, copy);
- if (collision) {
- offsetY = collision.GridY + collision.h;
- break;
- } else {
- copy.GridY--;
- }
- if (copy.GridY < 0) {
- offsetY = 0;
- break;
- }
- }
- })();
- }
- }
- movedItem.push(_extends({}, item, { GridY: offsetY, isUserMove: false }));
- return _extends({}, item, { GridY: offsetY, isUserMove: false });
- }
- } else if (fristItemkey === key) {
- /**永远保持用户移动的块是 isUserMove === true */
- return _extends({}, item, { GridX: layoutItem.GridX, GridY: layoutItem.GridY, isUserMove: true });
- }
- return item;
- });
- /** 递归调用,将layout中的所有重叠元素全部移动 */
- var length = movedItem.length;
- for (var c = 0; c < length; c++) {
- newlayout = layoutCheck(newlayout, movedItem[c], i[c], fristItemkey, undefined);
- }
- return newlayout;
- };
- var getMaxContainerHeight = function getMaxContainerHeight(layout, elementHeight) {
- var height = (layout[layout.length - 1].GridY + layout[layout.length - 1].h) * (30 + 10) + 10;
- console.log(height);
- return height;
- };
- var DraggerLayout = function (_React$Component) {
- _inherits(DraggerLayout, _React$Component);
- function DraggerLayout(props) {
- _classCallCheck(this, DraggerLayout);
- var _this = _possibleConstructorReturn(this, (DraggerLayout.__proto__ || _Object$getPrototypeOf(DraggerLayout)).call(this, props));
- _this.state = {
- GridXMoving: 0,
- GridYMoving: 0,
- wMoving: 0,
- hMoving: 0,
- placeholderShow: false,
- placeholderMoving: false,
- layout: MapLayoutTostate(_this.props.layout, _this.props.children),
- containerHeight: 500
- };
- _this.onDrag = _this.onDrag.bind(_this);
- _this.onDragStart = _this.onDragStart.bind(_this);
- _this.onDragEnd = _this.onDragEnd.bind(_this);
- return _this;
- }
- _createClass(DraggerLayout, [{
- key: 'onDragStart',
- value: function onDragStart(bundles) {
- var GridX = bundles.GridX,
- GridY = bundles.GridY,
- w = bundles.w,
- h = bundles.h,
- UniqueKey = bundles.UniqueKey;
- var newlayout = syncLayout(this.state.layout, UniqueKey, GridX, GridY, true);
- this.setState({
- GridXMoving: GridX,
- GridYMoving: GridY,
- wMoving: w,
- hMoving: h,
- placeholderShow: true,
- placeholderMoving: true,
- layout: newlayout
- });
- }
- }, {
- key: 'onDrag',
- value: function onDrag(layoutItem, key) {
- var GridX = layoutItem.GridX,
- GridY = layoutItem.GridY;
- var moving = GridY - this.state.GridYMoving;
- var newLayout = layoutCheck(this.state.layout, layoutItem, key, key /*用户移动方块的key */, moving);
- var compactedLayout = compactLayout(newLayout);
- for (var i = 0; i < compactedLayout.length; i++) {
- if (key === compactedLayout[i].key) {
- /**
- * 特殊点:当我们移动元素的时候,元素在layout中的位置不断改变
- * 但是当isUserMove=true的时候,鼠标拖拽的元素不会随着位图变化而变化
- * 但是实际layout中的位置还是会改变
- * (isUserMove=true用于解除placeholder和元素的绑定)
- */
- compactedLayout[i].isUserMove = true;
- layoutItem.GridX = compactedLayout[i].GridX;
- layoutItem.GridY = compactedLayout[i].GridY;
- break;
- }
- }
- this.setState({
- GridXMoving: layoutItem.GridX,
- GridYMoving: layoutItem.GridY,
- layout: compactedLayout,
- containerHeight: getMaxContainerHeight(compactedLayout)
- });
- }
- }, {
- key: 'onDragEnd',
- value: function onDragEnd(key) {
- var compactedLayout = compactLayout(this.state.layout);
- this.setState({
- placeholderShow: false,
- layout: compactedLayout,
- containerHeight: getMaxContainerHeight(compactedLayout)
- });
- }
- }, {
- key: 'placeholder',
- value: function placeholder() {
- if (!this.state.placeholderShow) return null;
- var _props = this.props,
- col = _props.col,
- width = _props.width,
- padding = _props.padding,
- rowHeight = _props.rowHeight;
- var _state = this.state,
- GridXMoving = _state.GridXMoving,
- GridYMoving = _state.GridYMoving,
- wMoving = _state.wMoving,
- hMoving = _state.hMoving,
- placeholderMoving = _state.placeholderMoving;
- return React.createElement(GridItem, {
- col: col,
- containerWidth: width,
- containerPadding: padding,
- rowHeight: rowHeight,
- GridX: GridXMoving,
- GridY: GridYMoving,
- w: wMoving,
- h: hMoving,
- style: { background: '#a31', zIndex: -1, transition: ' all .15s' },
- isUserMove: !placeholderMoving
- });
- }
- }, {
- key: 'componentDidMount',
- value: function componentDidMount() {
- var that = this;
- setTimeout(function () {
- var layout = correctLayout(that.state.layout);
- var compacted = compactLayout(layout);
- that.setState({
- layout: compacted,
- containerHeight: getMaxContainerHeight(compacted)
- });
- }, 1);
- }
- }, {
- key: 'getGridItem',
- value: function getGridItem(child, index) {
- var layout = this.state.layout;
- var _props2 = this.props,
- col = _props2.col,
- width = _props2.width,
- padding = _props2.padding,
- rowHeight = _props2.rowHeight;
- var renderItem = layoutItemForkey(layout, child.key);
- return React.createElement(
- GridItem,
- {
- col: col,
- containerWidth: width,
- containerPadding: padding,
- rowHeight: rowHeight,
- GridX: renderItem.GridX,
- GridY: renderItem.GridY,
- w: renderItem.w,
- h: renderItem.h,
- onDrag: this.onDrag,
- onDragStart: this.onDragStart,
- onDragEnd: this.onDragEnd,
- index: index,
- isUserMove: renderItem.isUserMove,
- style: { background: '#329' },
- UniqueKey: child.key
- },
- child
- );
- }
- }, {
- key: 'render',
- value: function render() {
- var _this2 = this;
- var _props3 = this.props,
- layout = _props3.layout,
- col = _props3.col,
- width = _props3.width,
- padding = _props3.padding,
- rowHeight = _props3.rowHeight;
- return React.createElement(
- 'div',
- {
- className: 'DraggerLayout',
- style: { left: 100, width: this.props.width, height: this.state.containerHeight, border: '1px solid black' }
- },
- React.Children.map(this.props.children, function (child, index) {
- return _this2.getGridItem(child, index);
- }),
- this.placeholder()
- );
- }
- }]);
- return DraggerLayout;
- }(React.Component);
- DraggerLayout.PropTypes = {
- /**外部属性 */
- layout: PropTypes.array,
- col: PropTypes.number,
- width: PropTypes.number,
- /**每个元素的最小高度 */
- rowHeight: PropTypes.number,
- padding: PropTypes.number
- };
- var LayoutDemo = function (_React$Component2) {
- _inherits(LayoutDemo, _React$Component2);
- function LayoutDemo() {
- _classCallCheck(this, LayoutDemo);
- return _possibleConstructorReturn(this, (LayoutDemo.__proto__ || _Object$getPrototypeOf(LayoutDemo)).apply(this, arguments));
- }
- _createClass(LayoutDemo, [{
- key: 'render',
- value: function render() {
- var layout = [{
- GridX: 0, GridY: 0, w: 5, h: 5
- }, {
- GridX: 0, GridY: 0, w: 3, h: 3
- }, {
- GridX: 0, GridY: 0, w: 3, h: 3
- }, {
- GridX: 0, GridY: 0, w: 3, h: 3
- }, {
- GridX: 3, GridY: 8, w: 3, h: 3
- }, {
- GridX: 3, GridY: 8, w: 3, h: 3
- }, {
- GridX: 3, GridY: 8, w: 3, h: 3
- }, {
- GridX: 3, GridY: 8, w: 3, h: 3
- }];
- return React.createElement(
- DraggerLayout,
- { layout: layout, width: 800, col: 12 },
- layout.map(function (el, index) {
- return React.createElement(
- 'div',
- { key: index },
- index
- );
- })
- );
- }
- }]);
- return LayoutDemo;
- }(React.Component);
- var _default = LayoutDemo;
- export default _default;
- ;
- var _temp = function () {
- if (typeof __REACT_HOT_LOADER__ === 'undefined') {
- return;
- }
- __REACT_HOT_LOADER__.register(correctLayout, 'correctLayout', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(layoutItemForkey, 'layoutItemForkey', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(MapLayoutTostate, 'MapLayoutTostate', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(syncLayout, 'syncLayout', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(collision, 'collision', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(sortLayout, 'sortLayout', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(getFirstCollison, 'getFirstCollison', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(compactItem, 'compactItem', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(compactLayout, 'compactLayout', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(layoutCheck, 'layoutCheck', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(getMaxContainerHeight, 'getMaxContainerHeight', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(DraggerLayout, 'DraggerLayout', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(LayoutDemo, 'LayoutDemo', 'app/src/App.js');
- __REACT_HOT_LOADER__.register(_default, 'default', 'app/src/App.js');
- }();
- ;
|