Просмотр исходного кода

[fix] layout auto compact done ( with some rubbish code)

方正 7 лет назад
Родитель
Сommit
23c251114c
3 измененных файлов с 169 добавлено и 59 удалено
  1. 159 50
      app/src/App.js
  2. 1 2
      app/src/Dragger.js
  3. 9 7
      app/src/GridItem.js

+ 159 - 50
app/src/App.js

@@ -5,28 +5,40 @@ import GridItem from './GridItem'
 import './style.css'
 
 
-const MapLayoutTostate = (layout) => {
-    return layout.map((child) => {
-        let newChild = { ...child, isUserMove: true }
+const layoutItemForkey = (layout, key) => {
+    for (let i = 0, length = layout.length; i < length; i++) {
+        if (key === layout[i].key) {
+            return layout[i]
+        }
+    }
+}
+
+const MapLayoutTostate = (layout, children) => {
+    return layout.map((child, index) => {
+        let newChild = { ...child, isUserMove: true, key: children[index].key }
         return newChild
     })
 }
 
-const syncLayout = (layout, childIndex, { GridX, GridY }, isUserMove) => {
-    let newlayout = Object.assign([], layout)
-    for (let i = 0, length = newlayout.length; i < length; i++) {
-        if (i === childIndex) {
-            newlayout[i].GridX = GridX
-            newlayout[i].GridY = GridY
-            newlayout[i].isUserMove = isUserMove
+const syncLayout = (layout, key, GridX, GridY, isUserMove) => {
+    const newlayout = layout.map((item) => {
+        if (item.key === key) {
+            return {
+                ...item,
+                GridX: GridX,
+                GridY: GridY,
+                isUserMove: isUserMove
+            }
         }
-    }
+        return item
+    })
     return newlayout
 }
 
 const collision = (a, b) => {
     if (a.GridX === b.GridX && a.GridY === b.GridY &&
         a.w === b.w && a.h === b.h) {
+
         return true
     }
 
@@ -34,30 +46,121 @@ const collision = (a, b) => {
     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, fristItemIndex) => {
+const sortLayout = (layout) => {
+    return [].concat(layout).sort((a, b) => {
+        // console.log('排序中:', 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第一个碰撞到的物体 */
+const getFirstCollison = (layout, item) => {
+    for (let i = 0, length = layout.length; i < length; i++) {
+        if (collision(layout[i], item)) {
+            return layout[i]
+        }
+    }
+    return null
+}
+
+const compactItem = (finishedLayout, item) => {
+    let newItem = { ...item }
+    if (finishedLayout.length === 0) {
+        return { ...newItem, GridY: 0 }
+    }
+
+    while (true) {
+        console.log('现在操作:',item.key)
+        
+        let FirstCollison = getFirstCollison(finishedLayout, newItem)
+        console.log('碰撞信息:',FirstCollison)
+        if (FirstCollison) {
+            newItem.GridY = FirstCollison.GridY + FirstCollison.h
+            console.log('碰撞的', FirstCollison.key, '移动的是', newItem.key,'移动到',newItem.GridY)
+            return newItem
+        }else{
+            if (newItem.GridY <= 0) return {...newItem,GridY:0}
+        }
+        newItem.GridY--
+
+    }
+
+
+
+
+    // for (let i = 0, length = finishedLayout.length; i < length; i++) {
+    //     let layoutItem = finishedLayout[i]
+    //     console.log('现在的队列:', layoutItem.key, '移动的是', item.key)
+    //     while (!collision(layoutItem, newItem)) {
+    //         if (newItem.GridY > 0) {
+    //             console.log('--')
+    //             newItem.GridY--
+    //         } else {
+    //             // console.log('重合', layoutItem.key)
+    //             break
+    //         }
+    //     }
+    //     while (collision(layoutItem, newItem)) {
+    //         newItem.GridY = layoutItem.GridY + layoutItem.h
+    //         finishedLayout.forEach((item) => {
+    //             console.log('此时队列里有:', item.key, 'x', item.GridX, 'y', item.GridY)
+    //         })
+    //         // if (typeof newItem === 'object' && item.GridY < newItem.GridY) break
+    //         // newItem = { ...item }
+    //         console.log('对应item', layoutItem.key, '编号', newItem.key, '移动', newItem.GridY, '高度', layoutItem.GridY + layoutItem.h)
+    //         return newItem
+    //     }
+    // }
+
+
+
+    return newItem
+}
+
+const compactLayout = (layout) => {
+    // console.log('排序前', layout)
+    let sorted = sortLayout(layout)
+    // console.log('排序后', sorted)
+    const needCompact = Array(layout.length)
+    const compareList = []
+    for (let i = 0, length = sorted.length; i < length; i++) {
+        let finished = compactItem(compareList, sorted[i])
+
+        finished.isUserMove = false
+        compareList.push(finished)
+        needCompact[layout.indexOf(sorted[i])] = finished
+    }
+
+    return needCompact
+}
+
+const layoutCheck = (layout, layoutItem, key, fristItemkey) => {
     let i, movedItem
     let newlayout = layout.map((item, idx) => {
-        if (idx !== index) {
+        if (item.key !== key) {
             if (collision(item, layoutItem)) {
-                i = idx
+                i = item.key
                 let offsetY = layoutItem.GridY + layoutItem.h
                 movedItem = { ...item, GridY: offsetY, isUserMove: false }
                 return movedItem
             }
-        } else if (fristItemIndex === idx) {
+        } else if (fristItemkey === key) {
             return { ...item, GridX: layoutItem.GridX, GridY: layoutItem.GridY, isUserMove: true }
         }
         return item
     })
     /** 递归调用,将layout中的所有重叠元素全部移动 */
-    if (typeof i === 'number' && typeof movedItem === 'object') {
-        
-        newlayout = layoutCheck(newlayout, movedItem, i, fristItemIndex)
-        console.log('检查这个layout:',newlayout)
+
+    if (typeof i === 'string' && typeof movedItem === 'object') {
+        newlayout = layoutCheck(newlayout, movedItem, i, fristItemkey)
     }
 
     return newlayout
@@ -89,17 +192,14 @@ class DraggerLayout extends React.Component {
         hMoving: 0,
         placeholderShow: false,
         placeholderMoving: false,
-        layout: MapLayoutTostate(this.props.layout)
+        layout: MapLayoutTostate(this.props.layout, this.props.children)
     }
 
     onDragStart(bundles) {
-        const { GridX, GridY, w, h, index } = bundles
-        const newlayout = syncLayout(this.state.layout, index, {
-            GridX: GridX,
-            GridY: GridY
-        }, true)
+        const { GridX, GridY, w, h, UniqueKey } = bundles
+
+        const newlayout = syncLayout(this.state.layout, UniqueKey, GridX, GridY, true)
 
-        console.log('placeholder', newlayout)
         this.setState({
             GridXMoving: GridX,
             GridYMoving: GridY,
@@ -111,11 +211,15 @@ class DraggerLayout extends React.Component {
         })
     }
 
-    onDrag(layoutItem, index) {
+    onDrag(layoutItem, key) {
+        const { GridX, GridY } = layoutItem
+        const newLayout = layoutCheck(this.state.layout, layoutItem, key, key/*用户移动方块的key */)
 
-        const subTmp = this.state.GridYMoving - layoutItem.GridY
+        // const synclayout = syncLayout(newLayout, key, {
+        //     GridX: GridX,
+        //     GridY: GridY
+        // }, true)
 
-        const newLayout = layoutCheck(this.state.layout, layoutItem, index, index/*第一个物品的参数 */)
         this.setState({
             GridXMoving: layoutItem.GridX,
             GridYMoving: layoutItem.GridY,
@@ -123,14 +227,14 @@ class DraggerLayout extends React.Component {
         })
     }
 
-    onDragEnd(childIndex) {
-        let Newlayout = syncLayout(this.state.layout, childIndex, {
-            GridX: this.state.GridXMoving,
-            GridY: this.state.GridYMoving
-        }, false)
+    onDragEnd(key) {
+        let Newlayout = syncLayout(this.state.layout, key, this.state.GridXMoving, this.state.GridYMoving, false)
+
+        const compactedLayout = compactLayout(Newlayout)
+
         this.setState({
             placeholderShow: false,
-            layout: Newlayout
+            layout: compactedLayout
         })
     }
     placeholder() {
@@ -155,28 +259,33 @@ class DraggerLayout extends React.Component {
         )
     }
     componentDidMount() {
-
+        // this.setState({
+        //     layout: compactLayout(this.state.layout)
+        // })
     }
 
     getGridItem(child, index) {
         const { layout } = this.state
         const { col, width, padding, rowHeight } = this.props
+        const renderItem = layoutItemForkey(layout, child.key)
+
         return (
             <GridItem
                 col={col}
                 containerWidth={width}
                 containerPadding={padding}
                 rowHeight={rowHeight}
-                GridX={layout[index].GridX}
-                GridY={layout[index].GridY}
-                w={layout[index].w}
-                h={layout[index].h}
+                GridX={renderItem.GridX}
+                GridY={renderItem.GridY}
+                w={renderItem.w}
+                h={renderItem.h}
                 onDrag={this.onDrag}
                 onDragStart={this.onDragStart}
                 onDragEnd={this.onDragEnd}
                 index={index}
-                isUserMove={layout[index].isUserMove}
+                isUserMove={renderItem.isUserMove}
                 style={{ background: '#329' }}
+                UniqueKey={child.key}
             >
                 {child}
             </GridItem >
@@ -202,20 +311,20 @@ class DraggerLayout extends React.Component {
 
 export const LayoutDemo = () => {
     const layout = [{
-        GridX: 3, GridY: 2, w: 2, h: 2
+        GridX: 3, GridY: 2, w: 1, h: 1
     }, {
-        GridX: 0, GridY: 1, w: 2, h: 2
+        GridX: 0, GridY: 1, w: 1, h: 3
     }, {
-        GridX: 3, GridY: 6, w: 2, h: 2
+        GridX: 3, GridY: 6, w: 2, h: 1
     }, {
-        GridX: 3, GridY: 8, w: 2, h: 2
+        GridX: 3, GridY: 8, w: 1, h: 4
     }]
     return (
         <DraggerLayout layout={layout} width={500}>
-            <p key='a'>absolute</p>
-            <p key='b'>black</p>
-            <p key='c'>children</p>
-            <p key='d'>fuck</p>
+            <p key='a'>a</p>
+            <p key='b'>b</p>
+            <p key='c'>c</p>
+            <p key='d'>d</p>
         </DraggerLayout>
     )
 }

+ 1 - 2
app/src/Dragger.js

@@ -232,7 +232,7 @@ export default class Dragger extends React.Component {
 
     componentWillReceiveProps(nextProps) {
         // console.log(nextProps)
-        const { isUserMove } = this.props
+        const { isUserMove } = nextProps
         if (!isUserMove) {
             if (typeof nextProps.x === 'number' &&
                 typeof nextProps.y === 'number') {
@@ -244,7 +244,6 @@ export default class Dragger extends React.Component {
                 })
             }
         }
-
     }
 
     render() {

+ 9 - 7
app/src/GridItem.js

@@ -90,29 +90,31 @@ export default class GridItem extends Component {
     }
 
     onDragStart(x, y) {
-        const { w, h, index } = this.props
+        const { w, h, UniqueKey } = this.props
         const { GridX, GridY } = this.calGridXY(x, y)
 
         this.props.onDragStart({
-            event, GridX, GridY, w, h, index
+            event, GridX, GridY, w, h, UniqueKey
         })
     }
     onDrag(event, x, y) {
         let { GridX, GridY } = this.calGridXY(x, y)
-        const { w, h, col } = this.props
-
-        this.props.onDrag({ GridX, GridY, w, h }, this.props.index)
+        const { w, h, col, UniqueKey } = this.props
+        this.props.onDrag({ GridX, GridY, w, h }, UniqueKey)
     }
 
     onDragEnd() {
-        if (this.props.onDragEnd) this.props.onDragEnd(this.props.index)
+        if (this.props.onDragEnd) this.props.onDragEnd(this.props.UniqueKey)
+    }
+
+    componentWillReceiveProps(nextProps) {
+        // console.log(nextProps.isUserMove,nextProps.GridX,nextProps.GridY)
     }
 
     render() {
         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={{