Z F пре 7 година
родитељ
комит
234c31c6bf
13 измењених фајлова са 229 додато и 331 уклоњено
  1. 1 1
      .babelrc
  2. 55 26
      app/src/App.js
  3. 34 6
      app/src/Dragger.js
  4. 3 3
      app/src/GridItem.js
  5. 5 4
      app/src/style.css
  6. 119 98
      build/App.js
  7. 6 5
      build/GridItem.js
  8. 1 1
      build/index.js
  9. 1 1
      build/react-dragger-layout.js
  10. 1 177
      package-lock.json
  11. 0 1
      package.json
  12. 2 7
      webpack.config.js
  13. 1 1
      webpack.pro.config.js

+ 1 - 1
.babelrc

@@ -12,7 +12,7 @@
   ],
   "plugins": [
     "transform-runtime",
-    // "react-hot-loader/babel",
+    "react-hot-loader/babel",
     "transform-object-rest-spread",
     "transform-react-jsx"
       // 开启react代码的模块热替换(HMR)

+ 55 - 26
app/src/App.js

@@ -5,11 +5,13 @@ import GridItem from './GridItem'
 import './style.css'
 
 const correctLayout = (layout) => {
-    for (let i = 0; i < layout.length; i++) {
-        if (collision(layout[i], layout[i + 1])) {
-            return layoutCheck(layout, layout[i], layout[i].key, layout[i].key, -1)
+    var copy = [...layout];
+    for (let 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;
 }
 
 /**
@@ -40,6 +42,14 @@ const MapLayoutTostate = (layout, children) => {
     })
 }
 
+/**
+ * 把用户移动的块,标记为true
+ * @param {*} layout 
+ * @param {*} key 
+ * @param {*} GridX 
+ * @param {*} GridY 
+ * @param {*} isUserMove 
+ */
 const syncLayout = (layout, key, GridX, GridY, isUserMove) => {
     const newlayout = layout.map((item) => {
         if (item.key === key) {
@@ -56,11 +66,8 @@ const syncLayout = (layout, key, GridX, GridY, isUserMove) => {
 const 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
@@ -89,6 +96,12 @@ const getFirstCollison = (layout, item) => {
     return null
 }
 
+
+/**
+ * 压缩单个元素,使得每一个元素都会紧挨着边界或者相邻的元素
+ * @param {*} finishedLayout 压缩完的元素会放进这里来,用来对比之后的每一个元素是否需要压缩
+ * @param {*} item 
+ */
 const compactItem = (finishedLayout, item) => {
     const newItem = { ...item }
 
@@ -102,16 +115,21 @@ const compactItem = (finishedLayout, item) => {
     while (true) {
         let FirstCollison = getFirstCollison(finishedLayout, newItem)
         if (FirstCollison) {
+            /**第一次发生碰撞时,就可以返回了 */
             newItem.GridY = FirstCollison.GridY + FirstCollison.h
             return newItem
         }
         newItem.GridY--
 
-        if (newItem.GridY < 0) return { ...newItem, GridY: 0 }
+        if (newItem.GridY < 0) return { ...newItem, GridY: 0 }/**碰到边界的时候,返回 */
     }
     return newItem
 }
 
+/**
+ * 压缩layout,使得每一个元素都会紧挨着边界或者相邻的元素
+ * @param {*} layout 
+ */
 const compactLayout = (layout) => {
     let sorted = sortLayout(layout)
     const needCompact = Array(layout.length)
@@ -120,13 +138,13 @@ const compactLayout = (layout) => {
         let finished = compactItem(compareList, sorted[i])
         finished.isUserMove = false
         compareList.push(finished)
-        needCompact[layout.indexOf(sorted[i])] = finished
+        needCompact[i] = finished//用于输出从小到大的位置
     }
-    return needCompact
+    return sortLayout(needCompact)
 }
 
 const layoutCheck = (layout, layoutItem, key, fristItemkey, moving) => {
-    let i = [], movedItem = []
+    let i = [], movedItem = []/**收集所有移动过的物体 */
     let newlayout = layout.map((item, idx) => {
         if (item.key !== key) {
             if (collision(item, layoutItem)) {
@@ -138,7 +156,7 @@ const layoutCheck = (layout, layoutItem, key, fristItemkey, moving) => {
                 let offsetY = item.GridY + 1
 
                 /**这一行也非常关键,当向上移动的时候,碰撞的元素必须固定 */
-                if (moving < 0 && layoutItem.GridY > 0) offsetY = item.GridY
+                // if (moving < 0 && layoutItem.GridY > 0) offsetY = item.GridY
 
                 if (layoutItem.GridY > item.GridY && layoutItem.GridY < item.GridY + item.h) {
                     /**
@@ -179,20 +197,26 @@ const layoutCheck = (layout, layoutItem, key, fristItemkey, moving) => {
                 return { ...item, GridY: offsetY, isUserMove: false }
             }
         } else if (fristItemkey === key) {
+            /**永远保持用户移动的块是 isUserMove === true */
             return { ...item, GridX: layoutItem.GridX, GridY: layoutItem.GridY, isUserMove: true }
         }
         return item
     })
     /** 递归调用,将layout中的所有重叠元素全部移动 */
-    if (i.length > 0 && movedItem.length > 0) {
-        for (let c = 0; c < Math.min(movedItem.length, i.length); c++) {
-            newlayout = layoutCheck(newlayout, movedItem[c], i[c], fristItemkey, undefined)
-        }
+    const length = movedItem.length;
+    for (let c = 0; c < length; c++) {
+        newlayout = layoutCheck(newlayout, movedItem[c], i[c], fristItemkey, undefined)
     }
     return newlayout
 }
 
 
+const getMaxContainerHeight = (layout, elementHeight) => {
+
+    const height = (layout[layout.length - 1].GridY + layout[layout.length - 1].h) * (30 + 10) + 10
+    return height
+}
+
 class DraggerLayout extends React.Component {
     constructor(props) {
         super(props)
@@ -218,14 +242,14 @@ class DraggerLayout extends React.Component {
         hMoving: 0,
         placeholderShow: false,
         placeholderMoving: false,
-        layout: MapLayoutTostate(this.props.layout, this.props.children)
+        layout: MapLayoutTostate(this.props.layout, this.props.children),
+        containerHeight: 500
     }
 
     onDragStart(bundles) {
         const { GridX, GridY, w, h, UniqueKey } = bundles
 
         const newlayout = syncLayout(this.state.layout, UniqueKey, GridX, GridY, true)
-
         this.setState({
             GridXMoving: GridX,
             GridYMoving: GridY,
@@ -238,6 +262,7 @@ class DraggerLayout extends React.Component {
     }
 
     onDrag(layoutItem, key) {
+
         const { GridX, GridY } = layoutItem
         const moving = GridY - this.state.GridYMoving
 
@@ -249,7 +274,7 @@ class DraggerLayout extends React.Component {
                  * 特殊点:当我们移动元素的时候,元素在layout中的位置不断改变
                  * 但是当isUserMove=true的时候,鼠标拖拽的元素不会随着位图变化而变化
                  * 但是实际layout中的位置还是会改变
-                 * (isUserMove=true用于接触placeholder和元素的绑定)
+                 * (isUserMove=true用于解除placeholder和元素的绑定)
                  */
                 compactedLayout[i].isUserMove = true
                 layoutItem.GridX = compactedLayout[i].GridX
@@ -261,7 +286,8 @@ class DraggerLayout extends React.Component {
         this.setState({
             GridXMoving: layoutItem.GridX,
             GridYMoving: layoutItem.GridY,
-            layout: compactedLayout
+            layout: compactedLayout,
+            containerHeight: getMaxContainerHeight(compactedLayout)
         })
     }
 
@@ -269,7 +295,8 @@ class DraggerLayout extends React.Component {
         const compactedLayout = compactLayout(this.state.layout)
         this.setState({
             placeholderShow: false,
-            layout: compactedLayout
+            layout: compactedLayout,
+            containerHeight: getMaxContainerHeight(compactedLayout)
         })
     }
     placeholder() {
@@ -297,8 +324,10 @@ class DraggerLayout extends React.Component {
         let that = this
         setTimeout(function () {
             let layout = correctLayout(that.state.layout)
+            const compacted = compactLayout(layout);
             that.setState({
-                layout: compactLayout(layout)
+                layout: compacted,
+                containerHeight: getMaxContainerHeight(compacted)
             })
         }, 1);
     }
@@ -336,7 +365,7 @@ class DraggerLayout extends React.Component {
         return (
             <div
                 className='DraggerLayout'
-                style={{ left: 100, width: this.props.width, height: 1000, border: '1px solid black' }}
+                style={{ left: 100, width: this.props.width, height: this.state.containerHeight, border: '1px solid black' }}
             >
                 {React.Children.map(this.props.children,
                     (child, index) => this.getGridItem(child, index)
@@ -349,9 +378,9 @@ class DraggerLayout extends React.Component {
 
 export default class LayoutDemo extends React.Component {
 
-    render(){
+    render() {
         const layout = [{
-            GridX: 0, GridY: 0, w: 5, h: 3
+            GridX: 0, GridY: 0, w: 5, h: 5
         }, {
             GridX: 0, GridY: 0, w: 3, h: 3
         }, {
@@ -368,9 +397,9 @@ export default class LayoutDemo extends React.Component {
             GridX: 3, GridY: 8, w: 3, h: 3
         }]
         return (
-            <DraggerLayout layout={layout} width={1000} col={12}>
+            <DraggerLayout layout={layout} width={800} col={12}>
                 {layout.map((el, index) => {
-                    return (<div key={index}>1</div>)
+                    return (<div key={index}>{index}</div>)
                 })}
             </DraggerLayout>
         )

+ 34 - 6
app/src/Dragger.js

@@ -98,13 +98,22 @@ export default class Dragger extends React.Component {
     }
 
     move(event) {
+
+
         let { lastX, lastY } = this.state
         /*  event.client - this.state.origin 表示的是移动的距离,
         *   elX表示的是原来已经有的位移
         */
-        let deltaX = event.clientX - this.state.originX + lastX
-        let deltaY = event.clientY - this.state.originY + lastY
+        let deltaX, deltaY;
+        if (event.clientX) {
+            deltaX = event.clientX - this.state.originX + lastX
+            deltaY = event.clientY - this.state.originY + lastY
+        } else {
+            deltaX = event.touches[0].clientX - this.state.originX + lastX
+            deltaY = event.touches[0].clientY - this.state.originY + lastY
+        }
 
+        console.log(event)
         const { bounds } = this.props
         if (bounds) {
             /**
@@ -127,9 +136,9 @@ export default class Dragger extends React.Component {
                     left: int(this.parent.style.paddingLeft) + int(this.self.style.marginLeft) - this.self.offsetLeft,
                     top: int(this.parent.style.paddingTop) + int(this.self.style.marginTop) - this.self.offsetTop,
                     right: innerWidth(this.parent) - outerWidth(this.self) - this.self.offsetLeft +
-                    int(this.parent.style.paddingRight) - int(this.self.style.marginRight),
+                        int(this.parent.style.paddingRight) - int(this.self.style.marginRight),
                     bottom: innerHeight(this.parent) - outerHeight(this.self) - this.self.offsetTop +
-                    int(this.parent.style.paddingBottom) - int(this.self.style.marginBottom)
+                        int(this.parent.style.paddingBottom) - int(this.self.style.marginBottom)
                 }
             }
 
@@ -177,7 +186,12 @@ export default class Dragger extends React.Component {
          * 如果绑定在元素上,则鼠标离开元素,就不会再被监听了
          */
         doc.addEventListener('mousemove', this.move)
+        doc.addEventListener('touchmove', this.move)
+
         doc.addEventListener('mouseup', this.onDragEnd)
+        doc.addEventListener('touchend', this.onDragEnd)
+
+
 
         if (this.props.bounds === 'parent' &&
             /**为了让 这段代码不会重复执行 */
@@ -197,9 +211,18 @@ export default class Dragger extends React.Component {
 
         this.props.onDragStart(this.state.x, this.state.y)
 
+        let originX, originY;
+        if (event.clientX) {
+            originX = event.clientX
+            originY = event.clientY
+        } else {
+            originX = event.touches[0].clientX
+            originY = event.touches[0].clientY
+        }
+
         this.setState({
-            originX: event.clientX,
-            originY: event.clientY,
+            originX: originX,
+            originY: originY,
             lastX: this.state.x,
             lastY: this.state.y
         })
@@ -211,6 +234,9 @@ export default class Dragger extends React.Component {
         this.parent = null
         this.self = null
         doc.removeEventListener('mousemove', this.move)
+        doc.removeEventListener('touchmove', this.move)
+
+        doc.removeEventListener('touchend', this.onDragEnd)
         doc.removeEventListener('mouseup', this.onDragEnd)
 
         this.props.onDragEnd(event)
@@ -266,6 +292,8 @@ export default class Dragger extends React.Component {
             <div className={`${fixedClassName}WrapDragger`}
                 style={{ ...style, touchAction: 'none!important', transform: `translate(${x}px,${y}px)` }}
                 onMouseDown={this.onDragStart.bind(this)}
+                onTouchStart={this.onDragStart.bind(this)}
+                onTouchEnd={this.onDragEnd.bind(this)}
                 onMouseUp={this.onDragEnd.bind(this)}
                 {...others}
             >

+ 3 - 3
app/src/GridItem.js

@@ -48,8 +48,8 @@ export default class GridItem extends React.Component {
 
     /** 计算容器的每一个格子多大 */
     calColWidth() {
-        const { containerWidth, col, containerPadding, margin } = this.props
-        console.log(this.props)
+        const { containerWidth, col, containerPadding, margin } = this.props;
+
         return (containerWidth - containerPadding[0] * 2 - margin[0] * (col + 1)) / col
     }
 
@@ -116,7 +116,7 @@ export default class GridItem extends React.Component {
             <Dragger
                 style={{
                     ...style, width: wPx, height: hPx, position: 'absolute',
-                    transition: this.props.isUserMove ? '' : 'all .15s'
+                    transition: this.props.isUserMove ? '' : 'all .2s'
                 }}
                 onDragStart={this.onDragStart}
                 onMove={this.onDrag}

+ 5 - 4
app/src/style.css

@@ -3,12 +3,13 @@
     height: 100px;
 } */
 
-.WrapDragger{
+.WrapDragger {
     display: flex;
     align-items: center;
     justify-content: center;
 }
-.DraggerLayout{
-    -webkit-transition: all 3.3s;
-    transition: all 3.3s;
+
+.DraggerLayout {
+    -webkit-transition: all .15s;
+    transition: all .15s;
 }

+ 119 - 98
build/App.js

@@ -4,6 +4,7 @@ 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';
@@ -11,13 +12,20 @@ import GridItem from './GridItem';
 import './style.css';
 
 var correctLayout = function correctLayout(layout) {
-    for (var i = 0; i < layout.length; i++) {
-        if (collision(layout[i], layout[i + 1])) {
-            return layoutCheck(layout, layout[i], layout[i].key, layout[i].key, -1);
+    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) {
@@ -26,6 +34,14 @@ var layoutItemForkey = function layoutItemForkey(layout, key) {
     }
 };
 
+/**
+ * 初始化的时候调用
+ * 会把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 });
@@ -33,6 +49,14 @@ var MapLayoutTostate = function MapLayoutTostate(layout, children) {
     });
 };
 
+/**
+ * 把用户移动的块,标记为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) {
@@ -48,10 +72,8 @@ var syncLayout = function syncLayout(layout, key, GridX, GridY, isUserMove) {
 
 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;
@@ -72,17 +94,19 @@ var sortLayout = function sortLayout(layout) {
 
 /**获取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);
 
@@ -96,16 +120,22 @@ var compactItem = function compactItem(finishedLayout, item) {
     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 });
+        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);
@@ -114,14 +144,14 @@ var compactLayout = function compactLayout(layout) {
         var finished = compactItem(compareList, sorted[i]);
         finished.isUserMove = false;
         compareList.push(finished);
-        needCompact[layout.indexOf(sorted[i])] = finished;
+        needCompact[i] = finished; //用于输出从小到大的位置
     }
-    return needCompact;
+    return sortLayout(needCompact);
 };
 
 var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, moving) {
     var i = [],
-        movedItem = [];
+        movedItem = []; /**收集所有移动过的物体 */
     var newlayout = layout.map(function (item, idx) {
         if (item.key !== key) {
             if (collision(item, layoutItem)) {
@@ -133,7 +163,7 @@ var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, mo
                 var offsetY = item.GridY + 1;
 
                 /**这一行也非常关键,当向上移动的时候,碰撞的元素必须固定 */
-                if (moving < 0 && layoutItem.GridY > 0) offsetY = item.GridY;
+                // if (moving < 0 && layoutItem.GridY > 0) offsetY = item.GridY
 
                 if (layoutItem.GridY > item.GridY && layoutItem.GridY < item.GridY + item.h) {
                     /**
@@ -142,16 +172,11 @@ var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, mo
                      * 
                      */
                     offsetY = item.GridY;
-                    console.log('移动到', offsetY, '操纵的物体key', layoutItem.key, '移动的key', item.key);
                 }
+                /**
+                 * 物体向下移动的时候
+                 */
                 if (moving > 0) {
-                    /**
-                     * 这个地方的实现有点奇妙了,moving用于检查最开始移动的方块
-                     * layoutItem.GridY > item.h*(3/4) 这个做会让方块移动比较准确和精确
-                     * 如果是其他数字,很可能会出现不可预计的效果
-                     * 建议取值范围在1/2 ~ 3/4之间
-                     */
-
                     if (layoutItem.GridY + layoutItem.h < item.GridY) {
                         (function () {
                             var collision = void 0;
@@ -165,13 +190,11 @@ var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, mo
                                 collision = getFirstCollison(newLayout, copy);
                                 if (collision) {
                                     offsetY = collision.GridY + collision.h;
-                                    console.log('移动到', offsetY, '操纵的物体底部', copy.key, '碰撞顶部', copy.GridY, 'key', collision.key);
                                     break;
                                 } else {
                                     copy.GridY--;
                                 }
                                 if (copy.GridY < 0) {
-                                    console.log('移动到', offsetY, '操纵的物体底部', copy.key, '碰撞顶部', copy.GridY);
                                     offsetY = 0;
                                     break;
                                 }
@@ -183,19 +206,26 @@ var layoutCheck = function layoutCheck(layout, layoutItem, key, fristItemkey, mo
                 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中的所有重叠元素全部移动 */
-    if (i.length > 0 && movedItem.length > 0) {
-        for (var c = 0; c < Math.min(movedItem.length, i.length); c++) {
-            newlayout = layoutCheck(newlayout, movedItem[c], i[c], fristItemkey, undefined);
-        }
+    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);
 
@@ -211,7 +241,8 @@ var DraggerLayout = function (_React$Component) {
             hMoving: 0,
             placeholderShow: false,
             placeholderMoving: false,
-            layout: MapLayoutTostate(_this.props.layout, _this.props.children)
+            layout: MapLayoutTostate(_this.props.layout, _this.props.children),
+            containerHeight: 500
         };
 
         _this.onDrag = _this.onDrag.bind(_this);
@@ -231,7 +262,6 @@ var DraggerLayout = function (_React$Component) {
 
 
             var newlayout = syncLayout(this.state.layout, UniqueKey, GridX, GridY, true);
-
             this.setState({
                 GridXMoving: GridX,
                 GridYMoving: GridY,
@@ -258,7 +288,7 @@ var DraggerLayout = function (_React$Component) {
                      * 特殊点:当我们移动元素的时候,元素在layout中的位置不断改变
                      * 但是当isUserMove=true的时候,鼠标拖拽的元素不会随着位图变化而变化
                      * 但是实际layout中的位置还是会改变
-                     * (isUserMove=true用于接触placeholder和元素的绑定)
+                     * (isUserMove=true用于解除placeholder和元素的绑定)
                      */
                     compactedLayout[i].isUserMove = true;
                     layoutItem.GridX = compactedLayout[i].GridX;
@@ -270,7 +300,8 @@ var DraggerLayout = function (_React$Component) {
             this.setState({
                 GridXMoving: layoutItem.GridX,
                 GridYMoving: layoutItem.GridY,
-                layout: compactedLayout
+                layout: compactedLayout,
+                containerHeight: getMaxContainerHeight(compactedLayout)
             });
         }
     }, {
@@ -279,7 +310,8 @@ var DraggerLayout = function (_React$Component) {
             var compactedLayout = compactLayout(this.state.layout);
             this.setState({
                 placeholderShow: false,
-                layout: compactedLayout
+                layout: compactedLayout,
+                containerHeight: getMaxContainerHeight(compactedLayout)
             });
         }
     }, {
@@ -318,8 +350,10 @@ var DraggerLayout = function (_React$Component) {
             var that = this;
             setTimeout(function () {
                 var layout = correctLayout(that.state.layout);
+                var compacted = compactLayout(layout);
                 that.setState({
-                    layout: compactLayout(layout)
+                    layout: compacted,
+                    containerHeight: getMaxContainerHeight(compacted)
                 });
             }, 1);
         }
@@ -334,7 +368,6 @@ var DraggerLayout = function (_React$Component) {
                 rowHeight = _props2.rowHeight;
 
             var renderItem = layoutItemForkey(layout, child.key);
-
             return React.createElement(
                 GridItem,
                 {
@@ -374,7 +407,7 @@ var DraggerLayout = function (_React$Component) {
                 'div',
                 {
                     className: 'DraggerLayout',
-                    style: { position: 'absolute', left: 100, width: this.props.width, height: 1000, border: '1px solid black' }
+                    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);
@@ -397,70 +430,54 @@ DraggerLayout.PropTypes = {
     padding: PropTypes.number
 };
 
+var LayoutDemo = function (_React$Component2) {
+    _inherits(LayoutDemo, _React$Component2);
 
-export var LayoutDemo = function LayoutDemo() {
-    var layout = [{
-        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: 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: 1000, col: 12 },
-        React.createElement(
-            'p',
-            { key: 'a' },
-            'a'
-        ),
-        React.createElement(
-            'p',
-            { key: 'b' },
-            'b'
-        ),
-        React.createElement(
-            'p',
-            { key: 'c' },
-            'c'
-        ),
-        React.createElement(
-            'p',
-            { key: 'd' },
-            'd'
-        ),
-        React.createElement(
-            'p',
-            { key: 'e' },
-            'e'
-        ),
-        React.createElement(
-            'p',
-            { key: 'f' },
-            'f'
-        ),
-        React.createElement(
-            'p',
-            { key: 'g' },
-            'g'
-        ),
-        React.createElement(
-            'p',
-            { key: 'h' },
-            'h'
-        )
-    );
-};
+    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 () {
@@ -488,9 +505,13 @@ var _temp = function () {
 
     __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');
 }();
 
 ;

+ 6 - 5
build/GridItem.js

@@ -5,12 +5,12 @@ import _createClass from 'babel-runtime/helpers/createClass';
 import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
 import _inherits from 'babel-runtime/helpers/inherits';
 import React from 'react';
-import { Component } from 'react';
+
 import PropTypes from 'prop-types';
 import Dragger from './Dragger';
 
-var GridItem = function (_Component) {
-    _inherits(GridItem, _Component);
+var GridItem = function (_React$Component) {
+    _inherits(GridItem, _React$Component);
 
     function GridItem(props) {
         _classCallCheck(this, GridItem);
@@ -37,6 +37,7 @@ var GridItem = function (_Component) {
                 containerPadding = _props.containerPadding,
                 margin = _props.margin;
 
+
             return (containerWidth - containerPadding[0] * 2 - margin[0] * (col + 1)) / col;
         }
 
@@ -158,7 +159,7 @@ var GridItem = function (_Component) {
                 Dragger,
                 {
                     style: _extends({}, style, { width: wPx, height: hPx, position: 'absolute',
-                        transition: this.props.isUserMove ? '' : 'all .15s'
+                        transition: this.props.isUserMove ? '' : 'all .2s'
                     }),
                     onDragStart: this.onDragStart,
                     onMove: this.onDrag,
@@ -179,7 +180,7 @@ var GridItem = function (_Component) {
     }]);
 
     return GridItem;
-}(Component);
+}(React.Component);
 
 GridItem.PropTypes = {
     /**外部容器属性 */

+ 1 - 1
build/index.js

@@ -2,7 +2,7 @@
 
 import React from 'react';
 import ReactDOM from 'react-dom';
-import { LayoutDemo } from './App';
+import LayoutDemo from './App';
 
 ReactDOM.render(React.createElement(
     'div',

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
build/react-dragger-layout.js


+ 1 - 177
package-lock.json

@@ -96,14 +96,6 @@
       "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
       "dev": true
     },
-    "anujs": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/anujs/-/anujs-1.1.4.tgz",
-      "integrity": "sha1-dWQnJwUXT3eOCvPbdza5wQ9A5N4=",
-      "requires": {
-        "chai-spies": "0.7.1"
-      }
-    },
     "anymatch": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz",
@@ -490,14 +482,6 @@
         "babel-runtime": "6.23.0"
       }
     },
-    "babel-plugin-external-helpers": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz",
-      "integrity": "sha1-IoX0iwK9Xe3oUXXK+MYuhq3M76E=",
-      "requires": {
-        "babel-runtime": "6.23.0"
-      }
-    },
     "babel-plugin-syntax-async-functions": {
       "version": "6.13.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
@@ -1312,11 +1296,6 @@
         "lazy-cache": "1.0.4"
       }
     },
-    "chai-spies": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/chai-spies/-/chai-spies-0.7.1.tgz",
-      "integrity": "sha1-ND2Z9RJEIS6LF+ZLk5lv97LCqbE="
-    },
     "chalk": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
@@ -3344,18 +3323,6 @@
         "inherits": "2.0.3"
       }
     },
-    "history": {
-      "version": "4.7.2",
-      "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
-      "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
-      "requires": {
-        "invariant": "2.2.2",
-        "loose-envify": "1.3.1",
-        "resolve-pathname": "2.2.0",
-        "value-equal": "0.4.0",
-        "warning": "3.0.0"
-      }
-    },
     "hmac-drbg": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -3367,11 +3334,6 @@
         "minimalistic-crypto-utils": "1.0.1"
       }
     },
-    "hoist-non-react-statics": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz",
-      "integrity": "sha1-ND24TGAYxlB3iJgkATWhQg7iLOA="
-    },
     "home-or-tmp": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
@@ -3542,6 +3504,7 @@
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
       "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+      "dev": true,
       "requires": {
         "loose-envify": "1.3.1"
       }
@@ -3844,11 +3807,6 @@
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
       "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
     },
-    "lodash-es": {
-      "version": "4.17.4",
-      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz",
-      "integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc="
-    },
     "lodash.camelcase": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
@@ -3881,67 +3839,6 @@
         "js-tokens": "3.0.1"
       }
     },
-    "luy": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/luy/-/luy-1.1.3.tgz",
-      "integrity": "sha512-8z9XZcHTZhBN+rDY1/finHRTBhFxB0hyAwn3WuMqzsrVX3nTxHn3kXCYD8LA8tcZ6vvJltLpEGQXg2UZmExSCA==",
-      "requires": {
-        "anujs": "1.1.4",
-        "babel-plugin-external-helpers": "6.22.0",
-        "babel-plugin-transform-object-rest-spread": "6.26.0",
-        "babel-plugin-transform-react-jsx": "6.24.1",
-        "babel-plugin-transform-runtime": "6.23.0",
-        "prop-types": "15.6.0",
-        "react": "15.6.2",
-        "react-dom": "15.6.1",
-        "react-redux": "5.0.6",
-        "react-router": "4.2.0",
-        "react-router-dom": "4.2.2"
-      },
-      "dependencies": {
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
-        },
-        "fbjs": {
-          "version": "0.8.16",
-          "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
-          "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
-          "requires": {
-            "core-js": "1.2.7",
-            "isomorphic-fetch": "2.2.1",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1",
-            "promise": "7.3.1",
-            "setimmediate": "1.0.5",
-            "ua-parser-js": "0.7.12"
-          }
-        },
-        "prop-types": {
-          "version": "15.6.0",
-          "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
-          "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
-          "requires": {
-            "fbjs": "0.8.16",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1"
-          }
-        },
-        "react": {
-          "version": "15.6.2",
-          "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz",
-          "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=",
-          "requires": {
-            "create-react-class": "15.6.0",
-            "fbjs": "0.8.16",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1",
-            "prop-types": "15.6.0"
-          }
-        }
-      }
-    },
     "macaddress": {
       "version": "0.2.8",
       "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
@@ -5065,61 +4962,6 @@
         "lodash": "4.17.4"
       }
     },
-    "react-redux": {
-      "version": "5.0.6",
-      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz",
-      "integrity": "sha512-8taaaGu+J7PMJQDJrk/xiWEYQmdo3mkXw6wPr3K3LxvXis3Fymiq7c13S+Tpls/AyNUAsoONkU81AP0RA6y6Vw==",
-      "requires": {
-        "hoist-non-react-statics": "2.3.1",
-        "invariant": "2.2.2",
-        "lodash": "4.17.4",
-        "lodash-es": "4.17.4",
-        "loose-envify": "1.3.1",
-        "prop-types": "15.5.10"
-      }
-    },
-    "react-router": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.2.0.tgz",
-      "integrity": "sha512-DY6pjwRhdARE4TDw7XjxjZsbx9lKmIcyZoZ+SDO7SBJ1KUeWNxT22Kara2AC7u6/c2SYEHlEDLnzBCcNhLE8Vg==",
-      "requires": {
-        "history": "4.7.2",
-        "hoist-non-react-statics": "2.3.1",
-        "invariant": "2.2.2",
-        "loose-envify": "1.3.1",
-        "path-to-regexp": "1.7.0",
-        "prop-types": "15.5.10",
-        "warning": "3.0.0"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
-        },
-        "path-to-regexp": {
-          "version": "1.7.0",
-          "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
-          "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
-          "requires": {
-            "isarray": "0.0.1"
-          }
-        }
-      }
-    },
-    "react-router-dom": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.2.2.tgz",
-      "integrity": "sha512-cHMFC1ZoLDfEaMFoKTjN7fry/oczMgRt5BKfMAkTu5zEuJvUiPp1J8d0eXSVTnBh6pxlbdqDhozunOOLtmKfPA==",
-      "requires": {
-        "history": "4.7.2",
-        "invariant": "2.2.2",
-        "loose-envify": "1.3.1",
-        "prop-types": "15.5.10",
-        "react-router": "4.2.0",
-        "warning": "3.0.0"
-      }
-    },
     "read-pkg": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
@@ -5327,11 +5169,6 @@
       "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
       "dev": true
     },
-    "resolve-pathname": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
-      "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
-    },
     "right-align": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
@@ -5993,11 +5830,6 @@
         "spdx-expression-parse": "1.0.4"
       }
     },
-    "value-equal": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
-      "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
-    },
     "vary": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz",
@@ -6019,14 +5851,6 @@
         "indexof": "0.0.1"
       }
     },
-    "warning": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
-      "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
-      "requires": {
-        "loose-envify": "1.3.1"
-      }
-    },
     "watchpack": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.3.1.tgz",

+ 0 - 1
package.json

@@ -28,7 +28,6 @@
     "babel-plugin-transform-object-rest-spread": "^6.26.0",
     "babel-plugin-transform-react-jsx": "^6.24.1",
     "babel-plugin-transform-runtime": "^6.23.0",
-    "luy": "^1.1.3",
     "prop-types": "^15.5.10",
     "react": "^15.6.1",
     "react-dom": "^15.6.1"

+ 2 - 7
webpack.config.js

@@ -10,7 +10,7 @@ module.exports = {
     ],
     output: {
         path: resolve(__dirname, 'build'),//打包后的文件存放的地方
-        filename: "bundle.js",//打包后输出文件的文件名
+        filename: "react-dragger-layout.js",//打包后输出文件的文件名
         publicPath: "/"
     },
     devServer: {
@@ -18,12 +18,7 @@ module.exports = {
         hot: true,
         publicPath: '/',
     },
-     resolve: {
-        alias: {
-           'react': 'luy',
-           'react-dom': 'luy'
-        }
-     },
+
     module: {
         rules: [
             {

+ 1 - 1
webpack.pro.config.js

@@ -37,7 +37,7 @@ module.exports = {
     },
     plugins: [
         // new webpack.HotModuleReplacementPlugin(),
-        new webpack.NamedModulesPlugin(),
+        // new webpack.NamedModulesPlugin(),
         new webpack.optimize.UglifyJsPlugin({
             compress: {
                 warnings: false

Неке датотеке нису приказане због велике количине промена