Explorar o código

v0.1.3

- 新增组件api:```getLayout```,用于获取当前的layout.
- 新增组件的resize
Z F %!s(int64=7) %!d(string=hai) anos
pai
achega
4a3b8b58aa

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
build/react-dragger-layout.js


+ 3 - 2
example/changelog.md

@@ -1,3 +1,4 @@
-v0.1.1
+v0.1.3
 
-- 新增组件api:```getLayout```,用于获取当前的layout.
+- 新增组件api:```getLayout```,用于获取当前的layout.
+- 新增组件的resize

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "dragact",
-  "version": "0.1.2",
+  "version": "0.1.3",
   "description": "",
   "main": "index.js",
   "scripts": {

+ 1 - 1
src/LayoutRestore/index.tsx

@@ -79,7 +79,7 @@ export class LayoutRestore extends React.Component<{}, {}> {
         return (
             <div style={{ display: 'flex', justifyContent: 'center' }}>
                 <div>
-                    <h1 style={{ textAlign: 'center' }}>Normal Layout Demo</h1>
+                    <h1 style={{ textAlign: 'center' }}>Layout Restore Demo</h1>
                     {this.renderDragact()}
                 </div>
             </div>

+ 1 - 0
src/index.tsx

@@ -45,6 +45,7 @@ class DemoDispatcher extends React.Component<{}, {}> {
 }
 
 
+
 ReactDOM.render(
     <DemoDispatcher />,
     document.getElementById('root')

+ 62 - 4
src/lib/dragact.tsx

@@ -89,7 +89,8 @@ interface DragactState {
     placeholderShow: Boolean,
     placeholderMoving: Boolean,
     layout: DragactLayoutItem[],
-    containerHeight: number
+    containerHeight: number,
+    dragType: 'drag' | 'resize'
 }
 
 export class Dragact extends React.Component<DragactProps, DragactState> {
@@ -113,11 +114,62 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
             placeholderShow: false,
             placeholderMoving: false,
             layout: layout,
-            containerHeight: 500
+            containerHeight: 500,
+            dragType: 'drag'
         }
     }
+    onResizeStart = (layoutItem: GridItemEvent) => {
+        const { GridX, GridY, w, h, UniqueKey } = layoutItem
+        const sync = syncLayout(this.state.layout, UniqueKey, GridX, GridY, true);
+        this.setState({
+            GridXMoving: GridX,
+            GridYMoving: GridY,
+            wMoving: w,
+            hMoving: h,
+            placeholderShow: true,
+            placeholderMoving: true,
+            layout: sync,
+            dragType: 'resize'
+        })
+    }
+
+    onResizing = (layoutItem: GridItemEvent) => {
+
+        const newLayout = layoutCheck(this.state.layout, layoutItem, layoutItem.UniqueKey, layoutItem.UniqueKey, 0);
+
+        const compacted = compactLayout(newLayout)
+
+        for (let i = 0; i < compacted.length; i++) {
+            const compactedItem = compacted[i];
+            if (layoutItem.UniqueKey === compactedItem.key) {
+                /**
+                 * 特殊点:当我们移动元素的时候,元素在layout中的位置不断改变
+                 * 但是当isUserMove=true的时候,鼠标拖拽的元素不会随着位图变化而变化
+                 * 但是实际layout中的位置还是会改变
+                 * (isUserMove=true用于解除placeholder和元素的绑定)
+                 */
+                compactedItem.isUserMove = true
+                break
+            }
+        }
 
+        this.setState({
+            layout: compacted,
+            wMoving: layoutItem.w,
+            hMoving: layoutItem.h,
+            containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1])
+        })
+    }
 
+    onResizeEnd = (layoutItem: GridItemEvent) => {
+        const compactedLayout = compactLayout(this.state.layout)
+        this.setState({
+            placeholderShow: false,
+            layout: compactedLayout,
+            containerHeight: getMaxContainerHeight(compactedLayout, this.props.rowHeight, this.props.margin[1])
+        })
+        this.props.onDragEnd && this.props.onDragEnd(layoutItem);
+    }
 
     onDragStart(bundles: GridItemEvent) {
         const { GridX, GridY, w, h, UniqueKey } = bundles
@@ -132,6 +184,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
             placeholderShow: true,
             placeholderMoving: true,
             layout: newlayout,
+            dragType: 'drag'
         })
         this.props.onDragStart && this.props.onDragStart(bundles)
     }
@@ -168,7 +221,9 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
     }
 
     onDragEnd(layoutItem: GridItemEvent) {
+
         const compactedLayout = compactLayout(this.state.layout)
+
         this.setState({
             placeholderShow: false,
             layout: compactedLayout,
@@ -180,7 +235,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
     renderPlaceholder() {
         if (!this.state.placeholderShow) return null
         var { col, width, padding, rowHeight, margin } = this.props
-        const { GridXMoving, GridYMoving, wMoving, hMoving, placeholderMoving } = this.state
+        const { GridXMoving, GridYMoving, wMoving, hMoving, placeholderMoving, dragType } = this.state
 
         if (!padding) padding = 0;
         return (
@@ -194,7 +249,7 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                 GridY={GridYMoving}
                 w={wMoving}
                 h={hMoving}
-                style={{ background: '#d6e4ff', zIndex: 1, transition: ' all .15s' }}
+                style={{ background: 'rgba(15,15,15,0.3)', zIndex: dragType === 'drag' ? 1 : 10, transition: ' all .15s' }}
                 isUserMove={!placeholderMoving}
             />
         )
@@ -234,6 +289,9 @@ export class Dragact extends React.Component<DragactProps, DragactState> {
                     UniqueKey={child.key}
                     style={{ zIndex: 2 }}
                     static={renderItem.static}
+                    onResizing={this.onResizing}
+                    onResizeStart={this.onResizeStart}
+                    onResizeEnd={this.onResizeEnd}
                 >
                     {child}
                 </GridItem >

+ 105 - 14
src/lib/dragger/index.tsx

@@ -1,6 +1,6 @@
 import * as React from "react";
 import { int, innerHeight, innerWidth, outerHeight, outerWidth, parseBounds, Bound } from '../utils'
-/// <reference path="react.d.ts" />
+
 
 const doc = document
 
@@ -50,7 +50,14 @@ interface DraggerProps {
     onMove?: (event: MouseEvent | TouchEvent, x: number, y: number) => void,
     onDragEnd?: (event: MouseEvent | TouchEvent, x: number, y: number) => void,
 
-    style?: React.CSSProperties
+    onResizeStart?: (event: any, x: number, y: number) => void,
+    onResizing?: (event: MouseEvent | TouchEvent, x: number, y: number) => void
+    onResizeEnd?: (event: MouseEvent | TouchEvent, x: number, y: number) => void
+
+    style?: React.CSSProperties,
+
+    w?: number,
+    h?: number
 }
 
 export class Dragger extends React.Component<DraggerProps, {}> {
@@ -91,7 +98,13 @@ export class Dragger extends React.Component<DraggerProps, {}> {
         lastY: 0,
 
         /**堆叠的层级 */
-        zIndex: 1
+        zIndex: 1,
+
+        w: 0,
+        h: 0,
+
+        lastW: 0,
+        lastH: 0
     }
 
 
@@ -253,6 +266,59 @@ export class Dragger extends React.Component<DraggerProps, {}> {
         this.props.onDragEnd && this.props.onDragEnd(event, this.state.x, this.state.y)
     }
 
+    onResizeStart = (event: React.MouseEvent<HTMLSpanElement>) => {
+        /** 保证用户在移动元素的时候不会选择到元素内部的东西 */
+        doc.body.style.userSelect = 'none';
+
+        doc.addEventListener('mouseup', this.onResizeEnd);
+        doc.addEventListener('mousemove', this.onResizing);
+
+        let originX, originY;
+        originX = event.clientX
+        originY = event.clientY
+
+        this.props.onResizeStart && this.props.onResizeStart(event, this.state.w, this.state.h);
+
+        this.setState({
+            originX: originX,
+            originY: originY,
+            zIndex: 10,
+            lastW: this.state.w,
+            lastH: this.state.h
+        })
+        event.stopPropagation();
+    }
+    onResizing = (event: any) => {
+        /*  event.client - this.state.origin 表示的是移动的距离,
+        *   elX表示的是原来已经有的位移
+        */
+
+        let deltaX, deltaY;
+        if (event.type.indexOf('mouse') >= 0) {
+            deltaX = (event as MouseEvent).clientX - this.state.originX
+            deltaY = (event as MouseEvent).clientY - this.state.originY
+        } else {
+            deltaX = (event as TouchEvent).touches[0].clientX - this.state.originX
+            deltaY = (event as TouchEvent).touches[0].clientY - this.state.originY
+        }
+        /**移动时回调,用于外部控制 */
+
+        this.props.onResizing && this.props.onResizing(event, this.state.w, this.state.h);
+
+        this.setState({
+            w: deltaX + this.state.lastW,
+            h: deltaY + this.state.lastH
+        })
+
+    }
+    onResizeEnd = (event: any) => {
+        doc.body.style.userSelect = '';
+        doc.removeEventListener('mousemove', this.onResizing)
+        doc.removeEventListener('mouseup', this.onResizeEnd)
+
+        this.props.onResizeEnd && this.props.onResizeEnd(event, this.state.w, this.state.h);
+    }
+
     componentDidMount() {
         /** 
          * 这个函数只会调用一次 
@@ -275,43 +341,68 @@ export class Dragger extends React.Component<DraggerProps, {}> {
          */
         const { isUserMove } = nextProps
         if (!isUserMove) {
+
             if (typeof nextProps.x === 'number' &&
                 typeof nextProps.y === 'number') {
                 this.setState({
                     x: nextProps.x,
                     y: nextProps.y,
                     lastX: nextProps.x,
-                    lastY: nextProps.y
+                    lastY: nextProps.y,
+                    w: nextProps.w,
+                    h: nextProps.h
                 })
             }
         }
     }
 
     render() {
-        let { x, y, zIndex } = this.state
-        const { style, className } = this.props
-
+        var { x, y, w, h } = this.state
+        var { style, className } = this.props
         if (!this.props.isUserMove) {
             /**当外部设置其props的x,y初始属性的时候,我们在这里设置元素的初始位移 */
-            x = this.props.x ? this.props.x : 0
-            y = this.props.y ? this.props.y : 0
+            x = this.props.x ? this.props.x : 0;
+            y = this.props.y ? this.props.y : 0;
+            if (style) {
+                w = style.width ? style.width : w;
+                h = style.height ? style.height : h;
+            }
         }
+        if (style) {
+            w = w === 0 ? style.width : w;
+            h = h === 0 ? style.height : h;
+        }
+
 
         /**主要是为了让用户定义自己的className去修改css */
         const fixedClassName = typeof className === 'undefined' ? '' : className + ' '
         return (
             <div className={`${fixedClassName}WrapDragger`}
-                style={{ ...style, zIndex: zIndex, touchAction: 'none!important', transform: `translate(${x}px,${y}px)` }}
+                style={{
+                    ...style,
+                    touchAction: 'none!important',
+                    transform: `translate(${x}px,${y}px)`,
+                    width: w,
+                    height: h
+                }}
                 onMouseDown={this.onDragStart.bind(this)}
                 onTouchStart={this.onDragStart.bind(this)}
                 onTouchEnd={this.onDragEnd.bind(this)}
                 onMouseUp={this.onDragEnd.bind(this)}
             >
-                {/**
-             *
-             *  React.Children.only 只允许子元素有一个根节点
-             */}
                 {React.Children.only(this.props.children)}
+                <span
+                    onMouseDown={this.onResizeStart}
+                    // onTouchStart={this.onDragStart.bind(this)}
+                    // onTouchEnd={this.onDragEnd.bind(this)}
+                    onMouseUp={this.onResizeEnd}
+                    style={{
+                        position: 'absolute',
+                        width: 10, height: 10, right: 2, bottom: 2, cursor: 'se-resize',
+                        borderRight: '2px solid rgba(15,15,15,0.2)',
+                        borderBottom: '2px solid rgba(15,15,15,0.2)'
+                    }}
+                />
             </div>
         )
     }

+ 58 - 6
src/lib/gridItem.tsx

@@ -1,7 +1,7 @@
 import * as React from "react";
 import { Dragger } from './dragger/index'
 import { checkInContainer } from './util/correction';
-import { Bound } from './utils'
+import { Bound } from './utils';
 
 
 export interface GridItemProps {
@@ -25,6 +25,10 @@ export interface GridItemProps {
     onDragEnd?: (event: GridItemEvent) => void,
     onDrag?: (event: GridItemEvent) => void
 
+    onResizeStart?: (event: GridItemEvent) => void
+    onResizing?: (event: GridItemEvent) => void
+    onResizeEnd?: (event: GridItemEvent) => void
+
     isUserMove: Boolean
 
     UniqueKey?: string | number
@@ -46,6 +50,20 @@ export interface GridItemEvent {
 }
 
 
+const checkWidthHeight = (w: number, h: number, col: number) => {
+    var newW = w;
+    var newH = h;
+    if (w > col) {
+        newW = col;
+    }
+    if(w<1)newW=1;
+    if(h<1)newH=1;
+    return {
+        w:newW,h:newH
+    }
+
+}
+
 export default class GridItem extends React.Component<GridItemProps, {}> {
     constructor(props: GridItemProps) {
         super(props)
@@ -111,7 +129,9 @@ export default class GridItem extends React.Component<GridItemProps, {}> {
 
         return this.props.GridX !== props.GridX ||
             this.props.GridY !== props.GridY ||
-            this.props.isUserMove !== props.isUserMove
+            this.props.isUserMove !== props.isUserMove ||
+            this.props.w !== props.w ||
+            this.props.h !== props.h
     }
 
     /**宽和高计算成为px */
@@ -125,6 +145,16 @@ export default class GridItem extends React.Component<GridItemProps, {}> {
         return { wPx, hPx }
     }
 
+    calPxToWH(wPx: number, hPx: number) {
+        const calWidth = this.calColWidth();
+
+        const w = Math.round((wPx-calWidth*0.5) / calWidth)
+        const h = Math.round((hPx-this.props.rowHeight*0.8) / this.props.rowHeight)
+        console.log(h);
+
+        return checkWidthHeight(w,h,this.props.col)
+    }
+
     onDragStart(x: number, y: number) {
         const { w, h, UniqueKey } = this.props;
         if (this.props.static) return;
@@ -149,29 +179,51 @@ export default class GridItem extends React.Component<GridItemProps, {}> {
         if (this.props.onDragEnd) this.props.onDragEnd({ GridX, GridY, w, h, UniqueKey: UniqueKey + '', event });
     }
 
+    onResizeStart = (event: any, wPx: number, hPx: number) => {
+        const { GridX, GridY, UniqueKey,w,h } = this.props;
+        this.props.onResizeStart && this.props.onResizeStart({ GridX, GridY, w, h, UniqueKey: UniqueKey + '', event })
+    }
+
+    onResizing = (event: any, wPx: number, hPx: number) => {
+        var { w, h } = this.calPxToWH(wPx, hPx);
+
+        const { GridX, GridY, UniqueKey } = this.props;
+        this.props.onResizing && this.props.onResizing({ GridX, GridY, w, h, UniqueKey: UniqueKey + '', event })
+    }
+
+    onResizeEnd = (event: any, wPx: number, hPx: number) => {
+        var { w, h } = this.calPxToWH(wPx, hPx);
+        const { GridX, GridY, UniqueKey } = this.props;
+
+        this.props.onResizeEnd && this.props.onResizeEnd({ GridX, GridY, w, h, UniqueKey: UniqueKey + '', event })
+    }
+
     render() {
 
         const { w, h, style, bounds, GridX, GridY } = this.props
         const { x, y } = this.calGridItemPosition(GridX, GridY)
         const { wPx, hPx } = this.calWHtoPx(w, h);
-
-
         return (
+
             <Dragger
                 style={{
                     ...style, width: wPx, height: hPx, position: 'absolute',
                     transition: this.props.isUserMove ? '' : 'all .2s'
                 }}
-
                 onDragStart={this.onDragStart}
                 onMove={this.onDrag}
                 onDragEnd={this.onDragEnd}
+                onResizeStart={this.onResizeStart}
+                onResizing={this.onResizing}
+                onResizeEnd={this.onResizeEnd}
                 x={x}
                 y={y}
+                w={wPx}
+                h={hPx}
                 isUserMove={this.props.isUserMove}
                 bounds={bounds}
             >
-                <div style={{ width: wPx, height: hPx }}>
+                <div style={{ height: '100%', width: "100%" }}>
                     {React.Children.map(this.props.children, (child) => child)}
                 </div>
             </Dragger>

+ 1 - 1
src/lib/util/collison.ts

@@ -87,7 +87,7 @@ export const layoutCheck = (layout: DragactLayoutItem[], layoutItem: GridItemEve
         } else if (fristItemkey === key) {
 
             /**永远保持用户移动的块是 isUserMove === true */
-            return { ...item, GridX: layoutItem.GridX, GridY: layoutItem.GridY, isUserMove: true }
+            return { ...item, GridX: layoutItem.GridX, GridY: layoutItem.GridY, isUserMove: true, w: layoutItem.w, h: layoutItem.h }
         }
 
         return item

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio