sense-react-timeline-editor 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/edit_area/edit_action.d.ts +1 -0
- package/dist/components/edit_area/edit_row.d.ts +2 -0
- package/dist/components/edit_area/hooks/use_row_drag.d.ts +88 -0
- package/dist/components/edit_area/hooks/use_row_selection.d.ts +16 -0
- package/dist/index.esm.js +762 -22
- package/dist/index.js +761 -21
- package/dist/interface/timeline.d.ts +8 -0
- package/package.json +7 -5
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ var React = require('react');
|
|
|
6
6
|
var reactVirtualized = require('react-virtualized');
|
|
7
7
|
var frameworkUtils = require('framework-utils');
|
|
8
8
|
var interact = require('interactjs');
|
|
9
|
+
var ahooks = require('ahooks');
|
|
10
|
+
var reactDragToSelect = require('@air/react-drag-to-select');
|
|
9
11
|
var es = require('antd/es');
|
|
10
12
|
var howler = require('howler');
|
|
11
13
|
var lodashEs = require('lodash-es');
|
|
@@ -162,6 +164,26 @@ function _objectSpread2(e) {
|
|
|
162
164
|
}
|
|
163
165
|
return e;
|
|
164
166
|
}
|
|
167
|
+
function _objectWithoutProperties(e, t) {
|
|
168
|
+
if (null == e) return {};
|
|
169
|
+
var o,
|
|
170
|
+
r,
|
|
171
|
+
i = _objectWithoutPropertiesLoose(e, t);
|
|
172
|
+
if (Object.getOwnPropertySymbols) {
|
|
173
|
+
var n = Object.getOwnPropertySymbols(e);
|
|
174
|
+
for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
|
175
|
+
}
|
|
176
|
+
return i;
|
|
177
|
+
}
|
|
178
|
+
function _objectWithoutPropertiesLoose(r, e) {
|
|
179
|
+
if (null == r) return {};
|
|
180
|
+
var t = {};
|
|
181
|
+
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
182
|
+
if (-1 !== e.indexOf(n)) continue;
|
|
183
|
+
t[n] = r[n];
|
|
184
|
+
}
|
|
185
|
+
return t;
|
|
186
|
+
}
|
|
165
187
|
function _possibleConstructorReturn(t, e) {
|
|
166
188
|
if (e && ("object" == typeof e || "function" == typeof e)) return e;
|
|
167
189
|
if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
|
|
@@ -2086,7 +2108,7 @@ var DragLines = function DragLines(_ref) {
|
|
|
2086
2108
|
}));
|
|
2087
2109
|
};
|
|
2088
2110
|
|
|
2089
|
-
var css_248z$2 = ".timeline-editor .ant-upload-wrapper .ant-upload-drag {\n border: none !important;\n background: none !important;\n}\n.timeline-editor:hover .timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n height: 4px;\n}\n.timeline-editor-edit-area {\n flex: 1 1 auto;\n margin-top: 10px;\n overflow: hidden;\n position: relative;\n}\n.timeline-editor-edit-area.no-flex {\n flex: 0 0 auto;\n}\n.timeline-editor-edit-area.overflow-hidden {\n overflow: hidden;\n}\n.timeline-editor-edit-area.overflow-hidden .ReactVirtualized__Grid {\n overflow: hidden !important;\n height: initial !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid {\n outline: none !important;\n overflow: overlay !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n width: 0;\n height: 0;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-track {\n background-color: transparent !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-thumb {\n background: #666;\n border-radius: 16px;\n}\n";
|
|
2111
|
+
var css_248z$2 = ".timeline-editor .ant-upload-wrapper .ant-upload-drag {\n border: none !important;\n background: none !important;\n}\n.timeline-editor:hover .timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n height: 4px;\n}\n.timeline-editor-edit-area {\n flex: 1 1 auto;\n margin-top: 10px;\n overflow: hidden;\n position: relative;\n}\n.timeline-editor-edit-area.no-flex {\n flex: 0 0 auto;\n}\n.timeline-editor-edit-area.overflow-hidden {\n overflow: hidden;\n}\n.timeline-editor-edit-area.overflow-hidden .ReactVirtualized__Grid {\n overflow: hidden !important;\n height: initial !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid {\n outline: none !important;\n overflow: overlay !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar {\n width: 0;\n height: 0;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-track {\n background-color: transparent !important;\n}\n.timeline-editor-edit-area .ReactVirtualized__Grid::-webkit-scrollbar-thumb {\n background: #666;\n border-radius: 16px;\n}\n.timeline-editor-selection-box {\n position: fixed;\n border: 2px solid #1890ff;\n background-color: rgba(24, 144, 255, 0.1);\n pointer-events: none;\n z-index: 9999;\n box-shadow: 0 0 8px rgba(24, 144, 255, 0.3);\n}\n";
|
|
2090
2112
|
styleInject(css_248z$2);
|
|
2091
2113
|
|
|
2092
2114
|
var css_248z$3 = ".timeline-editor-action {\n position: absolute;\n left: 0;\n top: 0;\n background-color: #c6cbd2;\n display: flex;\n align-items: center;\n}\n.timeline-editor-action .timeline-editor-action-left-stretch,\n.timeline-editor-action .timeline-editor-action-right-stretch {\n position: absolute;\n}\n.timeline-editor-action .timeline-editor-action-left-stretch {\n left: -3px;\n}\n.timeline-editor-action .timeline-editor-action-right-stretch {\n right: -3px;\n transform: rotate(180deg);\n}\n";
|
|
@@ -2094,6 +2116,7 @@ styleInject(css_248z$3);
|
|
|
2094
2116
|
|
|
2095
2117
|
var stretchIcon = "data:image/svg+xml,%3Csvg%20width%3D%227%22%20height%3D%2216%22%20viewBox%3D%220%200%207%2016%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M7%2015C7%2015.5523%206.55228%2016%206%2016L1%2016C0.447715%2016%201.06779e-08%2015.5523%202.38498e-08%2015L3.57746e-07%201C3.70918e-07%200.447715%200.447716%20-1.5627e-07%201%20-1.43099e-07L6%209.29825e-07C6.55229%209.42996e-07%207%200.447716%207%201L7%2015Z%22%20fill%3D%22%23226EFF%22%2F%3E%3Cpath%20d%3D%22M2%204L2%2012%22%20stroke%3D%22white%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M4%2012.25L5.5%208L4%203.75%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M4%2012.25L5.5%208L4%203.75L4%2012.25Z%22%20stroke%3D%22white%22%20stroke-width%3D%220.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E";
|
|
2096
2118
|
|
|
2119
|
+
var _excluded = ["left", "width", "top"];
|
|
2097
2120
|
var EditAction = function EditAction(_ref) {
|
|
2098
2121
|
var editorData = _ref.editorData,
|
|
2099
2122
|
row = _ref.row,
|
|
@@ -2231,7 +2254,8 @@ var EditAction = function EditAction(_ref) {
|
|
|
2231
2254
|
var handleDrag = function handleDrag(_ref2) {
|
|
2232
2255
|
var left = _ref2.left,
|
|
2233
2256
|
width = _ref2.width,
|
|
2234
|
-
top = _ref2.top
|
|
2257
|
+
top = _ref2.top,
|
|
2258
|
+
args = _objectWithoutProperties(_ref2, _excluded);
|
|
2235
2259
|
isDragWhenClick.current = true;
|
|
2236
2260
|
// 检查是否需要显示预览指示器
|
|
2237
2261
|
if (allowCreateTrack && setDropPreview && top !== undefined) {
|
|
@@ -2272,12 +2296,15 @@ var EditAction = function EditAction(_ref) {
|
|
|
2272
2296
|
}),
|
|
2273
2297
|
_start = _parserTransformToTim.start,
|
|
2274
2298
|
_end = _parserTransformToTim.end;
|
|
2275
|
-
var result = onActionMoving({
|
|
2299
|
+
var result = onActionMoving(_objectSpread2({
|
|
2276
2300
|
action: action,
|
|
2277
2301
|
row: row,
|
|
2278
2302
|
start: _start,
|
|
2279
|
-
end: _end
|
|
2280
|
-
|
|
2303
|
+
end: _end,
|
|
2304
|
+
left: left,
|
|
2305
|
+
width: width,
|
|
2306
|
+
top: top
|
|
2307
|
+
}, args));
|
|
2281
2308
|
if (result === false) return false;
|
|
2282
2309
|
}
|
|
2283
2310
|
if (isMounted.current) {
|
|
@@ -2289,11 +2316,12 @@ var EditAction = function EditAction(_ref) {
|
|
|
2289
2316
|
}
|
|
2290
2317
|
handleScaleCount(left, width);
|
|
2291
2318
|
};
|
|
2292
|
-
var
|
|
2319
|
+
var handleDragEndBase = React.useCallback(function (_ref3) {
|
|
2293
2320
|
var left = _ref3.left,
|
|
2294
2321
|
width = _ref3.width,
|
|
2295
2322
|
top = _ref3.top,
|
|
2296
2323
|
height = _ref3.height;
|
|
2324
|
+
console.log('handleDragEnd: ', left, width, top, height);
|
|
2297
2325
|
// 清理预览指示器
|
|
2298
2326
|
if (setDropPreview) {
|
|
2299
2327
|
setDropPreview(null);
|
|
@@ -2309,6 +2337,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2309
2337
|
}),
|
|
2310
2338
|
start = _parserTransformToTim2.start,
|
|
2311
2339
|
end = _parserTransformToTim2.end;
|
|
2340
|
+
console.log('handleDragEnd start, end : ', start, end);
|
|
2312
2341
|
// 检测目标row
|
|
2313
2342
|
var targetRowIndex = editorData.findIndex(function (item) {
|
|
2314
2343
|
return item.id === row.id;
|
|
@@ -2563,6 +2592,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2563
2592
|
// 更新action的时间
|
|
2564
2593
|
actionItem.start = start;
|
|
2565
2594
|
actionItem.end = end;
|
|
2595
|
+
console.log('handleDragEnd actionItem: ', targetRowItem, row);
|
|
2566
2596
|
// 如果拖拽到了不同的row,需要移动action
|
|
2567
2597
|
if (targetRowItem.id !== row.id) {
|
|
2568
2598
|
console.log('Moving action to different row');
|
|
@@ -2602,15 +2632,29 @@ var EditAction = function EditAction(_ref) {
|
|
|
2602
2632
|
setTransform(_objectSpread2(_objectSpread2({}, newTransform), {}, {
|
|
2603
2633
|
top: 0
|
|
2604
2634
|
}));
|
|
2635
|
+
var up = 0; // -1 向上移动,1 向下移动,0 不移动
|
|
2636
|
+
if (targetRowItem.id !== row.id) {
|
|
2637
|
+
up = top > 0 ? 1 : -1;
|
|
2638
|
+
}
|
|
2605
2639
|
// 执行回调
|
|
2606
2640
|
if (onActionMoveEnd) onActionMoveEnd({
|
|
2607
2641
|
action: actionItem,
|
|
2608
2642
|
row: targetRowItem,
|
|
2609
2643
|
start: start,
|
|
2610
2644
|
end: end,
|
|
2611
|
-
isNewRow: needCreateNewRow
|
|
2645
|
+
isNewRow: needCreateNewRow,
|
|
2646
|
+
left: left,
|
|
2647
|
+
width: width,
|
|
2648
|
+
top: top,
|
|
2649
|
+
height: height,
|
|
2650
|
+
up: up
|
|
2612
2651
|
});
|
|
2613
|
-
};
|
|
2652
|
+
}, [action, allowCreateTrack, editorData, id, onActionMoveEnd, parserTimeToTransform, parserTransformToTime, row, scale, scaleWidth, setDropPreview, setEditorData, startLeft]);
|
|
2653
|
+
// 防抖版本的 handleDragEnd
|
|
2654
|
+
var _useDebounceFn = ahooks.useDebounceFn(handleDragEndBase, {
|
|
2655
|
+
wait: 300
|
|
2656
|
+
}),
|
|
2657
|
+
handleDragEnd = _useDebounceFn.run;
|
|
2614
2658
|
var handleResizeStart = function handleResizeStart(dir) {
|
|
2615
2659
|
onActionResizeStart && onActionResizeStart({
|
|
2616
2660
|
action: action,
|
|
@@ -2670,6 +2714,8 @@ var EditAction = function EditAction(_ref) {
|
|
|
2670
2714
|
var action = rowItem.actions.find(function (item) {
|
|
2671
2715
|
return item.id === id;
|
|
2672
2716
|
});
|
|
2717
|
+
var originalStart = action.start;
|
|
2718
|
+
var originalEnd = action.end;
|
|
2673
2719
|
action.start = start;
|
|
2674
2720
|
action.end = end;
|
|
2675
2721
|
setEditorData(editorData);
|
|
@@ -2679,7 +2725,9 @@ var EditAction = function EditAction(_ref) {
|
|
|
2679
2725
|
row: row,
|
|
2680
2726
|
start: start,
|
|
2681
2727
|
end: end,
|
|
2682
|
-
dir: dir
|
|
2728
|
+
dir: dir,
|
|
2729
|
+
originalStart: originalStart,
|
|
2730
|
+
originalEnd: originalEnd
|
|
2683
2731
|
});
|
|
2684
2732
|
};
|
|
2685
2733
|
//#endregion
|
|
@@ -2700,6 +2748,29 @@ var EditAction = function EditAction(_ref) {
|
|
|
2700
2748
|
var currentRowIndex = editorData.findIndex(function (item) {
|
|
2701
2749
|
return item.id === row.id;
|
|
2702
2750
|
});
|
|
2751
|
+
React.useEffect(function () {
|
|
2752
|
+
var handleActionMoveEnd = function handleActionMoveEnd(e) {
|
|
2753
|
+
var _ref6 = e.detail || {},
|
|
2754
|
+
left = _ref6.left,
|
|
2755
|
+
width = _ref6.width,
|
|
2756
|
+
top = _ref6.top,
|
|
2757
|
+
height = _ref6.height,
|
|
2758
|
+
id = _ref6.id;
|
|
2759
|
+
console.log('handleActionMoveEnd: ', left, width, top, height, id);
|
|
2760
|
+
if (id === action.id) {
|
|
2761
|
+
handleDragEnd({
|
|
2762
|
+
left: left,
|
|
2763
|
+
width: width,
|
|
2764
|
+
top: top,
|
|
2765
|
+
height: height
|
|
2766
|
+
});
|
|
2767
|
+
}
|
|
2768
|
+
};
|
|
2769
|
+
window.addEventListener('action-move-end', handleActionMoveEnd);
|
|
2770
|
+
return function () {
|
|
2771
|
+
window.removeEventListener('action-move-end', handleActionMoveEnd);
|
|
2772
|
+
};
|
|
2773
|
+
}, [containerRef, handleDragEnd]);
|
|
2703
2774
|
return /*#__PURE__*/React__default['default'].createElement(RowDnd, {
|
|
2704
2775
|
ref: rowRnd,
|
|
2705
2776
|
parentRef: areaRef,
|
|
@@ -2733,6 +2804,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2733
2804
|
deltaScrollLeft: deltaScrollLeft,
|
|
2734
2805
|
deltaScrollTop: handleDeltaScrollTop
|
|
2735
2806
|
}, /*#__PURE__*/React__default['default'].createElement("div", {
|
|
2807
|
+
"data-action-id": action.id,
|
|
2736
2808
|
onMouseDown: function onMouseDown() {
|
|
2737
2809
|
isDragWhenClick.current = false;
|
|
2738
2810
|
},
|
|
@@ -2792,7 +2864,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2792
2864
|
}))));
|
|
2793
2865
|
};
|
|
2794
2866
|
|
|
2795
|
-
var css_248z$4 = ".timeline-editor-edit-row {\n background-repeat: no-repeat, repeat;\n display: flex;\n flex-direction: row;\n box-sizing: border-box;\n}\n.timeline-editor-edit-row.preview-row {\n background-color: rgba(100, 150, 255, 0.15);\n border: 1px dashed rgba(100, 150, 255, 0.5);\n opacity: 0.8;\n transition: all 0.2s ease;\n}\n";
|
|
2867
|
+
var css_248z$4 = ".timeline-editor-edit-row {\n background-repeat: no-repeat, repeat;\n display: flex;\n flex-direction: row;\n box-sizing: border-box;\n transition: background-color 0.15s ease, box-shadow 0.15s ease;\n}\n.timeline-editor-edit-row.preview-row {\n background-color: rgba(100, 150, 255, 0.15);\n border: 1px dashed rgba(100, 150, 255, 0.5);\n opacity: 0.8;\n transition: all 0.2s ease;\n}\n.timeline-editor-edit-row.selected {\n background-color: rgba(24, 144, 255, 0.08);\n box-shadow: inset 0 0 0 2px rgba(24, 144, 255, 0.4);\n position: relative;\n z-index: 10;\n}\n.timeline-editor-edit-row.selected::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background-color: #1890ff;\n}\n.timeline-editor-edit-row.dragging {\n opacity: 0.6;\n cursor: move;\n}\n";
|
|
2796
2868
|
styleInject(css_248z$4);
|
|
2797
2869
|
|
|
2798
2870
|
var EditRow = function EditRow(props) {
|
|
@@ -2808,9 +2880,11 @@ var EditRow = function EditRow(props) {
|
|
|
2808
2880
|
scale = props.scale,
|
|
2809
2881
|
scaleWidth = props.scaleWidth,
|
|
2810
2882
|
allowCreateTrack = props.allowCreateTrack,
|
|
2811
|
-
containerRef = props.containerRef
|
|
2883
|
+
containerRef = props.containerRef,
|
|
2884
|
+
_props$selectedAction = props.selectedActionIds,
|
|
2885
|
+
selectedActionIds = _props$selectedAction === void 0 ? [] : _props$selectedAction;
|
|
2812
2886
|
var classNames = ['edit-row'];
|
|
2813
|
-
if (rowData === null || rowData === void 0 ? void 0 : rowData.selected) classNames.push('
|
|
2887
|
+
if (rowData === null || rowData === void 0 ? void 0 : rowData.selected) classNames.push('selected');
|
|
2814
2888
|
var handleTime = function handleTime(e) {
|
|
2815
2889
|
if (!areaRef.current) return;
|
|
2816
2890
|
var rect = areaRef.current.getBoundingClientRect();
|
|
@@ -2826,6 +2900,8 @@ var EditRow = function EditRow(props) {
|
|
|
2826
2900
|
return /*#__PURE__*/React__default['default'].createElement("div", {
|
|
2827
2901
|
className: "".concat(prefix.apply(void 0, classNames), " ").concat(((rowData === null || rowData === void 0 ? void 0 : rowData.classNames) || []).join(' ')),
|
|
2828
2902
|
style: style,
|
|
2903
|
+
"data-row-id": rowData === null || rowData === void 0 ? void 0 : rowData.id,
|
|
2904
|
+
"data-y": "0",
|
|
2829
2905
|
onClick: function onClick(e) {
|
|
2830
2906
|
if (rowData && onClickRow) {
|
|
2831
2907
|
var time = handleTime(e);
|
|
@@ -2862,7 +2938,8 @@ var EditRow = function EditRow(props) {
|
|
|
2862
2938
|
action: action,
|
|
2863
2939
|
allowCreateTrack: allowCreateTrack,
|
|
2864
2940
|
setDropPreview: props.setDropPreview,
|
|
2865
|
-
containerRef: containerRef
|
|
2941
|
+
containerRef: containerRef,
|
|
2942
|
+
selectedActionIds: selectedActionIds
|
|
2866
2943
|
}));
|
|
2867
2944
|
}));
|
|
2868
2945
|
};
|
|
@@ -2973,16 +3050,570 @@ function useDragLine() {
|
|
|
2973
3050
|
};
|
|
2974
3051
|
}
|
|
2975
3052
|
|
|
3053
|
+
var useRowSelection = function useRowSelection(options) {
|
|
3054
|
+
var editorData = options.editorData,
|
|
3055
|
+
rowHeight = options.rowHeight,
|
|
3056
|
+
scrollTop = options.scrollTop,
|
|
3057
|
+
scrollLeft = options.scrollLeft,
|
|
3058
|
+
_onSelectionChange = options.onSelectionChange,
|
|
3059
|
+
_options$disabled = options.disabled,
|
|
3060
|
+
disabled = _options$disabled === void 0 ? false : _options$disabled,
|
|
3061
|
+
containerRef = options.containerRef;
|
|
3062
|
+
var _useState = React.useState(new Set()),
|
|
3063
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
3064
|
+
selectedActionIds = _useState2[0],
|
|
3065
|
+
setSelectedActionIds = _useState2[1];
|
|
3066
|
+
// 计算框选区域与 action 的交集
|
|
3067
|
+
var getIntersectedActions = React.useCallback(function (box) {
|
|
3068
|
+
var _containerRef$current, _containerRef$current2;
|
|
3069
|
+
var intersectedActionIds = [];
|
|
3070
|
+
// 直接从 container 获取滚动值
|
|
3071
|
+
var currentScrollLeft = ((_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.scrollLeft) || 0;
|
|
3072
|
+
var currentScrollTop = ((_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.scrollTop) || 0;
|
|
3073
|
+
// box 坐标是相对于可视区域的,需要减去滚动偏移量才能得到相对于 container 的坐标
|
|
3074
|
+
var boxTop = box.top - currentScrollTop;
|
|
3075
|
+
var boxBottom = boxTop + box.height;
|
|
3076
|
+
var boxLeft = box.left - currentScrollLeft;
|
|
3077
|
+
var boxRight = boxLeft + box.width;
|
|
3078
|
+
editorData.forEach(function (row) {
|
|
3079
|
+
// 检查框选区域是否与 action 相交
|
|
3080
|
+
row.actions.forEach(function (action) {
|
|
3081
|
+
var _containerRef$current3;
|
|
3082
|
+
var actionEl = (_containerRef$current3 = containerRef.current) === null || _containerRef$current3 === void 0 ? void 0 : _containerRef$current3.querySelector(".timeline-editor-action[data-action-id=\"".concat(action.id, "\"]"));
|
|
3083
|
+
if (actionEl) {
|
|
3084
|
+
var actionRect = actionEl.getBoundingClientRect();
|
|
3085
|
+
var actionLeft = actionRect.left;
|
|
3086
|
+
var actionTop = actionRect.top;
|
|
3087
|
+
var actionWidth = actionRect.width;
|
|
3088
|
+
var actionHeight = actionRect.height;
|
|
3089
|
+
var actionRight = actionLeft + actionWidth;
|
|
3090
|
+
var actionBottom = actionTop + actionHeight;
|
|
3091
|
+
// 检查框选区域是否与 action 相交
|
|
3092
|
+
var isActionIntersecting = boxLeft < actionRight && boxRight > actionLeft && boxTop < actionBottom && boxBottom > actionTop;
|
|
3093
|
+
if (isActionIntersecting) {
|
|
3094
|
+
intersectedActionIds.push(action.id);
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
});
|
|
3098
|
+
});
|
|
3099
|
+
return {
|
|
3100
|
+
actionIds: intersectedActionIds
|
|
3101
|
+
};
|
|
3102
|
+
}, [editorData, rowHeight, scrollTop, scrollLeft, containerRef]);
|
|
3103
|
+
// 使用 @air/react-drag-to-select 的框选功能
|
|
3104
|
+
var _useSelectionContaine = reactDragToSelect.useSelectionContainer({
|
|
3105
|
+
onSelectionChange: function onSelectionChange(box) {
|
|
3106
|
+
if (disabled) return;
|
|
3107
|
+
// 边界检查:确保框选区域有效
|
|
3108
|
+
if (!box || box.width < 5 || box.height < 5) {
|
|
3109
|
+
return;
|
|
3110
|
+
}
|
|
3111
|
+
var _getIntersectedAction = getIntersectedActions(box),
|
|
3112
|
+
actionIds = _getIntersectedAction.actionIds;
|
|
3113
|
+
var newSelectedActionIds = new Set(actionIds);
|
|
3114
|
+
// 只在选中状态变化时更新
|
|
3115
|
+
if (newSelectedActionIds.size !== selectedActionIds.size || !_toConsumableArray(newSelectedActionIds).every(function (id) {
|
|
3116
|
+
return selectedActionIds.has(id);
|
|
3117
|
+
})) {
|
|
3118
|
+
setSelectedActionIds(newSelectedActionIds);
|
|
3119
|
+
_onSelectionChange(actionIds);
|
|
3120
|
+
}
|
|
3121
|
+
},
|
|
3122
|
+
onSelectionStart: function onSelectionStart() {
|
|
3123
|
+
if (!disabled) {
|
|
3124
|
+
// 清除之前的选择
|
|
3125
|
+
setSelectedActionIds(new Set());
|
|
3126
|
+
_onSelectionChange([]);
|
|
3127
|
+
}
|
|
3128
|
+
},
|
|
3129
|
+
onSelectionEnd: function onSelectionEnd() {
|
|
3130
|
+
// 框选结束时的处理(可用于性能优化)
|
|
3131
|
+
},
|
|
3132
|
+
shouldStartSelecting: function shouldStartSelecting(target) {
|
|
3133
|
+
var _element$closest, _element$closest2, _element$closest3, _element$closest4;
|
|
3134
|
+
if (disabled) return false;
|
|
3135
|
+
// 不在 action 元素上启动框选
|
|
3136
|
+
var element = target;
|
|
3137
|
+
if (((_element$closest = element.closest) === null || _element$closest === void 0 ? void 0 : _element$closest.call(element, '.timeline-editor-action')) || ((_element$closest2 = element.closest) === null || _element$closest2 === void 0 ? void 0 : _element$closest2.call(element, '.timeline-editor-edit-action')) || ((_element$closest3 = element.closest) === null || _element$closest3 === void 0 ? void 0 : _element$closest3.call(element, '[data-draggable="true"]')) || ((_element$closest4 = element.closest) === null || _element$closest4 === void 0 ? void 0 : _element$closest4.call(element, '.timeline-editor-edit-row.dragging'))) {
|
|
3138
|
+
return false;
|
|
3139
|
+
}
|
|
3140
|
+
return true;
|
|
3141
|
+
},
|
|
3142
|
+
selectionProps: {
|
|
3143
|
+
className: 'timeline-editor-selection-box',
|
|
3144
|
+
style: {
|
|
3145
|
+
border: '2px solid #1890ff',
|
|
3146
|
+
backgroundColor: 'rgba(24, 144, 255, 0.1)',
|
|
3147
|
+
zIndex: 9999
|
|
3148
|
+
}
|
|
3149
|
+
},
|
|
3150
|
+
isEnabled: !disabled,
|
|
3151
|
+
eventsElement: containerRef === null || containerRef === void 0 ? void 0 : containerRef.current
|
|
3152
|
+
}),
|
|
3153
|
+
DragSelection = _useSelectionContaine.DragSelection;
|
|
3154
|
+
// 清除选择
|
|
3155
|
+
var clearSelection = React.useCallback(function () {
|
|
3156
|
+
setSelectedActionIds(new Set());
|
|
3157
|
+
_onSelectionChange([]);
|
|
3158
|
+
}, [_onSelectionChange]);
|
|
3159
|
+
// 点击空白区域取消选择
|
|
3160
|
+
React.useEffect(function () {
|
|
3161
|
+
if (disabled) return;
|
|
3162
|
+
var handleClickOutside = function handleClickOutside(e) {
|
|
3163
|
+
var target = e.target;
|
|
3164
|
+
// 如果点击的不是选中的 action 或框选框,清除选择
|
|
3165
|
+
if (!target.closest('.timeline-editor-selection-box') && !target.closest('.timeline-editor-action') && !target.closest('[data-draggable="true"]')) {
|
|
3166
|
+
clearSelection();
|
|
3167
|
+
}
|
|
3168
|
+
};
|
|
3169
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
3170
|
+
return function () {
|
|
3171
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
3172
|
+
};
|
|
3173
|
+
}, [disabled, clearSelection]);
|
|
3174
|
+
// 监听 Escape 键取消选择
|
|
3175
|
+
React.useEffect(function () {
|
|
3176
|
+
if (disabled) return;
|
|
3177
|
+
var handleKeyDown = function handleKeyDown(e) {
|
|
3178
|
+
if (e.key === 'Escape' && selectedActionIds.size > 0) {
|
|
3179
|
+
clearSelection();
|
|
3180
|
+
}
|
|
3181
|
+
};
|
|
3182
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
3183
|
+
return function () {
|
|
3184
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
3185
|
+
};
|
|
3186
|
+
}, [disabled, selectedActionIds.size, clearSelection]);
|
|
3187
|
+
return {
|
|
3188
|
+
DragSelection: DragSelection,
|
|
3189
|
+
selectedActionIds: Array.from(selectedActionIds),
|
|
3190
|
+
clearSelection: clearSelection
|
|
3191
|
+
};
|
|
3192
|
+
};
|
|
3193
|
+
|
|
3194
|
+
var useRowDrag = function useRowDrag(options) {
|
|
3195
|
+
var selectedActionIds = options.selectedActionIds,
|
|
3196
|
+
editorData = options.editorData,
|
|
3197
|
+
containerRef = options.containerRef,
|
|
3198
|
+
_options$scale = options.scale,
|
|
3199
|
+
scale = _options$scale === void 0 ? 1 : _options$scale,
|
|
3200
|
+
_options$scaleWidth = options.scaleWidth,
|
|
3201
|
+
scaleWidth = _options$scaleWidth === void 0 ? 160 : _options$scaleWidth,
|
|
3202
|
+
_options$startLeft = options.startLeft,
|
|
3203
|
+
startLeft = _options$startLeft === void 0 ? 20 : _options$startLeft,
|
|
3204
|
+
setEditorData = options.setEditorData;
|
|
3205
|
+
// 多选拖拽状态
|
|
3206
|
+
var multiDragState = React__default['default'].useRef({
|
|
3207
|
+
isMultiDrag: false,
|
|
3208
|
+
primaryActionId: null,
|
|
3209
|
+
initialPositions: new Map(),
|
|
3210
|
+
dragOffset: {
|
|
3211
|
+
dx: 0,
|
|
3212
|
+
dy: 0
|
|
3213
|
+
},
|
|
3214
|
+
startCursor: null,
|
|
3215
|
+
isDraggingSelection: false,
|
|
3216
|
+
start: 0,
|
|
3217
|
+
end: 0
|
|
3218
|
+
});
|
|
3219
|
+
// 获取选中的 action DOM 元素
|
|
3220
|
+
var getSelectedActionEls = React__default['default'].useCallback(function () {
|
|
3221
|
+
if (!(containerRef === null || containerRef === void 0 ? void 0 : containerRef.current)) return [];
|
|
3222
|
+
// 查找所有选中的 action 元素(action-selected 是选中状态的类名)
|
|
3223
|
+
var actions = containerRef.current.querySelectorAll('.timeline-editor-action-selected');
|
|
3224
|
+
return Array.from(actions);
|
|
3225
|
+
}, [containerRef]);
|
|
3226
|
+
var actionEls = getSelectedActionEls();
|
|
3227
|
+
// 存储所有选中 action 的当前预览位置
|
|
3228
|
+
var _React$useState = React__default['default'].useState(new Map()),
|
|
3229
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
3230
|
+
previewPositions = _React$useState2[0],
|
|
3231
|
+
setPreviewPositions = _React$useState2[1];
|
|
3232
|
+
// 拖拽开始
|
|
3233
|
+
var onDragStart = React__default['default'].useCallback(function (_ref) {
|
|
3234
|
+
var action = _ref.action,
|
|
3235
|
+
row = _ref.row;
|
|
3236
|
+
// 检查是否有多选
|
|
3237
|
+
if (selectedActionIds.length <= 1) {
|
|
3238
|
+
console.log('useRowDrag: 单选拖拽,不进行多选处理');
|
|
3239
|
+
return;
|
|
3240
|
+
}
|
|
3241
|
+
// 获取当前选中的元素
|
|
3242
|
+
var selectedEls = getSelectedActionEls();
|
|
3243
|
+
if (selectedEls.length <= 1) {
|
|
3244
|
+
console.log('useRowDrag: DOM元素不足,跳过');
|
|
3245
|
+
return;
|
|
3246
|
+
}
|
|
3247
|
+
// 记录每个选中元素的初始位置
|
|
3248
|
+
var initialElementPositions = new Map();
|
|
3249
|
+
selectedEls.forEach(function (el) {
|
|
3250
|
+
// 获取 action id
|
|
3251
|
+
var actionId = el.getAttribute('data-action-id');
|
|
3252
|
+
if (!actionId) return;
|
|
3253
|
+
// 获取当前 transform
|
|
3254
|
+
var style = window.getComputedStyle(el);
|
|
3255
|
+
var transform = style.transform;
|
|
3256
|
+
var x = 0,
|
|
3257
|
+
y = 0;
|
|
3258
|
+
if (transform && transform !== 'none') {
|
|
3259
|
+
// 解析 matrix
|
|
3260
|
+
var matrix = transform.match(/matrix\(([^)]+)\)/);
|
|
3261
|
+
if (matrix) {
|
|
3262
|
+
var values = matrix[1].split(', ');
|
|
3263
|
+
x = parseFloat(values[4]) || 0;
|
|
3264
|
+
y = parseFloat(values[5]) || 0;
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
// 存储初始位置
|
|
3268
|
+
initialElementPositions.set(actionId, {
|
|
3269
|
+
x: x,
|
|
3270
|
+
y: y
|
|
3271
|
+
});
|
|
3272
|
+
// 初始化 data 属性
|
|
3273
|
+
el.setAttribute('data-x', x.toString());
|
|
3274
|
+
el.setAttribute('data-y', y.toString());
|
|
3275
|
+
console.log('useRowDrag: 初始化元素位置', {
|
|
3276
|
+
actionId: actionId,
|
|
3277
|
+
x: x,
|
|
3278
|
+
y: y
|
|
3279
|
+
});
|
|
3280
|
+
});
|
|
3281
|
+
// 记录初始位置信息(用于计算时间偏移)
|
|
3282
|
+
var initialPositions = new Map();
|
|
3283
|
+
editorData.forEach(function (r) {
|
|
3284
|
+
r.actions.forEach(function (a) {
|
|
3285
|
+
if (selectedActionIds.includes(a.id)) {
|
|
3286
|
+
var transform = parserTimeToTransform({
|
|
3287
|
+
start: a.start,
|
|
3288
|
+
end: a.end
|
|
3289
|
+
}, {
|
|
3290
|
+
startLeft: startLeft,
|
|
3291
|
+
scale: scale,
|
|
3292
|
+
scaleWidth: scaleWidth
|
|
3293
|
+
});
|
|
3294
|
+
initialPositions.set(a.id, {
|
|
3295
|
+
rowId: r.id,
|
|
3296
|
+
start: a.start,
|
|
3297
|
+
end: a.end,
|
|
3298
|
+
left: transform.left,
|
|
3299
|
+
width: transform.width
|
|
3300
|
+
});
|
|
3301
|
+
}
|
|
3302
|
+
});
|
|
3303
|
+
});
|
|
3304
|
+
// 记录初始位置
|
|
3305
|
+
multiDragState.current = {
|
|
3306
|
+
isMultiDrag: true,
|
|
3307
|
+
initialPositions: initialPositions,
|
|
3308
|
+
dragOffset: {
|
|
3309
|
+
dx: 0,
|
|
3310
|
+
dy: 0
|
|
3311
|
+
},
|
|
3312
|
+
isDraggingSelection: true,
|
|
3313
|
+
primaryActionId: action.id,
|
|
3314
|
+
offsetX: 0,
|
|
3315
|
+
offsetY: 0,
|
|
3316
|
+
initialElementPositions: initialElementPositions,
|
|
3317
|
+
start: action.start,
|
|
3318
|
+
end: action.end
|
|
3319
|
+
};
|
|
3320
|
+
console.log('useRowDrag: 开始多选拖拽', {
|
|
3321
|
+
actionId: action.id,
|
|
3322
|
+
selectedCount: selectedActionIds.length,
|
|
3323
|
+
elementCount: selectedEls.length
|
|
3324
|
+
});
|
|
3325
|
+
}, [selectedActionIds, editorData, getSelectedActionEls, scale, scaleWidth, startLeft]);
|
|
3326
|
+
// 拖拽移动
|
|
3327
|
+
var onDragMove = React__default['default'].useCallback(function (params) {
|
|
3328
|
+
var actionId = params.actionId,
|
|
3329
|
+
dx = params.dx,
|
|
3330
|
+
dy = params.dy;
|
|
3331
|
+
var state = multiDragState.current;
|
|
3332
|
+
if (!state.isMultiDrag || !state.isDraggingSelection || !state.initialElementPositions) {
|
|
3333
|
+
return;
|
|
3334
|
+
}
|
|
3335
|
+
// 获取当前选中的元素
|
|
3336
|
+
var selectedEls = getSelectedActionEls();
|
|
3337
|
+
if (selectedEls.length === 0) return;
|
|
3338
|
+
// 更新偏移量
|
|
3339
|
+
state.offsetX = (state.offsetX || 0) + dx;
|
|
3340
|
+
state.offsetY = (state.offsetY || 0) + dy;
|
|
3341
|
+
// 遍历所有选中的元素,同步移动
|
|
3342
|
+
selectedEls.forEach(function (el) {
|
|
3343
|
+
var elActionId = el.getAttribute('data-action-id');
|
|
3344
|
+
if (!elActionId || elActionId === actionId) return;
|
|
3345
|
+
// 获取元素初始位置
|
|
3346
|
+
var initialPos = state.initialElementPositions.get(elActionId);
|
|
3347
|
+
if (!initialPos) return;
|
|
3348
|
+
// 计算新位置 = 初始位置 + 总偏移量
|
|
3349
|
+
var newX = initialPos.x + state.offsetX;
|
|
3350
|
+
var newY = initialPos.y + state.offsetY;
|
|
3351
|
+
// 更新元素位置
|
|
3352
|
+
el.style.transform = "translate(".concat(newX, "px, ").concat(newY, "px)");
|
|
3353
|
+
// 存储当前位置数据
|
|
3354
|
+
el.setAttribute('data-x', newX.toString());
|
|
3355
|
+
el.setAttribute('data-y', newY.toString());
|
|
3356
|
+
});
|
|
3357
|
+
console.log('useRowDrag: 拖拽移动', {
|
|
3358
|
+
actionId: actionId,
|
|
3359
|
+
dx: dx,
|
|
3360
|
+
dy: dy,
|
|
3361
|
+
offsetX: state.offsetX,
|
|
3362
|
+
offsetY: state.offsetY,
|
|
3363
|
+
elementCount: selectedEls.length
|
|
3364
|
+
});
|
|
3365
|
+
}, [getSelectedActionEls]);
|
|
3366
|
+
// 拖拽结束
|
|
3367
|
+
var onDragEnd = React__default['default'].useCallback(function (params) {
|
|
3368
|
+
var state = multiDragState.current;
|
|
3369
|
+
var _ref2 = params || {},
|
|
3370
|
+
up = _ref2.up;
|
|
3371
|
+
console.log('useRowDrag: 拖拽结束', params);
|
|
3372
|
+
// 清理 DOM 元素上的 data 属性
|
|
3373
|
+
var selectedEls = getSelectedActionEls();
|
|
3374
|
+
selectedEls.forEach(function (el) {
|
|
3375
|
+
el.removeAttribute('data-x');
|
|
3376
|
+
el.removeAttribute('data-y');
|
|
3377
|
+
// 清除 transform 样式
|
|
3378
|
+
el.style.transform = '';
|
|
3379
|
+
});
|
|
3380
|
+
if (!state.isMultiDrag || !params || (params === null || params === void 0 ? void 0 : params.actionId) !== state.primaryActionId) {
|
|
3381
|
+
// 清理状态
|
|
3382
|
+
multiDragState.current = {
|
|
3383
|
+
isMultiDrag: false,
|
|
3384
|
+
primaryActionId: null,
|
|
3385
|
+
initialPositions: new Map(),
|
|
3386
|
+
dragOffset: {
|
|
3387
|
+
dx: 0,
|
|
3388
|
+
dy: 0
|
|
3389
|
+
},
|
|
3390
|
+
startCursor: null,
|
|
3391
|
+
isDraggingSelection: false,
|
|
3392
|
+
start: 0,
|
|
3393
|
+
end: 0
|
|
3394
|
+
};
|
|
3395
|
+
setPreviewPositions(new Map());
|
|
3396
|
+
return;
|
|
3397
|
+
}
|
|
3398
|
+
var actionId = params.actionId,
|
|
3399
|
+
left = params.left,
|
|
3400
|
+
width = params.width,
|
|
3401
|
+
height = params.height,
|
|
3402
|
+
_params$dx = params.dx,
|
|
3403
|
+
_params$dy = params.dy;
|
|
3404
|
+
var top = params.top;
|
|
3405
|
+
var initialPositions = state.initialPositions,
|
|
3406
|
+
primaryActionId = state.primaryActionId,
|
|
3407
|
+
_state$offsetX = state.offsetX,
|
|
3408
|
+
offsetX = _state$offsetX === void 0 ? 0 : _state$offsetX,
|
|
3409
|
+
_state$offsetY = state.offsetY,
|
|
3410
|
+
offsetY = _state$offsetY === void 0 ? 0 : _state$offsetY;
|
|
3411
|
+
if (up === 0) {
|
|
3412
|
+
top = 0;
|
|
3413
|
+
} else if (up === 1) {
|
|
3414
|
+
top = -20;
|
|
3415
|
+
} else if (up === -1) {
|
|
3416
|
+
top = 20;
|
|
3417
|
+
}
|
|
3418
|
+
// 如果没有初始位置数据,说明不是有效的多选拖拽
|
|
3419
|
+
if (!setEditorData || initialPositions.size === 0) {
|
|
3420
|
+
// 清理状态
|
|
3421
|
+
multiDragState.current = {
|
|
3422
|
+
isMultiDrag: false,
|
|
3423
|
+
primaryActionId: null,
|
|
3424
|
+
initialPositions: new Map(),
|
|
3425
|
+
dragOffset: {
|
|
3426
|
+
dx: 0,
|
|
3427
|
+
dy: 0
|
|
3428
|
+
},
|
|
3429
|
+
startCursor: null,
|
|
3430
|
+
isDraggingSelection: false,
|
|
3431
|
+
start: 0,
|
|
3432
|
+
end: 0
|
|
3433
|
+
};
|
|
3434
|
+
setPreviewPositions(new Map());
|
|
3435
|
+
return;
|
|
3436
|
+
}
|
|
3437
|
+
// 计算主 action 的最终时间
|
|
3438
|
+
var primaryFinalTime = parserTransformToTime({
|
|
3439
|
+
left: left,
|
|
3440
|
+
width: width
|
|
3441
|
+
}, {
|
|
3442
|
+
startLeft: startLeft,
|
|
3443
|
+
scale: scale,
|
|
3444
|
+
scaleWidth: scaleWidth
|
|
3445
|
+
});
|
|
3446
|
+
// 计算主 action 的偏移量(时间)
|
|
3447
|
+
var primaryInitial = initialPositions.get(primaryActionId);
|
|
3448
|
+
if (!primaryInitial) {
|
|
3449
|
+
multiDragState.current = {
|
|
3450
|
+
isMultiDrag: false,
|
|
3451
|
+
primaryActionId: null,
|
|
3452
|
+
initialPositions: new Map(),
|
|
3453
|
+
dragOffset: {
|
|
3454
|
+
dx: 0,
|
|
3455
|
+
dy: 0
|
|
3456
|
+
},
|
|
3457
|
+
startCursor: null,
|
|
3458
|
+
isDraggingSelection: false,
|
|
3459
|
+
start: 0,
|
|
3460
|
+
end: 0
|
|
3461
|
+
};
|
|
3462
|
+
setPreviewPositions(new Map());
|
|
3463
|
+
return;
|
|
3464
|
+
}
|
|
3465
|
+
var timeOffset = primaryFinalTime.start - primaryInitial.start;
|
|
3466
|
+
console.log('useRowDrag: 拖拽结束', {
|
|
3467
|
+
actionId: actionId,
|
|
3468
|
+
primaryInitialStart: primaryInitial.start,
|
|
3469
|
+
primaryFinalStart: primaryFinalTime.start,
|
|
3470
|
+
timeOffset: timeOffset,
|
|
3471
|
+
selectedCount: initialPositions.size,
|
|
3472
|
+
offsetX: offsetX,
|
|
3473
|
+
offsetY: offsetY
|
|
3474
|
+
});
|
|
3475
|
+
// 如果时间偏移太小,不更新数据
|
|
3476
|
+
if (Math.abs(timeOffset) < 0.001) {
|
|
3477
|
+
console.log('useRowDrag: 偏移太小,跳过更新');
|
|
3478
|
+
multiDragState.current = {
|
|
3479
|
+
isMultiDrag: false,
|
|
3480
|
+
primaryActionId: null,
|
|
3481
|
+
initialPositions: new Map(),
|
|
3482
|
+
dragOffset: {
|
|
3483
|
+
dx: 0,
|
|
3484
|
+
dy: 0
|
|
3485
|
+
},
|
|
3486
|
+
startCursor: null,
|
|
3487
|
+
isDraggingSelection: false,
|
|
3488
|
+
start: 0,
|
|
3489
|
+
end: 0
|
|
3490
|
+
};
|
|
3491
|
+
setPreviewPositions(new Map());
|
|
3492
|
+
return;
|
|
3493
|
+
}
|
|
3494
|
+
// ------------------------------------------------------------
|
|
3495
|
+
var _multiDragState$curre = multiDragState.current,
|
|
3496
|
+
start = _multiDragState$curre.start,
|
|
3497
|
+
end = _multiDragState$curre.end,
|
|
3498
|
+
isMultiDrag = _multiDragState$curre.isMultiDrag;
|
|
3499
|
+
// 如果是多选拖拽,处理所有选中的 actions
|
|
3500
|
+
if (isMultiDrag) {
|
|
3501
|
+
// 计算当前 action 的偏移量
|
|
3502
|
+
var currentStart = parserTransformToTime({
|
|
3503
|
+
left: left,
|
|
3504
|
+
width: width
|
|
3505
|
+
}, {
|
|
3506
|
+
scaleWidth: scaleWidth,
|
|
3507
|
+
scale: scale,
|
|
3508
|
+
startLeft: startLeft
|
|
3509
|
+
}).start;
|
|
3510
|
+
var deltaTime = currentStart - start;
|
|
3511
|
+
console.log('Multi-drag ended, deltaTime:', deltaTime);
|
|
3512
|
+
// 更新所有选中的 actions 的最终位置
|
|
3513
|
+
var updatedData = editorData.map(function (r) {
|
|
3514
|
+
return _objectSpread2(_objectSpread2({}, r), {}, {
|
|
3515
|
+
actions: r.actions.map(function (a) {
|
|
3516
|
+
if (selectedActionIds.includes(a.id) && primaryActionId !== a.id) {
|
|
3517
|
+
var newStart = a.start + deltaTime;
|
|
3518
|
+
var newEnd = a.end + deltaTime;
|
|
3519
|
+
// 计算 left, width, top, height
|
|
3520
|
+
var _parserTimeToTransfor = parserTimeToTransform({
|
|
3521
|
+
start: newStart,
|
|
3522
|
+
end: newEnd
|
|
3523
|
+
}, {
|
|
3524
|
+
scaleWidth: scaleWidth,
|
|
3525
|
+
scale: scale,
|
|
3526
|
+
startLeft: startLeft
|
|
3527
|
+
}),
|
|
3528
|
+
_left = _parserTimeToTransfor.left,
|
|
3529
|
+
_width = _parserTimeToTransfor.width;
|
|
3530
|
+
setTimeout(function () {
|
|
3531
|
+
console.log('useRowDrag 1222: 拖拽结束', {
|
|
3532
|
+
left: _left,
|
|
3533
|
+
width: _width,
|
|
3534
|
+
top: top,
|
|
3535
|
+
height: height,
|
|
3536
|
+
id: a.id
|
|
3537
|
+
});
|
|
3538
|
+
window.dispatchEvent(new CustomEvent('action-move-end', {
|
|
3539
|
+
detail: {
|
|
3540
|
+
left: _left,
|
|
3541
|
+
width: _width,
|
|
3542
|
+
top: top,
|
|
3543
|
+
height: height,
|
|
3544
|
+
id: a.id
|
|
3545
|
+
}
|
|
3546
|
+
}));
|
|
3547
|
+
}, 0);
|
|
3548
|
+
return _objectSpread2(_objectSpread2({}, a), {}, {
|
|
3549
|
+
start: newStart,
|
|
3550
|
+
end: newEnd
|
|
3551
|
+
});
|
|
3552
|
+
}
|
|
3553
|
+
return a;
|
|
3554
|
+
})
|
|
3555
|
+
});
|
|
3556
|
+
});
|
|
3557
|
+
// setEditorData([...updatedData]);
|
|
3558
|
+
return;
|
|
3559
|
+
}
|
|
3560
|
+
// ------------------------------------------------------------
|
|
3561
|
+
// 清理状态
|
|
3562
|
+
multiDragState.current = {
|
|
3563
|
+
isMultiDrag: false,
|
|
3564
|
+
primaryActionId: null,
|
|
3565
|
+
initialPositions: new Map(),
|
|
3566
|
+
dragOffset: {
|
|
3567
|
+
dx: 0,
|
|
3568
|
+
dy: 0
|
|
3569
|
+
},
|
|
3570
|
+
startCursor: null,
|
|
3571
|
+
isDraggingSelection: false,
|
|
3572
|
+
start: 0,
|
|
3573
|
+
end: 0
|
|
3574
|
+
};
|
|
3575
|
+
setPreviewPositions(new Map());
|
|
3576
|
+
console.log('useRowDrag: 多选拖拽完成', {
|
|
3577
|
+
updatedCount: initialPositions.size
|
|
3578
|
+
});
|
|
3579
|
+
}, [editorData, setEditorData, scale, scaleWidth, startLeft, getSelectedActionEls, selectedActionIds]);
|
|
3580
|
+
// 获取指定 action 的预览位置
|
|
3581
|
+
var getPreviewPosition = React__default['default'].useCallback(function (actionId) {
|
|
3582
|
+
return previewPositions.get(actionId) || null;
|
|
3583
|
+
}, [previewPositions]);
|
|
3584
|
+
// 检查是否是多选拖拽模式
|
|
3585
|
+
var isMultiDragging = React__default['default'].useCallback(function () {
|
|
3586
|
+
return multiDragState.current.isMultiDrag;
|
|
3587
|
+
}, []);
|
|
3588
|
+
// 获取当前拖拽状态
|
|
3589
|
+
var getMultiDragState = React__default['default'].useCallback(function () {
|
|
3590
|
+
return multiDragState.current;
|
|
3591
|
+
}, []);
|
|
3592
|
+
return {
|
|
3593
|
+
onDragStart: onDragStart,
|
|
3594
|
+
onDragMove: onDragMove,
|
|
3595
|
+
onDragEnd: onDragEnd,
|
|
3596
|
+
getPreviewPosition: getPreviewPosition,
|
|
3597
|
+
isMultiDragging: isMultiDragging,
|
|
3598
|
+
getMultiDragState: getMultiDragState,
|
|
3599
|
+
isMultiDrag: multiDragState.current.isMultiDrag
|
|
3600
|
+
};
|
|
3601
|
+
};
|
|
3602
|
+
|
|
2976
3603
|
// 获取音频时长
|
|
2977
3604
|
var getAudioDuration = function getAudioDuration(url) {
|
|
2978
3605
|
return new Promise(function (resolve) {
|
|
2979
3606
|
var sound = new howler.Howl({
|
|
2980
|
-
src:
|
|
3607
|
+
src: url
|
|
2981
3608
|
});
|
|
2982
3609
|
sound.on('load', function () {
|
|
2983
3610
|
resolve(sound.duration());
|
|
2984
3611
|
sound.unload();
|
|
2985
3612
|
});
|
|
3613
|
+
setTimeout(function () {
|
|
3614
|
+
resolve(2); // 加载失败时返回默认时长2秒
|
|
3615
|
+
sound.unload();
|
|
3616
|
+
}, 6 * 1000); // 60秒超时 60 * 1000
|
|
2986
3617
|
sound.on('loaderror', function () {
|
|
2987
3618
|
resolve(2); // 加载失败时返回默认时长2秒
|
|
2988
3619
|
sound.unload();
|
|
@@ -3031,6 +3662,7 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3031
3662
|
var handleUploadChange = function handleUploadChange(row) {
|
|
3032
3663
|
return /*#__PURE__*/function () {
|
|
3033
3664
|
var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(info) {
|
|
3665
|
+
var _info$file$response;
|
|
3034
3666
|
var uid, duration, newAction;
|
|
3035
3667
|
return _regenerator().w(function (_context) {
|
|
3036
3668
|
while (1) switch (_context.n) {
|
|
@@ -3048,7 +3680,7 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3048
3680
|
case 2:
|
|
3049
3681
|
duration = _context.v;
|
|
3050
3682
|
newAction = {
|
|
3051
|
-
id: uid,
|
|
3683
|
+
id: ((_info$file$response = info.file.response) === null || _info$file$response === void 0 ? void 0 : _info$file$response.id) || uid,
|
|
3052
3684
|
effectId: 'custom_video_effect',
|
|
3053
3685
|
flexible: true,
|
|
3054
3686
|
url: info.file.response.url,
|
|
@@ -3085,6 +3717,63 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3085
3717
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
3086
3718
|
dropPreview = _useState4[0],
|
|
3087
3719
|
setDropPreview = _useState4[1];
|
|
3720
|
+
var _useState5 = React.useState(null),
|
|
3721
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
3722
|
+
dragIndicator = _useState6[0],
|
|
3723
|
+
setDragIndicator = _useState6[1];
|
|
3724
|
+
// 框选功能
|
|
3725
|
+
var _useRowSelection = useRowSelection({
|
|
3726
|
+
editorData: editorData,
|
|
3727
|
+
rowHeight: _rowHeight,
|
|
3728
|
+
scrollTop: scrollTop,
|
|
3729
|
+
scrollLeft: scrollLeft,
|
|
3730
|
+
onSelectionChange: function onSelectionChange(selectedActionIds) {
|
|
3731
|
+
// 更新 editorData 中每个 action 的选中状态
|
|
3732
|
+
var updatedData = editorData.map(function (row) {
|
|
3733
|
+
return _objectSpread2(_objectSpread2({}, row), {}, {
|
|
3734
|
+
actions: row.actions.map(function (action) {
|
|
3735
|
+
return _objectSpread2(_objectSpread2({}, action), {}, {
|
|
3736
|
+
selected: selectedActionIds.includes(action.id)
|
|
3737
|
+
});
|
|
3738
|
+
})
|
|
3739
|
+
});
|
|
3740
|
+
});
|
|
3741
|
+
setEditorData(updatedData);
|
|
3742
|
+
},
|
|
3743
|
+
disabled: false,
|
|
3744
|
+
containerRef: editAreaRef
|
|
3745
|
+
}),
|
|
3746
|
+
DragSelection = _useRowSelection.DragSelection,
|
|
3747
|
+
selectedActionIds = _useRowSelection.selectedActionIds;
|
|
3748
|
+
var _useRowDrag = useRowDrag({
|
|
3749
|
+
selectedActionIds: selectedActionIds,
|
|
3750
|
+
editorData: editorData,
|
|
3751
|
+
containerRef: editAreaRef,
|
|
3752
|
+
scale: scale,
|
|
3753
|
+
scaleWidth: scaleWidth,
|
|
3754
|
+
startLeft: startLeft,
|
|
3755
|
+
setEditorData: setEditorData,
|
|
3756
|
+
allowCreateTrack: allowCreateTrack,
|
|
3757
|
+
rowHeight: _rowHeight
|
|
3758
|
+
}),
|
|
3759
|
+
onDragStart = _useRowDrag.onDragStart,
|
|
3760
|
+
onDragMove = _useRowDrag.onDragMove,
|
|
3761
|
+
onDragEnd = _useRowDrag.onDragEnd;
|
|
3762
|
+
// 监听拖拽位置指示器事件
|
|
3763
|
+
React.useEffect(function () {
|
|
3764
|
+
var handleDragMove = function handleDragMove(e) {
|
|
3765
|
+
setDragIndicator(e.detail);
|
|
3766
|
+
};
|
|
3767
|
+
var handleDragEnd = function handleDragEnd() {
|
|
3768
|
+
setDragIndicator(null);
|
|
3769
|
+
};
|
|
3770
|
+
window.addEventListener('row-drag-move', handleDragMove);
|
|
3771
|
+
window.addEventListener('row-drag-end', handleDragEnd);
|
|
3772
|
+
return function () {
|
|
3773
|
+
window.removeEventListener('row-drag-move', handleDragMove);
|
|
3774
|
+
window.removeEventListener('row-drag-end', handleDragEnd);
|
|
3775
|
+
};
|
|
3776
|
+
}, []);
|
|
3088
3777
|
// 处理拖拽上传事件
|
|
3089
3778
|
var handleDrop = function handleDrop(e) {
|
|
3090
3779
|
e.preventDefault();
|
|
@@ -3169,8 +3858,13 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3169
3858
|
allowCreateTrack: allowCreateTrack,
|
|
3170
3859
|
setDropPreview: setDropPreview,
|
|
3171
3860
|
containerRef: containerRef,
|
|
3861
|
+
selectedActionIds: selectedActionIds,
|
|
3172
3862
|
onActionMoveStart: function onActionMoveStart(data) {
|
|
3173
3863
|
handleInitDragLine(data);
|
|
3864
|
+
onDragStart({
|
|
3865
|
+
action: data.action,
|
|
3866
|
+
row: data.row
|
|
3867
|
+
});
|
|
3174
3868
|
return _onActionMoveStart && _onActionMoveStart(data);
|
|
3175
3869
|
},
|
|
3176
3870
|
onActionResizeStart: function onActionResizeStart(data) {
|
|
@@ -3179,6 +3873,20 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3179
3873
|
},
|
|
3180
3874
|
onActionMoving: function onActionMoving(data) {
|
|
3181
3875
|
handleUpdateDragLine(data);
|
|
3876
|
+
// 传递拖拽参数给多选拖拽处理
|
|
3877
|
+
onDragMove({
|
|
3878
|
+
actionId: data.action.id,
|
|
3879
|
+
left: data.left,
|
|
3880
|
+
width: data.width,
|
|
3881
|
+
top: data.top || 0,
|
|
3882
|
+
height: data.height || 0,
|
|
3883
|
+
dx: (data.left || 0) - (data.lastLeft || 0),
|
|
3884
|
+
dy: (data.top || 0) - (data.lastTop || 0),
|
|
3885
|
+
lastLeft: data.lastLeft,
|
|
3886
|
+
lastWidth: data.lastWidth,
|
|
3887
|
+
lastTop: data.lastTop,
|
|
3888
|
+
lastHeight: data.lastHeight
|
|
3889
|
+
});
|
|
3182
3890
|
return _onActionMoving && _onActionMoving(data);
|
|
3183
3891
|
},
|
|
3184
3892
|
onActionResizing: function onActionResizing(data) {
|
|
@@ -3191,13 +3899,22 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3191
3899
|
},
|
|
3192
3900
|
onActionMoveEnd: function onActionMoveEnd(data) {
|
|
3193
3901
|
disposeDragLine();
|
|
3902
|
+
// 传递拖拽结束参数给多选拖拽处理
|
|
3903
|
+
onDragEnd({
|
|
3904
|
+
actionId: data.action.id,
|
|
3905
|
+
left: data.left || 0,
|
|
3906
|
+
width: data.width || 0,
|
|
3907
|
+
top: data.top || 0,
|
|
3908
|
+
height: data.height || 0,
|
|
3909
|
+
up: data.up || 0
|
|
3910
|
+
});
|
|
3194
3911
|
return _onActionMoveEnd && _onActionMoveEnd(data);
|
|
3195
3912
|
}
|
|
3196
3913
|
}));
|
|
3197
|
-
if (canUpload || (row === null || row === void 0 ? void 0 : row.canUpload)) {
|
|
3914
|
+
if (!!row && (canUpload || (row === null || row === void 0 ? void 0 : row.canUpload))) {
|
|
3198
3915
|
return /*#__PURE__*/React__default['default'].createElement(es.Upload, {
|
|
3199
3916
|
ref: uploadRef,
|
|
3200
|
-
key: key,
|
|
3917
|
+
key: key + 'upload',
|
|
3201
3918
|
style: _objectSpread2(_objectSpread2({
|
|
3202
3919
|
width: '100%',
|
|
3203
3920
|
display: 'block'
|
|
@@ -3233,7 +3950,9 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3233
3950
|
className: prefix('edit-area') + " ".concat((className || '').replace('timeline-editor', '') || ''),
|
|
3234
3951
|
style: {
|
|
3235
3952
|
height: isMulti ? _totalHeight : 'unset',
|
|
3236
|
-
maxHeight: isMulti ? _totalHeight : 'unset'
|
|
3953
|
+
maxHeight: isMulti ? _totalHeight : 'unset',
|
|
3954
|
+
width: isMulti ? Math.max(scaleCount * scaleWidth + startLeft, 0) : 'unset',
|
|
3955
|
+
minWidth: isMulti ? '100%' : 'unset'
|
|
3237
3956
|
}
|
|
3238
3957
|
}, /*#__PURE__*/React__default['default'].createElement(reactVirtualized.AutoSizer, {
|
|
3239
3958
|
style: {
|
|
@@ -3280,9 +3999,30 @@ var EditArea = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3280
3999
|
_onScroll(param);
|
|
3281
4000
|
}
|
|
3282
4001
|
});
|
|
3283
|
-
}), dragLine && /*#__PURE__*/React__default['default'].createElement(DragLines, _objectSpread2({
|
|
4002
|
+
}), /*#__PURE__*/React__default['default'].createElement(DragSelection, null), dragLine && /*#__PURE__*/React__default['default'].createElement(DragLines, _objectSpread2({
|
|
3284
4003
|
scrollLeft: scrollLeft
|
|
3285
|
-
}, dragLineData)),
|
|
4004
|
+
}, dragLineData)), dragIndicator && function () {
|
|
4005
|
+
// 计算拖拽位置指示器的位置
|
|
4006
|
+
var top = 0;
|
|
4007
|
+
var targetIndex = dragIndicator.targetIndex;
|
|
4008
|
+
for (var i = 0; i < Math.min(targetIndex, editorData.length); i++) {
|
|
4009
|
+
top += editorData[i].rowHeight || _rowHeight;
|
|
4010
|
+
}
|
|
4011
|
+
return /*#__PURE__*/React__default['default'].createElement("div", {
|
|
4012
|
+
style: {
|
|
4013
|
+
position: 'absolute',
|
|
4014
|
+
left: 0,
|
|
4015
|
+
right: 0,
|
|
4016
|
+
top: top - scrollTop + 16,
|
|
4017
|
+
height: '3px',
|
|
4018
|
+
backgroundColor: '#1890ff',
|
|
4019
|
+
boxShadow: '0 0 8px rgba(24, 144, 255, 0.6)',
|
|
4020
|
+
zIndex: 1001,
|
|
4021
|
+
pointerEvents: 'none',
|
|
4022
|
+
transition: 'top 0.05s ease-out'
|
|
4023
|
+
}
|
|
4024
|
+
});
|
|
4025
|
+
}(), dropPreview && function () {
|
|
3286
4026
|
// 计算预览指示器的位置
|
|
3287
4027
|
var top = 0;
|
|
3288
4028
|
for (var i = 0; i < editorData.length; i++) {
|
|
@@ -3676,7 +4416,7 @@ var Timeline = /*#__PURE__*/React__default['default'].forwardRef(function (props
|
|
|
3676
4416
|
key: key,
|
|
3677
4417
|
isMulti: areaCount > 1
|
|
3678
4418
|
}, checkedProps), {}, {
|
|
3679
|
-
className: index !== 0 ? "no-flex ".concat(key, " ").concat(index) : "overflow-hidden ".concat(key, " ").concat(index),
|
|
4419
|
+
className: index !== 0 ? "no-flex ".concat(key, " ").concat(index, " overflow-hidden") : "overflow-hidden ".concat(key, " ").concat(index),
|
|
3680
4420
|
timelineWidth: width,
|
|
3681
4421
|
ref: function ref(_ref4) {
|
|
3682
4422
|
return areaRef.current = _ref4 === null || _ref4 === void 0 ? void 0 : _ref4.domRef.current;
|