dragact.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import * as React from "react";
  2. import GridItem from './GridItem';
  3. import { compactLayout } from './util/compact';
  4. import { getMaxContainerHeight } from './util/sort';
  5. import { layoutCheck } from './util/collison';
  6. import { correctLayout } from './util/correction';
  7. import { getDataSet, stringJoin } from './utils';
  8. import { layoutItemForkey, syncLayout, MapLayoutTostate } from './util/initiate';
  9. import './style.css';
  10. export class Dragact extends React.Component {
  11. constructor(props) {
  12. super(props);
  13. this.onDrag = this.onDrag.bind(this);
  14. this.onDragStart = this.onDragStart.bind(this);
  15. this.onDragEnd = this.onDragEnd.bind(this);
  16. const layout = props.layout ?
  17. MapLayoutTostate(props.layout, props.children)
  18. :
  19. getDataSet(props.children);
  20. this.state = {
  21. GridXMoving: 0,
  22. GridYMoving: 0,
  23. wMoving: 0,
  24. hMoving: 0,
  25. placeholderShow: false,
  26. placeholderMoving: false,
  27. layout: layout,
  28. containerHeight: 500
  29. };
  30. }
  31. onDragStart(bundles) {
  32. const { GridX, GridY, w, h, UniqueKey } = bundles;
  33. const newlayout = syncLayout(this.state.layout, UniqueKey, GridX, GridY, true);
  34. this.setState({
  35. GridXMoving: GridX,
  36. GridYMoving: GridY,
  37. wMoving: w,
  38. hMoving: h,
  39. placeholderShow: true,
  40. placeholderMoving: true,
  41. layout: newlayout,
  42. });
  43. this.props.onDragStart && this.props.onDragStart(bundles);
  44. }
  45. onDrag(layoutItem) {
  46. const { GridY, UniqueKey } = layoutItem;
  47. const moving = GridY - this.state.GridYMoving;
  48. const newLayout = layoutCheck(this.state.layout, layoutItem, UniqueKey, UniqueKey /*用户移动方块的key */, moving);
  49. const compactedLayout = compactLayout(newLayout);
  50. for (let i = 0; i < compactedLayout.length; i++) {
  51. const compactedItem = compactedLayout[i];
  52. if (UniqueKey === compactedItem.key) {
  53. /**
  54. * 特殊点:当我们移动元素的时候,元素在layout中的位置不断改变
  55. * 但是当isUserMove=true的时候,鼠标拖拽的元素不会随着位图变化而变化
  56. * 但是实际layout中的位置还是会改变
  57. * (isUserMove=true用于解除placeholder和元素的绑定)
  58. */
  59. compactedItem.isUserMove = true;
  60. layoutItem.GridX = compactedItem.GridX;
  61. layoutItem.GridY = compactedItem.GridY;
  62. break;
  63. }
  64. }
  65. this.setState({
  66. GridXMoving: layoutItem.GridX,
  67. GridYMoving: layoutItem.GridY,
  68. layout: compactedLayout,
  69. containerHeight: getMaxContainerHeight(compactedLayout, this.props.rowHeight, this.props.margin[1])
  70. });
  71. this.props.onDrag && this.props.onDrag(layoutItem);
  72. }
  73. onDragEnd(key) {
  74. const compactedLayout = compactLayout(this.state.layout);
  75. this.setState({
  76. placeholderShow: false,
  77. layout: compactedLayout,
  78. containerHeight: getMaxContainerHeight(compactedLayout, this.props.rowHeight, this.props.margin[1])
  79. });
  80. this.props.onDragEnd && this.props.onDragEnd(key);
  81. }
  82. renderPlaceholder() {
  83. if (!this.state.placeholderShow)
  84. return null;
  85. var { col, width, padding, rowHeight, margin } = this.props;
  86. const { GridXMoving, GridYMoving, wMoving, hMoving, placeholderMoving } = this.state;
  87. if (!padding)
  88. padding = 0;
  89. return (React.createElement(GridItem, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, GridX: GridXMoving, GridY: GridYMoving, w: wMoving, h: hMoving, style: { background: '#d6e4ff', zIndex: 1, transition: ' all .15s' }, isUserMove: !placeholderMoving }));
  90. }
  91. componentDidMount() {
  92. setTimeout(() => {
  93. let layout = correctLayout(this.state.layout, this.props.col);
  94. const compacted = compactLayout(layout);
  95. this.setState({
  96. layout: compacted,
  97. containerHeight: getMaxContainerHeight(compacted, this.props.rowHeight, this.props.margin[1])
  98. });
  99. }, 1);
  100. }
  101. getGridItem(child, index) {
  102. const { layout } = this.state;
  103. var { col, width, padding, rowHeight, margin } = this.props;
  104. const renderItem = layoutItemForkey(layout, child.key); //TODO:可以优化速度,这一步不是必须;
  105. if (renderItem) {
  106. if (!padding)
  107. padding = 0;
  108. return (React.createElement(GridItem, { margin: margin, col: col, containerWidth: width, containerPadding: [padding, padding], rowHeight: rowHeight, GridX: renderItem.GridX, GridY: renderItem.GridY, w: renderItem.w, h: renderItem.h, onDrag: this.onDrag, onDragStart: this.onDragStart, onDragEnd: this.onDragEnd, isUserMove: renderItem.isUserMove !== void 666 ? renderItem.isUserMove : false, UniqueKey: child.key, style: { zIndex: 2 }, static: renderItem.static }, child));
  109. }
  110. }
  111. render() {
  112. const { width, className } = this.props;
  113. const { containerHeight } = this.state;
  114. return (React.createElement("div", { className: stringJoin('DraggerLayout', className + ''), style: { left: 100, width: width, height: containerHeight, zIndex: 1 } },
  115. React.Children.map(this.props.children, (child, index) => this.getGridItem(child, index)),
  116. this.renderPlaceholder()));
  117. }
  118. }