Explorar el Código

[fix] lower level bug nextProps.x ,nextProps.y

方正 hace 7 años
padre
commit
9eb15a02b4
Se han modificado 3 ficheros con 79 adiciones y 29 borrados
  1. 52 14
      app/src/App.js
  2. 7 6
      app/src/Dragger.js
  3. 20 9
      app/src/GridItem.js

+ 52 - 14
app/src/App.js

@@ -21,7 +21,42 @@ const syncLayout = (layout, childIndex, { GridX, GridY }, isUserMove) => {
             newlayout[i].isUserMove = isUserMove
         }
     }
+    return newlayout
+}
+
+const collision = (a, b) => {
+    if (a.GridX === b.GridX && a.GridY === b.GridY &&
+        a.w === b.w && a.h === b.h) {
+            return false
+    }
+
+    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
+}
 
+const layoutCheck = (layout, layoutItem, index, movingY) => {
+    let i, movedItem
+    let newlayout = layout.map((item, idx) => {
+        if (idx !== index) {
+            if (collision(item, layoutItem)) {
+                i = idx
+                let offsetY = layoutItem.GridY + layoutItem.h
+                // if (movingY > 0) offsetY = layoutItem.GridY + layoutItem.h
+                // if (movingY < 0) offsetY = layoutItem.GridY
+                movedItem = { ...item, GridY: offsetY, isUserMove: false }
+                return movedItem
+            }
+        }
+        return item
+    })
+    /** 递归调用,将layout中的所有重叠元素全部移动 */
+    if (typeof i === 'number' && typeof movedItem === 'object') {
+        newlayout = layoutCheck(newlayout, movedItem, i, 0)
+    }
     return newlayout
 }
 
@@ -51,8 +86,7 @@ class DraggerLayout extends React.Component {
         hMoving: 0,
         placeholderShow: false,
         placeholderMoving: false,
-        layout: MapLayoutTostate(this.props.layout),
-        transitionStyle: ''
+        layout: MapLayoutTostate(this.props.layout)
     }
 
     onDragStart(bundles) {
@@ -71,16 +105,21 @@ class DraggerLayout extends React.Component {
             placeholderShow: true,
             placeholderMoving: true,
             layout: newlayout,
-            transitionStyle: ''
         })
     }
 
-    onDrag(cor) {
+    onDrag(layoutItem, index) {
+
+        const subTmp = this.state.GridYMoving - layoutItem.GridY
 
+        const newLayout = layoutCheck(this.state.layout, layoutItem, index, subTmp)
         this.setState({
-            GridXMoving: cor.GridX,
-            GridYMoving: cor.GridY,
+            GridXMoving: layoutItem.GridX,
+            GridYMoving: layoutItem.GridY,
+            layout: newLayout
         })
+
+
     }
 
     onDragEnd(childIndex) {
@@ -90,8 +129,7 @@ class DraggerLayout extends React.Component {
         }, false)
         this.setState({
             placeholderShow: false,
-            layout: Newlayout,
-            transitionStyle: '.WrapDragger{-webkit-transition: all .3s;transition: all .3s;}'
+            layout: Newlayout
         })
     }
     placeholder() {
@@ -146,12 +184,12 @@ class DraggerLayout extends React.Component {
 
     render() {
         const { layout, col, width, padding, rowHeight } = this.props
+
         return (
             <div
                 className='DraggerLayout'
                 style={{ position: 'absolute', left: 100, width: this.props.width, height: 500, border: '1px solid black' }}
             >
-                <style dangerouslySetInnerHTML={{ __html: this.state.transitionStyle }}></style>
                 {React.Children.map(this.props.children,
                     (child, index) => this.getGridItem(child, index)
                 )}
@@ -163,20 +201,20 @@ class DraggerLayout extends React.Component {
 
 export const LayoutDemo = () => {
     const layout = [{
-        GridX: 3, GridY: 4, w: 1, h: 3
+        GridX: 3, GridY: 2, w: 2, h: 2
     }, {
-        GridX: 3, GridY: 5, w: 2, h: 2
+        GridX: 0, GridY: 1, w: 2, h: 2
     }, {
-        GridX: 4, GridY: 5, w: 1, h: 3
+        GridX: 3, GridY: 6, w: 2, h: 2
     }, {
-        GridX: 4, GridY: 5, w: 3, h: 3
+        GridX: 3, GridY: 8, w: 2, h: 2
     }]
     return (
         <DraggerLayout layout={layout} width={500}>
             <p key='a'>absolute</p>
             <p key='b'>black</p>
             <p key='c'>children</p>
-            <p key='d'>children</p>
+            <p key='d'>fuck</p>
         </DraggerLayout>
     )
 }

+ 7 - 6
app/src/Dragger.js

@@ -234,13 +234,14 @@ export default class Dragger extends React.Component {
         // console.log(nextProps)
         const { isUserMove } = this.props
         if (!isUserMove) {
-            if (typeof this.props.x === 'number' &&
-                typeof this.props.y === 'number') {
+            console.log()
+            if (typeof nextProps.x === 'number' &&
+                typeof nextProps.y === 'number') {
                 this.setState({
-                    x: this.props.x,
-                    y: this.props.y,
-                    lastX:this.props.x,
-                    lastY:this.props.y
+                    x: nextProps.x,
+                    y: nextProps.y,
+                    lastX:nextProps.x,
+                    lastY:nextProps.y
                 })
             }
         }

+ 20 - 9
app/src/GridItem.js

@@ -54,20 +54,25 @@ export default class GridItem extends Component {
 
     /**转化,计算网格的GridX,GridY值 */
     calGridXY(x, y) {
-        const { margin, containerWidth, col } = this.props
+        const { margin, containerWidth, col, w } = this.props
 
         /**坐标转换成格子的时候,无须计算margin */
         let GridX = Math.round(x / containerWidth * col)
         let GridY = Math.round(y / (this.props.rowHeight + margin[1]))
+
+        /**防止元素出container */
+        if (GridX + w > col - 1) GridX = col - w
+        if (GridX < 0) GridX = 0
+        if (GridY < 0) GridY = 0
+
         return { GridX, GridY }
     }
 
     /**给予一个grid的位置,算出元素具体的在容器中位置在哪里,单位是px */
     calGridItemPosition(GridX, GridY) {
         const { w, margin, col, containerWidth } = this.props
-        if (GridX + w > col - 1) GridX = col - w
-        if (GridX < 0) GridX = 0
-        if (GridY < 0) GridY = 0
+
+
 
         let x = Math.round(GridX * (containerWidth - margin[0] * (col + 1)) / col + (GridX + 1) * margin[0])
         let y = Math.round(GridY * this.props.rowHeight + margin[1] * (GridY + 1))
@@ -90,14 +95,16 @@ export default class GridItem extends Component {
     onDragStart(x, y) {
         const { w, h, index } = this.props
         const { GridX, GridY } = this.calGridXY(x, y)
-        console.log(GridX, GridY)
+
         this.props.onDragStart({
             event, GridX, GridY, w, h, index
         })
     }
     onDrag(event, x, y) {
-        const cor = this.calGridXY(x, y)
-        this.props.onDrag(cor)
+        let { GridX, GridY } = this.calGridXY(x, y)
+        const { w, h, col } = this.props
+
+        this.props.onDrag({ GridX, GridY, w, h }, this.props.index)
     }
 
     onDragEnd() {
@@ -108,9 +115,13 @@ export default class GridItem extends Component {
         const { x, y } = this.calGridItemPosition(this.props.GridX, this.props.GridY)
         const { w, h, margin, style, bounds } = this.props
         const { wPx, hPx } = this.calWHtoPx(w, h)
+
         return (
             <Dragger
-                style={{ ...style, width: wPx, height: hPx, position: 'absolute' }}
+                style={{
+                    ...style, width: wPx, height: hPx, position: 'absolute',
+                    transition: this.props.isUserMove ? '' : 'all .15s'
+                }}
                 onDragStart={this.onDragStart}
                 onMove={this.onDrag}
                 onDragEnd={this.onDragEnd}
@@ -118,7 +129,7 @@ export default class GridItem extends Component {
                 y={y}
                 isUserMove={this.props.isUserMove}
             >
-                <div>
+                <div >
                     {React.Children.map(this.props.children, (child) => child)}
                 </div>
             </Dragger>