114 |
118 | defaultLayout.containerHeight
123 | ? containerHeight
124 | : defaultLayout.containerHeight
125 | }}
126 | >
127 | {this.createCards(cards, id, groups)}
128 |
129 |
130 |
131 | );
132 | }
133 | }
134 | function collectTarget(connect, monitor) {
135 | return {
136 | connectDropTarget: connect.dropTarget(),
137 | isOver: monitor.isOver()
138 | }
139 | }
140 | const Container = DropTarget('item', groupItemTarget, collectTarget)(Demo);
141 | export default Container;
142 |
--------------------------------------------------------------------------------
/src/components/layout.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import HTML5Backend from 'react-dnd-html5-backend';
3 | import { DragDropContext } from 'react-dnd';
4 | import _ from 'lodash';
5 | //自定义组件
6 | import { layoutCheck } from '../utils/collision';
7 | import { compactLayout, compactLayoutHorizontal } from '../utils/compact';
8 | import utils from '../utils';
9 | import GroupItem from './groupItem';
10 | import CustomDragLayer from './dragLayer';
11 | import PropTypes from 'prop-types'
12 | import styles from '../styles.module.css';
13 |
14 | let resizeWaiter = false;
15 |
16 | class MyContent extends Component {
17 | constructor(props) {
18 | super(props);
19 | this.state = {
20 | defaultLayout: {
21 | containerWidth: 1200,
22 | containerHeight: 300,
23 | calWidth: 175,
24 | rowHeight: 175,
25 | col: 6,
26 | margin: [10, 10],
27 | containerPadding: [0, 0]
28 | },
29 | layout: props.layout,
30 | shadowCard: {},
31 | groups: props.groups
32 | };
33 | }
34 | componentWillUnmount() {
35 | window.removeEventListener('resize', this.handleLoad);
36 | }
37 | componentDidMount() {
38 | window.addEventListener('resize', this.handleLoad);
39 | }
40 | // 当页面加载完成,获得卡片容器宽度,并自动排列卡片
41 | handleLoad = () => {
42 | if (!resizeWaiter) {
43 | resizeWaiter = true;
44 | setTimeout(() => {
45 | console.info('resize!');
46 | resizeWaiter = false;
47 | let clientWidth;
48 | const containerDom = document.querySelector('#card-container');
49 | if (containerDom) {
50 | clientWidth = containerDom.clientWidth;
51 | } else {
52 | const firstAddButton = document.querySelector('#first-add');
53 | if (firstAddButton) {
54 | clientWidth = firstAddButton.clientWidth - 10;
55 | } else {
56 | return;
57 | }
58 | }
59 | const defaultCalWidth = this.state.defaultLayout.calWidth;
60 | const { containerPadding, margin } = this.state.layout;
61 | let layout = _.cloneDeep(this.state.layout);
62 | const windowWidth = window.innerWidth - 60 * 2;
63 | const col = utils.calColCount(defaultCalWidth, windowWidth, containerPadding, margin);
64 | const calWidth = utils.calColWidth(clientWidth, col, containerPadding, margin);
65 |
66 | let { groups } = this.state;
67 | groups = _.cloneDeep(groups);
68 | _.forEach(groups, (g) => {
69 | let compactedLayout = compactLayoutHorizontal(g.cards, col);
70 | g.cards = compactedLayout;
71 | });
72 |
73 | layout.calWidth = layout.rowHeight = calWidth;
74 | layout.col = col;
75 | layout.containerWidth = clientWidth;
76 | this.updateGroupList(groups);
77 | this.updateLayout(layout);
78 | }, 500);
79 | }
80 | }
81 | /*
82 | * 关于卡片在组内的操作
83 | */
84 | /**
85 | * 拖拽中卡片在组上移动
86 | * @param {Object} dragItem 拖拽中的对象
87 | * @param {Object} hoverItem 拖拽中鼠标悬浮的对象
88 | * @param {Number} x 当前元素所在的网页的x轴位置,单位为px
89 | * @param {Number} y 当前元素所在的网页的y轴位置,单位为px
90 | **/
91 | moveCardInGroupItem = (dragItem, hoverItem, x, y) => {
92 | let groups = this.state.groups;
93 | let shadowCard = this.state.shadowCard;
94 | const { margin, containerWidth, col, rowHeight } = this.state.layout;
95 | //计算当前所在的网格坐标
96 | const { gridX, gridY } = utils.calGridXY(x, y, shadowCard.width, margin, containerWidth, col, rowHeight);
97 | if (gridX === shadowCard.gridx && gridY === shadowCard.gridy) {
98 | return;
99 | }
100 | let groupIndex = hoverItem.index;
101 | //先判断组内是否存在相同的卡片
102 | // const cardid = shadowCard.id;
103 | // const isContain = utils.checkCardContainInGroup(groups[groupIndex], cardid);
104 | // if (isContain) {
105 | // return;
106 | // }
107 |
108 | //删除阴影的卡片
109 | _.forEach(groups, (g, index) => {
110 | _.remove(g.cards, (a) => {
111 | return a.isShadow === true;
112 | });
113 | });
114 |
115 | shadowCard = { ...shadowCard, gridx: gridX, gridy: gridY };
116 | //添加阴影的卡片
117 | groups[groupIndex].cards.push(shadowCard);
118 | //获得当前分组内最新的layout布局
119 | const newlayout = layoutCheck(
120 | groups[groupIndex].cards,
121 | shadowCard,
122 | shadowCard.id,
123 | shadowCard.id,
124 | this.props.compactType
125 | );
126 | //压缩当前分组内的layout布局
127 | let compactedLayout;
128 | if (this.props.compactType === 'horizontal') {
129 | compactedLayout = compactLayoutHorizontal(newlayout, this.state.layout.col, shadowCard.id);
130 | } else if (this.props.compactType === 'vertical') {
131 | compactedLayout = compactLayout(newlayout, shadowCard);
132 | }
133 | //更新group对象
134 | groups[groupIndex].cards = compactedLayout;
135 | this.updateShadowCard(shadowCard);
136 | this.updateGroupList(groups);
137 | };
138 | /**
139 | * 释放卡片到分组
140 | * @param {Object} dragItem 拖拽的卡片对象
141 | * @param {Object} dropItem 释放的目标组对象
142 | **/
143 | onCardDropInGroupItem = (dragItem, dropItem) => {
144 | let { groups } = this.state;
145 | groups = _.cloneDeep(groups);
146 | //将所有分组内的阴影卡片设为非阴影
147 | utils.setPropertyValueForCards(groups, 'isShadow', false);
148 | //目标组内重新横向压缩布局,由于跨组,故须全部压缩
149 | _.forEach(groups, (g, i) => {
150 | if (this.props.compactType === 'horizontal') {
151 | let compactedLayout = compactLayoutHorizontal(groups[i].cards, this.state.layout.col);
152 | g.cards = compactedLayout;
153 | } else if (this.props.compactType === 'vertical') {
154 | let compactedLayout = compactLayout(groups[i].cards);
155 | g.cards = compactedLayout;
156 | }
157 |
158 | });
159 | this.updateGroupList(groups);
160 | this.updateShadowCard({});
161 | };
162 | //初始化组
163 | initGroupItem(groups) {
164 | console.log(groups,'groups')
165 | let itemDoms = [];
166 | itemDoms = groups.map((g, i) => {
167 | return (
168 |