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.esm.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import React, { useRef, useEffect, cloneElement, useImperativeHandle, useState, useLayoutEffect } from 'react';
|
|
1
|
+
import React, { useRef, useEffect, cloneElement, useImperativeHandle, useState, useLayoutEffect, useCallback } from 'react';
|
|
2
2
|
import { AutoSizer, Grid, ScrollSync } from 'react-virtualized';
|
|
3
3
|
import { prefixNames } from 'framework-utils';
|
|
4
4
|
import interact from 'interactjs';
|
|
5
|
+
import { useDebounceFn } from 'ahooks';
|
|
6
|
+
import { useSelectionContainer } from '@air/react-drag-to-select';
|
|
5
7
|
import { Upload, message } from 'antd/es';
|
|
6
8
|
import { Howl } from 'howler';
|
|
7
9
|
import { groupBy } from 'lodash-es';
|
|
@@ -153,6 +155,26 @@ function _objectSpread2(e) {
|
|
|
153
155
|
}
|
|
154
156
|
return e;
|
|
155
157
|
}
|
|
158
|
+
function _objectWithoutProperties(e, t) {
|
|
159
|
+
if (null == e) return {};
|
|
160
|
+
var o,
|
|
161
|
+
r,
|
|
162
|
+
i = _objectWithoutPropertiesLoose(e, t);
|
|
163
|
+
if (Object.getOwnPropertySymbols) {
|
|
164
|
+
var n = Object.getOwnPropertySymbols(e);
|
|
165
|
+
for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
|
166
|
+
}
|
|
167
|
+
return i;
|
|
168
|
+
}
|
|
169
|
+
function _objectWithoutPropertiesLoose(r, e) {
|
|
170
|
+
if (null == r) return {};
|
|
171
|
+
var t = {};
|
|
172
|
+
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
173
|
+
if (-1 !== e.indexOf(n)) continue;
|
|
174
|
+
t[n] = r[n];
|
|
175
|
+
}
|
|
176
|
+
return t;
|
|
177
|
+
}
|
|
156
178
|
function _possibleConstructorReturn(t, e) {
|
|
157
179
|
if (e && ("object" == typeof e || "function" == typeof e)) return e;
|
|
158
180
|
if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
|
|
@@ -2077,7 +2099,7 @@ var DragLines = function DragLines(_ref) {
|
|
|
2077
2099
|
}));
|
|
2078
2100
|
};
|
|
2079
2101
|
|
|
2080
|
-
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";
|
|
2102
|
+
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";
|
|
2081
2103
|
styleInject(css_248z$2);
|
|
2082
2104
|
|
|
2083
2105
|
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";
|
|
@@ -2085,6 +2107,7 @@ styleInject(css_248z$3);
|
|
|
2085
2107
|
|
|
2086
2108
|
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";
|
|
2087
2109
|
|
|
2110
|
+
var _excluded = ["left", "width", "top"];
|
|
2088
2111
|
var EditAction = function EditAction(_ref) {
|
|
2089
2112
|
var editorData = _ref.editorData,
|
|
2090
2113
|
row = _ref.row,
|
|
@@ -2222,7 +2245,8 @@ var EditAction = function EditAction(_ref) {
|
|
|
2222
2245
|
var handleDrag = function handleDrag(_ref2) {
|
|
2223
2246
|
var left = _ref2.left,
|
|
2224
2247
|
width = _ref2.width,
|
|
2225
|
-
top = _ref2.top
|
|
2248
|
+
top = _ref2.top,
|
|
2249
|
+
args = _objectWithoutProperties(_ref2, _excluded);
|
|
2226
2250
|
isDragWhenClick.current = true;
|
|
2227
2251
|
// 检查是否需要显示预览指示器
|
|
2228
2252
|
if (allowCreateTrack && setDropPreview && top !== undefined) {
|
|
@@ -2263,12 +2287,15 @@ var EditAction = function EditAction(_ref) {
|
|
|
2263
2287
|
}),
|
|
2264
2288
|
_start = _parserTransformToTim.start,
|
|
2265
2289
|
_end = _parserTransformToTim.end;
|
|
2266
|
-
var result = onActionMoving({
|
|
2290
|
+
var result = onActionMoving(_objectSpread2({
|
|
2267
2291
|
action: action,
|
|
2268
2292
|
row: row,
|
|
2269
2293
|
start: _start,
|
|
2270
|
-
end: _end
|
|
2271
|
-
|
|
2294
|
+
end: _end,
|
|
2295
|
+
left: left,
|
|
2296
|
+
width: width,
|
|
2297
|
+
top: top
|
|
2298
|
+
}, args));
|
|
2272
2299
|
if (result === false) return false;
|
|
2273
2300
|
}
|
|
2274
2301
|
if (isMounted.current) {
|
|
@@ -2280,11 +2307,12 @@ var EditAction = function EditAction(_ref) {
|
|
|
2280
2307
|
}
|
|
2281
2308
|
handleScaleCount(left, width);
|
|
2282
2309
|
};
|
|
2283
|
-
var
|
|
2310
|
+
var handleDragEndBase = useCallback(function (_ref3) {
|
|
2284
2311
|
var left = _ref3.left,
|
|
2285
2312
|
width = _ref3.width,
|
|
2286
2313
|
top = _ref3.top,
|
|
2287
2314
|
height = _ref3.height;
|
|
2315
|
+
console.log('handleDragEnd: ', left, width, top, height);
|
|
2288
2316
|
// 清理预览指示器
|
|
2289
2317
|
if (setDropPreview) {
|
|
2290
2318
|
setDropPreview(null);
|
|
@@ -2300,6 +2328,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2300
2328
|
}),
|
|
2301
2329
|
start = _parserTransformToTim2.start,
|
|
2302
2330
|
end = _parserTransformToTim2.end;
|
|
2331
|
+
console.log('handleDragEnd start, end : ', start, end);
|
|
2303
2332
|
// 检测目标row
|
|
2304
2333
|
var targetRowIndex = editorData.findIndex(function (item) {
|
|
2305
2334
|
return item.id === row.id;
|
|
@@ -2554,6 +2583,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2554
2583
|
// 更新action的时间
|
|
2555
2584
|
actionItem.start = start;
|
|
2556
2585
|
actionItem.end = end;
|
|
2586
|
+
console.log('handleDragEnd actionItem: ', targetRowItem, row);
|
|
2557
2587
|
// 如果拖拽到了不同的row,需要移动action
|
|
2558
2588
|
if (targetRowItem.id !== row.id) {
|
|
2559
2589
|
console.log('Moving action to different row');
|
|
@@ -2593,15 +2623,29 @@ var EditAction = function EditAction(_ref) {
|
|
|
2593
2623
|
setTransform(_objectSpread2(_objectSpread2({}, newTransform), {}, {
|
|
2594
2624
|
top: 0
|
|
2595
2625
|
}));
|
|
2626
|
+
var up = 0; // -1 向上移动,1 向下移动,0 不移动
|
|
2627
|
+
if (targetRowItem.id !== row.id) {
|
|
2628
|
+
up = top > 0 ? 1 : -1;
|
|
2629
|
+
}
|
|
2596
2630
|
// 执行回调
|
|
2597
2631
|
if (onActionMoveEnd) onActionMoveEnd({
|
|
2598
2632
|
action: actionItem,
|
|
2599
2633
|
row: targetRowItem,
|
|
2600
2634
|
start: start,
|
|
2601
2635
|
end: end,
|
|
2602
|
-
isNewRow: needCreateNewRow
|
|
2636
|
+
isNewRow: needCreateNewRow,
|
|
2637
|
+
left: left,
|
|
2638
|
+
width: width,
|
|
2639
|
+
top: top,
|
|
2640
|
+
height: height,
|
|
2641
|
+
up: up
|
|
2603
2642
|
});
|
|
2604
|
-
};
|
|
2643
|
+
}, [action, allowCreateTrack, editorData, id, onActionMoveEnd, parserTimeToTransform, parserTransformToTime, row, scale, scaleWidth, setDropPreview, setEditorData, startLeft]);
|
|
2644
|
+
// 防抖版本的 handleDragEnd
|
|
2645
|
+
var _useDebounceFn = useDebounceFn(handleDragEndBase, {
|
|
2646
|
+
wait: 300
|
|
2647
|
+
}),
|
|
2648
|
+
handleDragEnd = _useDebounceFn.run;
|
|
2605
2649
|
var handleResizeStart = function handleResizeStart(dir) {
|
|
2606
2650
|
onActionResizeStart && onActionResizeStart({
|
|
2607
2651
|
action: action,
|
|
@@ -2661,6 +2705,8 @@ var EditAction = function EditAction(_ref) {
|
|
|
2661
2705
|
var action = rowItem.actions.find(function (item) {
|
|
2662
2706
|
return item.id === id;
|
|
2663
2707
|
});
|
|
2708
|
+
var originalStart = action.start;
|
|
2709
|
+
var originalEnd = action.end;
|
|
2664
2710
|
action.start = start;
|
|
2665
2711
|
action.end = end;
|
|
2666
2712
|
setEditorData(editorData);
|
|
@@ -2670,7 +2716,9 @@ var EditAction = function EditAction(_ref) {
|
|
|
2670
2716
|
row: row,
|
|
2671
2717
|
start: start,
|
|
2672
2718
|
end: end,
|
|
2673
|
-
dir: dir
|
|
2719
|
+
dir: dir,
|
|
2720
|
+
originalStart: originalStart,
|
|
2721
|
+
originalEnd: originalEnd
|
|
2674
2722
|
});
|
|
2675
2723
|
};
|
|
2676
2724
|
//#endregion
|
|
@@ -2691,6 +2739,29 @@ var EditAction = function EditAction(_ref) {
|
|
|
2691
2739
|
var currentRowIndex = editorData.findIndex(function (item) {
|
|
2692
2740
|
return item.id === row.id;
|
|
2693
2741
|
});
|
|
2742
|
+
useEffect(function () {
|
|
2743
|
+
var handleActionMoveEnd = function handleActionMoveEnd(e) {
|
|
2744
|
+
var _ref6 = e.detail || {},
|
|
2745
|
+
left = _ref6.left,
|
|
2746
|
+
width = _ref6.width,
|
|
2747
|
+
top = _ref6.top,
|
|
2748
|
+
height = _ref6.height,
|
|
2749
|
+
id = _ref6.id;
|
|
2750
|
+
console.log('handleActionMoveEnd: ', left, width, top, height, id);
|
|
2751
|
+
if (id === action.id) {
|
|
2752
|
+
handleDragEnd({
|
|
2753
|
+
left: left,
|
|
2754
|
+
width: width,
|
|
2755
|
+
top: top,
|
|
2756
|
+
height: height
|
|
2757
|
+
});
|
|
2758
|
+
}
|
|
2759
|
+
};
|
|
2760
|
+
window.addEventListener('action-move-end', handleActionMoveEnd);
|
|
2761
|
+
return function () {
|
|
2762
|
+
window.removeEventListener('action-move-end', handleActionMoveEnd);
|
|
2763
|
+
};
|
|
2764
|
+
}, [containerRef, handleDragEnd]);
|
|
2694
2765
|
return /*#__PURE__*/React.createElement(RowDnd, {
|
|
2695
2766
|
ref: rowRnd,
|
|
2696
2767
|
parentRef: areaRef,
|
|
@@ -2724,6 +2795,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2724
2795
|
deltaScrollLeft: deltaScrollLeft,
|
|
2725
2796
|
deltaScrollTop: handleDeltaScrollTop
|
|
2726
2797
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2798
|
+
"data-action-id": action.id,
|
|
2727
2799
|
onMouseDown: function onMouseDown() {
|
|
2728
2800
|
isDragWhenClick.current = false;
|
|
2729
2801
|
},
|
|
@@ -2783,7 +2855,7 @@ var EditAction = function EditAction(_ref) {
|
|
|
2783
2855
|
}))));
|
|
2784
2856
|
};
|
|
2785
2857
|
|
|
2786
|
-
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";
|
|
2858
|
+
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";
|
|
2787
2859
|
styleInject(css_248z$4);
|
|
2788
2860
|
|
|
2789
2861
|
var EditRow = function EditRow(props) {
|
|
@@ -2799,9 +2871,11 @@ var EditRow = function EditRow(props) {
|
|
|
2799
2871
|
scale = props.scale,
|
|
2800
2872
|
scaleWidth = props.scaleWidth,
|
|
2801
2873
|
allowCreateTrack = props.allowCreateTrack,
|
|
2802
|
-
containerRef = props.containerRef
|
|
2874
|
+
containerRef = props.containerRef,
|
|
2875
|
+
_props$selectedAction = props.selectedActionIds,
|
|
2876
|
+
selectedActionIds = _props$selectedAction === void 0 ? [] : _props$selectedAction;
|
|
2803
2877
|
var classNames = ['edit-row'];
|
|
2804
|
-
if (rowData === null || rowData === void 0 ? void 0 : rowData.selected) classNames.push('
|
|
2878
|
+
if (rowData === null || rowData === void 0 ? void 0 : rowData.selected) classNames.push('selected');
|
|
2805
2879
|
var handleTime = function handleTime(e) {
|
|
2806
2880
|
if (!areaRef.current) return;
|
|
2807
2881
|
var rect = areaRef.current.getBoundingClientRect();
|
|
@@ -2817,6 +2891,8 @@ var EditRow = function EditRow(props) {
|
|
|
2817
2891
|
return /*#__PURE__*/React.createElement("div", {
|
|
2818
2892
|
className: "".concat(prefix.apply(void 0, classNames), " ").concat(((rowData === null || rowData === void 0 ? void 0 : rowData.classNames) || []).join(' ')),
|
|
2819
2893
|
style: style,
|
|
2894
|
+
"data-row-id": rowData === null || rowData === void 0 ? void 0 : rowData.id,
|
|
2895
|
+
"data-y": "0",
|
|
2820
2896
|
onClick: function onClick(e) {
|
|
2821
2897
|
if (rowData && onClickRow) {
|
|
2822
2898
|
var time = handleTime(e);
|
|
@@ -2853,7 +2929,8 @@ var EditRow = function EditRow(props) {
|
|
|
2853
2929
|
action: action,
|
|
2854
2930
|
allowCreateTrack: allowCreateTrack,
|
|
2855
2931
|
setDropPreview: props.setDropPreview,
|
|
2856
|
-
containerRef: containerRef
|
|
2932
|
+
containerRef: containerRef,
|
|
2933
|
+
selectedActionIds: selectedActionIds
|
|
2857
2934
|
}));
|
|
2858
2935
|
}));
|
|
2859
2936
|
};
|
|
@@ -2964,16 +3041,570 @@ function useDragLine() {
|
|
|
2964
3041
|
};
|
|
2965
3042
|
}
|
|
2966
3043
|
|
|
3044
|
+
var useRowSelection = function useRowSelection(options) {
|
|
3045
|
+
var editorData = options.editorData,
|
|
3046
|
+
rowHeight = options.rowHeight,
|
|
3047
|
+
scrollTop = options.scrollTop,
|
|
3048
|
+
scrollLeft = options.scrollLeft,
|
|
3049
|
+
_onSelectionChange = options.onSelectionChange,
|
|
3050
|
+
_options$disabled = options.disabled,
|
|
3051
|
+
disabled = _options$disabled === void 0 ? false : _options$disabled,
|
|
3052
|
+
containerRef = options.containerRef;
|
|
3053
|
+
var _useState = useState(new Set()),
|
|
3054
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
3055
|
+
selectedActionIds = _useState2[0],
|
|
3056
|
+
setSelectedActionIds = _useState2[1];
|
|
3057
|
+
// 计算框选区域与 action 的交集
|
|
3058
|
+
var getIntersectedActions = useCallback(function (box) {
|
|
3059
|
+
var _containerRef$current, _containerRef$current2;
|
|
3060
|
+
var intersectedActionIds = [];
|
|
3061
|
+
// 直接从 container 获取滚动值
|
|
3062
|
+
var currentScrollLeft = ((_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.scrollLeft) || 0;
|
|
3063
|
+
var currentScrollTop = ((_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.scrollTop) || 0;
|
|
3064
|
+
// box 坐标是相对于可视区域的,需要减去滚动偏移量才能得到相对于 container 的坐标
|
|
3065
|
+
var boxTop = box.top - currentScrollTop;
|
|
3066
|
+
var boxBottom = boxTop + box.height;
|
|
3067
|
+
var boxLeft = box.left - currentScrollLeft;
|
|
3068
|
+
var boxRight = boxLeft + box.width;
|
|
3069
|
+
editorData.forEach(function (row) {
|
|
3070
|
+
// 检查框选区域是否与 action 相交
|
|
3071
|
+
row.actions.forEach(function (action) {
|
|
3072
|
+
var _containerRef$current3;
|
|
3073
|
+
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, "\"]"));
|
|
3074
|
+
if (actionEl) {
|
|
3075
|
+
var actionRect = actionEl.getBoundingClientRect();
|
|
3076
|
+
var actionLeft = actionRect.left;
|
|
3077
|
+
var actionTop = actionRect.top;
|
|
3078
|
+
var actionWidth = actionRect.width;
|
|
3079
|
+
var actionHeight = actionRect.height;
|
|
3080
|
+
var actionRight = actionLeft + actionWidth;
|
|
3081
|
+
var actionBottom = actionTop + actionHeight;
|
|
3082
|
+
// 检查框选区域是否与 action 相交
|
|
3083
|
+
var isActionIntersecting = boxLeft < actionRight && boxRight > actionLeft && boxTop < actionBottom && boxBottom > actionTop;
|
|
3084
|
+
if (isActionIntersecting) {
|
|
3085
|
+
intersectedActionIds.push(action.id);
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
});
|
|
3089
|
+
});
|
|
3090
|
+
return {
|
|
3091
|
+
actionIds: intersectedActionIds
|
|
3092
|
+
};
|
|
3093
|
+
}, [editorData, rowHeight, scrollTop, scrollLeft, containerRef]);
|
|
3094
|
+
// 使用 @air/react-drag-to-select 的框选功能
|
|
3095
|
+
var _useSelectionContaine = useSelectionContainer({
|
|
3096
|
+
onSelectionChange: function onSelectionChange(box) {
|
|
3097
|
+
if (disabled) return;
|
|
3098
|
+
// 边界检查:确保框选区域有效
|
|
3099
|
+
if (!box || box.width < 5 || box.height < 5) {
|
|
3100
|
+
return;
|
|
3101
|
+
}
|
|
3102
|
+
var _getIntersectedAction = getIntersectedActions(box),
|
|
3103
|
+
actionIds = _getIntersectedAction.actionIds;
|
|
3104
|
+
var newSelectedActionIds = new Set(actionIds);
|
|
3105
|
+
// 只在选中状态变化时更新
|
|
3106
|
+
if (newSelectedActionIds.size !== selectedActionIds.size || !_toConsumableArray(newSelectedActionIds).every(function (id) {
|
|
3107
|
+
return selectedActionIds.has(id);
|
|
3108
|
+
})) {
|
|
3109
|
+
setSelectedActionIds(newSelectedActionIds);
|
|
3110
|
+
_onSelectionChange(actionIds);
|
|
3111
|
+
}
|
|
3112
|
+
},
|
|
3113
|
+
onSelectionStart: function onSelectionStart() {
|
|
3114
|
+
if (!disabled) {
|
|
3115
|
+
// 清除之前的选择
|
|
3116
|
+
setSelectedActionIds(new Set());
|
|
3117
|
+
_onSelectionChange([]);
|
|
3118
|
+
}
|
|
3119
|
+
},
|
|
3120
|
+
onSelectionEnd: function onSelectionEnd() {
|
|
3121
|
+
// 框选结束时的处理(可用于性能优化)
|
|
3122
|
+
},
|
|
3123
|
+
shouldStartSelecting: function shouldStartSelecting(target) {
|
|
3124
|
+
var _element$closest, _element$closest2, _element$closest3, _element$closest4;
|
|
3125
|
+
if (disabled) return false;
|
|
3126
|
+
// 不在 action 元素上启动框选
|
|
3127
|
+
var element = target;
|
|
3128
|
+
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'))) {
|
|
3129
|
+
return false;
|
|
3130
|
+
}
|
|
3131
|
+
return true;
|
|
3132
|
+
},
|
|
3133
|
+
selectionProps: {
|
|
3134
|
+
className: 'timeline-editor-selection-box',
|
|
3135
|
+
style: {
|
|
3136
|
+
border: '2px solid #1890ff',
|
|
3137
|
+
backgroundColor: 'rgba(24, 144, 255, 0.1)',
|
|
3138
|
+
zIndex: 9999
|
|
3139
|
+
}
|
|
3140
|
+
},
|
|
3141
|
+
isEnabled: !disabled,
|
|
3142
|
+
eventsElement: containerRef === null || containerRef === void 0 ? void 0 : containerRef.current
|
|
3143
|
+
}),
|
|
3144
|
+
DragSelection = _useSelectionContaine.DragSelection;
|
|
3145
|
+
// 清除选择
|
|
3146
|
+
var clearSelection = useCallback(function () {
|
|
3147
|
+
setSelectedActionIds(new Set());
|
|
3148
|
+
_onSelectionChange([]);
|
|
3149
|
+
}, [_onSelectionChange]);
|
|
3150
|
+
// 点击空白区域取消选择
|
|
3151
|
+
useEffect(function () {
|
|
3152
|
+
if (disabled) return;
|
|
3153
|
+
var handleClickOutside = function handleClickOutside(e) {
|
|
3154
|
+
var target = e.target;
|
|
3155
|
+
// 如果点击的不是选中的 action 或框选框,清除选择
|
|
3156
|
+
if (!target.closest('.timeline-editor-selection-box') && !target.closest('.timeline-editor-action') && !target.closest('[data-draggable="true"]')) {
|
|
3157
|
+
clearSelection();
|
|
3158
|
+
}
|
|
3159
|
+
};
|
|
3160
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
3161
|
+
return function () {
|
|
3162
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
3163
|
+
};
|
|
3164
|
+
}, [disabled, clearSelection]);
|
|
3165
|
+
// 监听 Escape 键取消选择
|
|
3166
|
+
useEffect(function () {
|
|
3167
|
+
if (disabled) return;
|
|
3168
|
+
var handleKeyDown = function handleKeyDown(e) {
|
|
3169
|
+
if (e.key === 'Escape' && selectedActionIds.size > 0) {
|
|
3170
|
+
clearSelection();
|
|
3171
|
+
}
|
|
3172
|
+
};
|
|
3173
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
3174
|
+
return function () {
|
|
3175
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
3176
|
+
};
|
|
3177
|
+
}, [disabled, selectedActionIds.size, clearSelection]);
|
|
3178
|
+
return {
|
|
3179
|
+
DragSelection: DragSelection,
|
|
3180
|
+
selectedActionIds: Array.from(selectedActionIds),
|
|
3181
|
+
clearSelection: clearSelection
|
|
3182
|
+
};
|
|
3183
|
+
};
|
|
3184
|
+
|
|
3185
|
+
var useRowDrag = function useRowDrag(options) {
|
|
3186
|
+
var selectedActionIds = options.selectedActionIds,
|
|
3187
|
+
editorData = options.editorData,
|
|
3188
|
+
containerRef = options.containerRef,
|
|
3189
|
+
_options$scale = options.scale,
|
|
3190
|
+
scale = _options$scale === void 0 ? 1 : _options$scale,
|
|
3191
|
+
_options$scaleWidth = options.scaleWidth,
|
|
3192
|
+
scaleWidth = _options$scaleWidth === void 0 ? 160 : _options$scaleWidth,
|
|
3193
|
+
_options$startLeft = options.startLeft,
|
|
3194
|
+
startLeft = _options$startLeft === void 0 ? 20 : _options$startLeft,
|
|
3195
|
+
setEditorData = options.setEditorData;
|
|
3196
|
+
// 多选拖拽状态
|
|
3197
|
+
var multiDragState = React.useRef({
|
|
3198
|
+
isMultiDrag: false,
|
|
3199
|
+
primaryActionId: null,
|
|
3200
|
+
initialPositions: new Map(),
|
|
3201
|
+
dragOffset: {
|
|
3202
|
+
dx: 0,
|
|
3203
|
+
dy: 0
|
|
3204
|
+
},
|
|
3205
|
+
startCursor: null,
|
|
3206
|
+
isDraggingSelection: false,
|
|
3207
|
+
start: 0,
|
|
3208
|
+
end: 0
|
|
3209
|
+
});
|
|
3210
|
+
// 获取选中的 action DOM 元素
|
|
3211
|
+
var getSelectedActionEls = React.useCallback(function () {
|
|
3212
|
+
if (!(containerRef === null || containerRef === void 0 ? void 0 : containerRef.current)) return [];
|
|
3213
|
+
// 查找所有选中的 action 元素(action-selected 是选中状态的类名)
|
|
3214
|
+
var actions = containerRef.current.querySelectorAll('.timeline-editor-action-selected');
|
|
3215
|
+
return Array.from(actions);
|
|
3216
|
+
}, [containerRef]);
|
|
3217
|
+
var actionEls = getSelectedActionEls();
|
|
3218
|
+
// 存储所有选中 action 的当前预览位置
|
|
3219
|
+
var _React$useState = React.useState(new Map()),
|
|
3220
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
3221
|
+
previewPositions = _React$useState2[0],
|
|
3222
|
+
setPreviewPositions = _React$useState2[1];
|
|
3223
|
+
// 拖拽开始
|
|
3224
|
+
var onDragStart = React.useCallback(function (_ref) {
|
|
3225
|
+
var action = _ref.action,
|
|
3226
|
+
row = _ref.row;
|
|
3227
|
+
// 检查是否有多选
|
|
3228
|
+
if (selectedActionIds.length <= 1) {
|
|
3229
|
+
console.log('useRowDrag: 单选拖拽,不进行多选处理');
|
|
3230
|
+
return;
|
|
3231
|
+
}
|
|
3232
|
+
// 获取当前选中的元素
|
|
3233
|
+
var selectedEls = getSelectedActionEls();
|
|
3234
|
+
if (selectedEls.length <= 1) {
|
|
3235
|
+
console.log('useRowDrag: DOM元素不足,跳过');
|
|
3236
|
+
return;
|
|
3237
|
+
}
|
|
3238
|
+
// 记录每个选中元素的初始位置
|
|
3239
|
+
var initialElementPositions = new Map();
|
|
3240
|
+
selectedEls.forEach(function (el) {
|
|
3241
|
+
// 获取 action id
|
|
3242
|
+
var actionId = el.getAttribute('data-action-id');
|
|
3243
|
+
if (!actionId) return;
|
|
3244
|
+
// 获取当前 transform
|
|
3245
|
+
var style = window.getComputedStyle(el);
|
|
3246
|
+
var transform = style.transform;
|
|
3247
|
+
var x = 0,
|
|
3248
|
+
y = 0;
|
|
3249
|
+
if (transform && transform !== 'none') {
|
|
3250
|
+
// 解析 matrix
|
|
3251
|
+
var matrix = transform.match(/matrix\(([^)]+)\)/);
|
|
3252
|
+
if (matrix) {
|
|
3253
|
+
var values = matrix[1].split(', ');
|
|
3254
|
+
x = parseFloat(values[4]) || 0;
|
|
3255
|
+
y = parseFloat(values[5]) || 0;
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
// 存储初始位置
|
|
3259
|
+
initialElementPositions.set(actionId, {
|
|
3260
|
+
x: x,
|
|
3261
|
+
y: y
|
|
3262
|
+
});
|
|
3263
|
+
// 初始化 data 属性
|
|
3264
|
+
el.setAttribute('data-x', x.toString());
|
|
3265
|
+
el.setAttribute('data-y', y.toString());
|
|
3266
|
+
console.log('useRowDrag: 初始化元素位置', {
|
|
3267
|
+
actionId: actionId,
|
|
3268
|
+
x: x,
|
|
3269
|
+
y: y
|
|
3270
|
+
});
|
|
3271
|
+
});
|
|
3272
|
+
// 记录初始位置信息(用于计算时间偏移)
|
|
3273
|
+
var initialPositions = new Map();
|
|
3274
|
+
editorData.forEach(function (r) {
|
|
3275
|
+
r.actions.forEach(function (a) {
|
|
3276
|
+
if (selectedActionIds.includes(a.id)) {
|
|
3277
|
+
var transform = parserTimeToTransform({
|
|
3278
|
+
start: a.start,
|
|
3279
|
+
end: a.end
|
|
3280
|
+
}, {
|
|
3281
|
+
startLeft: startLeft,
|
|
3282
|
+
scale: scale,
|
|
3283
|
+
scaleWidth: scaleWidth
|
|
3284
|
+
});
|
|
3285
|
+
initialPositions.set(a.id, {
|
|
3286
|
+
rowId: r.id,
|
|
3287
|
+
start: a.start,
|
|
3288
|
+
end: a.end,
|
|
3289
|
+
left: transform.left,
|
|
3290
|
+
width: transform.width
|
|
3291
|
+
});
|
|
3292
|
+
}
|
|
3293
|
+
});
|
|
3294
|
+
});
|
|
3295
|
+
// 记录初始位置
|
|
3296
|
+
multiDragState.current = {
|
|
3297
|
+
isMultiDrag: true,
|
|
3298
|
+
initialPositions: initialPositions,
|
|
3299
|
+
dragOffset: {
|
|
3300
|
+
dx: 0,
|
|
3301
|
+
dy: 0
|
|
3302
|
+
},
|
|
3303
|
+
isDraggingSelection: true,
|
|
3304
|
+
primaryActionId: action.id,
|
|
3305
|
+
offsetX: 0,
|
|
3306
|
+
offsetY: 0,
|
|
3307
|
+
initialElementPositions: initialElementPositions,
|
|
3308
|
+
start: action.start,
|
|
3309
|
+
end: action.end
|
|
3310
|
+
};
|
|
3311
|
+
console.log('useRowDrag: 开始多选拖拽', {
|
|
3312
|
+
actionId: action.id,
|
|
3313
|
+
selectedCount: selectedActionIds.length,
|
|
3314
|
+
elementCount: selectedEls.length
|
|
3315
|
+
});
|
|
3316
|
+
}, [selectedActionIds, editorData, getSelectedActionEls, scale, scaleWidth, startLeft]);
|
|
3317
|
+
// 拖拽移动
|
|
3318
|
+
var onDragMove = React.useCallback(function (params) {
|
|
3319
|
+
var actionId = params.actionId,
|
|
3320
|
+
dx = params.dx,
|
|
3321
|
+
dy = params.dy;
|
|
3322
|
+
var state = multiDragState.current;
|
|
3323
|
+
if (!state.isMultiDrag || !state.isDraggingSelection || !state.initialElementPositions) {
|
|
3324
|
+
return;
|
|
3325
|
+
}
|
|
3326
|
+
// 获取当前选中的元素
|
|
3327
|
+
var selectedEls = getSelectedActionEls();
|
|
3328
|
+
if (selectedEls.length === 0) return;
|
|
3329
|
+
// 更新偏移量
|
|
3330
|
+
state.offsetX = (state.offsetX || 0) + dx;
|
|
3331
|
+
state.offsetY = (state.offsetY || 0) + dy;
|
|
3332
|
+
// 遍历所有选中的元素,同步移动
|
|
3333
|
+
selectedEls.forEach(function (el) {
|
|
3334
|
+
var elActionId = el.getAttribute('data-action-id');
|
|
3335
|
+
if (!elActionId || elActionId === actionId) return;
|
|
3336
|
+
// 获取元素初始位置
|
|
3337
|
+
var initialPos = state.initialElementPositions.get(elActionId);
|
|
3338
|
+
if (!initialPos) return;
|
|
3339
|
+
// 计算新位置 = 初始位置 + 总偏移量
|
|
3340
|
+
var newX = initialPos.x + state.offsetX;
|
|
3341
|
+
var newY = initialPos.y + state.offsetY;
|
|
3342
|
+
// 更新元素位置
|
|
3343
|
+
el.style.transform = "translate(".concat(newX, "px, ").concat(newY, "px)");
|
|
3344
|
+
// 存储当前位置数据
|
|
3345
|
+
el.setAttribute('data-x', newX.toString());
|
|
3346
|
+
el.setAttribute('data-y', newY.toString());
|
|
3347
|
+
});
|
|
3348
|
+
console.log('useRowDrag: 拖拽移动', {
|
|
3349
|
+
actionId: actionId,
|
|
3350
|
+
dx: dx,
|
|
3351
|
+
dy: dy,
|
|
3352
|
+
offsetX: state.offsetX,
|
|
3353
|
+
offsetY: state.offsetY,
|
|
3354
|
+
elementCount: selectedEls.length
|
|
3355
|
+
});
|
|
3356
|
+
}, [getSelectedActionEls]);
|
|
3357
|
+
// 拖拽结束
|
|
3358
|
+
var onDragEnd = React.useCallback(function (params) {
|
|
3359
|
+
var state = multiDragState.current;
|
|
3360
|
+
var _ref2 = params || {},
|
|
3361
|
+
up = _ref2.up;
|
|
3362
|
+
console.log('useRowDrag: 拖拽结束', params);
|
|
3363
|
+
// 清理 DOM 元素上的 data 属性
|
|
3364
|
+
var selectedEls = getSelectedActionEls();
|
|
3365
|
+
selectedEls.forEach(function (el) {
|
|
3366
|
+
el.removeAttribute('data-x');
|
|
3367
|
+
el.removeAttribute('data-y');
|
|
3368
|
+
// 清除 transform 样式
|
|
3369
|
+
el.style.transform = '';
|
|
3370
|
+
});
|
|
3371
|
+
if (!state.isMultiDrag || !params || (params === null || params === void 0 ? void 0 : params.actionId) !== state.primaryActionId) {
|
|
3372
|
+
// 清理状态
|
|
3373
|
+
multiDragState.current = {
|
|
3374
|
+
isMultiDrag: false,
|
|
3375
|
+
primaryActionId: null,
|
|
3376
|
+
initialPositions: new Map(),
|
|
3377
|
+
dragOffset: {
|
|
3378
|
+
dx: 0,
|
|
3379
|
+
dy: 0
|
|
3380
|
+
},
|
|
3381
|
+
startCursor: null,
|
|
3382
|
+
isDraggingSelection: false,
|
|
3383
|
+
start: 0,
|
|
3384
|
+
end: 0
|
|
3385
|
+
};
|
|
3386
|
+
setPreviewPositions(new Map());
|
|
3387
|
+
return;
|
|
3388
|
+
}
|
|
3389
|
+
var actionId = params.actionId,
|
|
3390
|
+
left = params.left,
|
|
3391
|
+
width = params.width,
|
|
3392
|
+
height = params.height,
|
|
3393
|
+
_params$dx = params.dx,
|
|
3394
|
+
_params$dy = params.dy;
|
|
3395
|
+
var top = params.top;
|
|
3396
|
+
var initialPositions = state.initialPositions,
|
|
3397
|
+
primaryActionId = state.primaryActionId,
|
|
3398
|
+
_state$offsetX = state.offsetX,
|
|
3399
|
+
offsetX = _state$offsetX === void 0 ? 0 : _state$offsetX,
|
|
3400
|
+
_state$offsetY = state.offsetY,
|
|
3401
|
+
offsetY = _state$offsetY === void 0 ? 0 : _state$offsetY;
|
|
3402
|
+
if (up === 0) {
|
|
3403
|
+
top = 0;
|
|
3404
|
+
} else if (up === 1) {
|
|
3405
|
+
top = -20;
|
|
3406
|
+
} else if (up === -1) {
|
|
3407
|
+
top = 20;
|
|
3408
|
+
}
|
|
3409
|
+
// 如果没有初始位置数据,说明不是有效的多选拖拽
|
|
3410
|
+
if (!setEditorData || initialPositions.size === 0) {
|
|
3411
|
+
// 清理状态
|
|
3412
|
+
multiDragState.current = {
|
|
3413
|
+
isMultiDrag: false,
|
|
3414
|
+
primaryActionId: null,
|
|
3415
|
+
initialPositions: new Map(),
|
|
3416
|
+
dragOffset: {
|
|
3417
|
+
dx: 0,
|
|
3418
|
+
dy: 0
|
|
3419
|
+
},
|
|
3420
|
+
startCursor: null,
|
|
3421
|
+
isDraggingSelection: false,
|
|
3422
|
+
start: 0,
|
|
3423
|
+
end: 0
|
|
3424
|
+
};
|
|
3425
|
+
setPreviewPositions(new Map());
|
|
3426
|
+
return;
|
|
3427
|
+
}
|
|
3428
|
+
// 计算主 action 的最终时间
|
|
3429
|
+
var primaryFinalTime = parserTransformToTime({
|
|
3430
|
+
left: left,
|
|
3431
|
+
width: width
|
|
3432
|
+
}, {
|
|
3433
|
+
startLeft: startLeft,
|
|
3434
|
+
scale: scale,
|
|
3435
|
+
scaleWidth: scaleWidth
|
|
3436
|
+
});
|
|
3437
|
+
// 计算主 action 的偏移量(时间)
|
|
3438
|
+
var primaryInitial = initialPositions.get(primaryActionId);
|
|
3439
|
+
if (!primaryInitial) {
|
|
3440
|
+
multiDragState.current = {
|
|
3441
|
+
isMultiDrag: false,
|
|
3442
|
+
primaryActionId: null,
|
|
3443
|
+
initialPositions: new Map(),
|
|
3444
|
+
dragOffset: {
|
|
3445
|
+
dx: 0,
|
|
3446
|
+
dy: 0
|
|
3447
|
+
},
|
|
3448
|
+
startCursor: null,
|
|
3449
|
+
isDraggingSelection: false,
|
|
3450
|
+
start: 0,
|
|
3451
|
+
end: 0
|
|
3452
|
+
};
|
|
3453
|
+
setPreviewPositions(new Map());
|
|
3454
|
+
return;
|
|
3455
|
+
}
|
|
3456
|
+
var timeOffset = primaryFinalTime.start - primaryInitial.start;
|
|
3457
|
+
console.log('useRowDrag: 拖拽结束', {
|
|
3458
|
+
actionId: actionId,
|
|
3459
|
+
primaryInitialStart: primaryInitial.start,
|
|
3460
|
+
primaryFinalStart: primaryFinalTime.start,
|
|
3461
|
+
timeOffset: timeOffset,
|
|
3462
|
+
selectedCount: initialPositions.size,
|
|
3463
|
+
offsetX: offsetX,
|
|
3464
|
+
offsetY: offsetY
|
|
3465
|
+
});
|
|
3466
|
+
// 如果时间偏移太小,不更新数据
|
|
3467
|
+
if (Math.abs(timeOffset) < 0.001) {
|
|
3468
|
+
console.log('useRowDrag: 偏移太小,跳过更新');
|
|
3469
|
+
multiDragState.current = {
|
|
3470
|
+
isMultiDrag: false,
|
|
3471
|
+
primaryActionId: null,
|
|
3472
|
+
initialPositions: new Map(),
|
|
3473
|
+
dragOffset: {
|
|
3474
|
+
dx: 0,
|
|
3475
|
+
dy: 0
|
|
3476
|
+
},
|
|
3477
|
+
startCursor: null,
|
|
3478
|
+
isDraggingSelection: false,
|
|
3479
|
+
start: 0,
|
|
3480
|
+
end: 0
|
|
3481
|
+
};
|
|
3482
|
+
setPreviewPositions(new Map());
|
|
3483
|
+
return;
|
|
3484
|
+
}
|
|
3485
|
+
// ------------------------------------------------------------
|
|
3486
|
+
var _multiDragState$curre = multiDragState.current,
|
|
3487
|
+
start = _multiDragState$curre.start,
|
|
3488
|
+
end = _multiDragState$curre.end,
|
|
3489
|
+
isMultiDrag = _multiDragState$curre.isMultiDrag;
|
|
3490
|
+
// 如果是多选拖拽,处理所有选中的 actions
|
|
3491
|
+
if (isMultiDrag) {
|
|
3492
|
+
// 计算当前 action 的偏移量
|
|
3493
|
+
var currentStart = parserTransformToTime({
|
|
3494
|
+
left: left,
|
|
3495
|
+
width: width
|
|
3496
|
+
}, {
|
|
3497
|
+
scaleWidth: scaleWidth,
|
|
3498
|
+
scale: scale,
|
|
3499
|
+
startLeft: startLeft
|
|
3500
|
+
}).start;
|
|
3501
|
+
var deltaTime = currentStart - start;
|
|
3502
|
+
console.log('Multi-drag ended, deltaTime:', deltaTime);
|
|
3503
|
+
// 更新所有选中的 actions 的最终位置
|
|
3504
|
+
var updatedData = editorData.map(function (r) {
|
|
3505
|
+
return _objectSpread2(_objectSpread2({}, r), {}, {
|
|
3506
|
+
actions: r.actions.map(function (a) {
|
|
3507
|
+
if (selectedActionIds.includes(a.id) && primaryActionId !== a.id) {
|
|
3508
|
+
var newStart = a.start + deltaTime;
|
|
3509
|
+
var newEnd = a.end + deltaTime;
|
|
3510
|
+
// 计算 left, width, top, height
|
|
3511
|
+
var _parserTimeToTransfor = parserTimeToTransform({
|
|
3512
|
+
start: newStart,
|
|
3513
|
+
end: newEnd
|
|
3514
|
+
}, {
|
|
3515
|
+
scaleWidth: scaleWidth,
|
|
3516
|
+
scale: scale,
|
|
3517
|
+
startLeft: startLeft
|
|
3518
|
+
}),
|
|
3519
|
+
_left = _parserTimeToTransfor.left,
|
|
3520
|
+
_width = _parserTimeToTransfor.width;
|
|
3521
|
+
setTimeout(function () {
|
|
3522
|
+
console.log('useRowDrag 1222: 拖拽结束', {
|
|
3523
|
+
left: _left,
|
|
3524
|
+
width: _width,
|
|
3525
|
+
top: top,
|
|
3526
|
+
height: height,
|
|
3527
|
+
id: a.id
|
|
3528
|
+
});
|
|
3529
|
+
window.dispatchEvent(new CustomEvent('action-move-end', {
|
|
3530
|
+
detail: {
|
|
3531
|
+
left: _left,
|
|
3532
|
+
width: _width,
|
|
3533
|
+
top: top,
|
|
3534
|
+
height: height,
|
|
3535
|
+
id: a.id
|
|
3536
|
+
}
|
|
3537
|
+
}));
|
|
3538
|
+
}, 0);
|
|
3539
|
+
return _objectSpread2(_objectSpread2({}, a), {}, {
|
|
3540
|
+
start: newStart,
|
|
3541
|
+
end: newEnd
|
|
3542
|
+
});
|
|
3543
|
+
}
|
|
3544
|
+
return a;
|
|
3545
|
+
})
|
|
3546
|
+
});
|
|
3547
|
+
});
|
|
3548
|
+
// setEditorData([...updatedData]);
|
|
3549
|
+
return;
|
|
3550
|
+
}
|
|
3551
|
+
// ------------------------------------------------------------
|
|
3552
|
+
// 清理状态
|
|
3553
|
+
multiDragState.current = {
|
|
3554
|
+
isMultiDrag: false,
|
|
3555
|
+
primaryActionId: null,
|
|
3556
|
+
initialPositions: new Map(),
|
|
3557
|
+
dragOffset: {
|
|
3558
|
+
dx: 0,
|
|
3559
|
+
dy: 0
|
|
3560
|
+
},
|
|
3561
|
+
startCursor: null,
|
|
3562
|
+
isDraggingSelection: false,
|
|
3563
|
+
start: 0,
|
|
3564
|
+
end: 0
|
|
3565
|
+
};
|
|
3566
|
+
setPreviewPositions(new Map());
|
|
3567
|
+
console.log('useRowDrag: 多选拖拽完成', {
|
|
3568
|
+
updatedCount: initialPositions.size
|
|
3569
|
+
});
|
|
3570
|
+
}, [editorData, setEditorData, scale, scaleWidth, startLeft, getSelectedActionEls, selectedActionIds]);
|
|
3571
|
+
// 获取指定 action 的预览位置
|
|
3572
|
+
var getPreviewPosition = React.useCallback(function (actionId) {
|
|
3573
|
+
return previewPositions.get(actionId) || null;
|
|
3574
|
+
}, [previewPositions]);
|
|
3575
|
+
// 检查是否是多选拖拽模式
|
|
3576
|
+
var isMultiDragging = React.useCallback(function () {
|
|
3577
|
+
return multiDragState.current.isMultiDrag;
|
|
3578
|
+
}, []);
|
|
3579
|
+
// 获取当前拖拽状态
|
|
3580
|
+
var getMultiDragState = React.useCallback(function () {
|
|
3581
|
+
return multiDragState.current;
|
|
3582
|
+
}, []);
|
|
3583
|
+
return {
|
|
3584
|
+
onDragStart: onDragStart,
|
|
3585
|
+
onDragMove: onDragMove,
|
|
3586
|
+
onDragEnd: onDragEnd,
|
|
3587
|
+
getPreviewPosition: getPreviewPosition,
|
|
3588
|
+
isMultiDragging: isMultiDragging,
|
|
3589
|
+
getMultiDragState: getMultiDragState,
|
|
3590
|
+
isMultiDrag: multiDragState.current.isMultiDrag
|
|
3591
|
+
};
|
|
3592
|
+
};
|
|
3593
|
+
|
|
2967
3594
|
// 获取音频时长
|
|
2968
3595
|
var getAudioDuration = function getAudioDuration(url) {
|
|
2969
3596
|
return new Promise(function (resolve) {
|
|
2970
3597
|
var sound = new Howl({
|
|
2971
|
-
src:
|
|
3598
|
+
src: url
|
|
2972
3599
|
});
|
|
2973
3600
|
sound.on('load', function () {
|
|
2974
3601
|
resolve(sound.duration());
|
|
2975
3602
|
sound.unload();
|
|
2976
3603
|
});
|
|
3604
|
+
setTimeout(function () {
|
|
3605
|
+
resolve(2); // 加载失败时返回默认时长2秒
|
|
3606
|
+
sound.unload();
|
|
3607
|
+
}, 6 * 1000); // 60秒超时 60 * 1000
|
|
2977
3608
|
sound.on('loaderror', function () {
|
|
2978
3609
|
resolve(2); // 加载失败时返回默认时长2秒
|
|
2979
3610
|
sound.unload();
|
|
@@ -3022,6 +3653,7 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3022
3653
|
var handleUploadChange = function handleUploadChange(row) {
|
|
3023
3654
|
return /*#__PURE__*/function () {
|
|
3024
3655
|
var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(info) {
|
|
3656
|
+
var _info$file$response;
|
|
3025
3657
|
var uid, duration, newAction;
|
|
3026
3658
|
return _regenerator().w(function (_context) {
|
|
3027
3659
|
while (1) switch (_context.n) {
|
|
@@ -3039,7 +3671,7 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3039
3671
|
case 2:
|
|
3040
3672
|
duration = _context.v;
|
|
3041
3673
|
newAction = {
|
|
3042
|
-
id: uid,
|
|
3674
|
+
id: ((_info$file$response = info.file.response) === null || _info$file$response === void 0 ? void 0 : _info$file$response.id) || uid,
|
|
3043
3675
|
effectId: 'custom_video_effect',
|
|
3044
3676
|
flexible: true,
|
|
3045
3677
|
url: info.file.response.url,
|
|
@@ -3076,6 +3708,63 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3076
3708
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
3077
3709
|
dropPreview = _useState4[0],
|
|
3078
3710
|
setDropPreview = _useState4[1];
|
|
3711
|
+
var _useState5 = useState(null),
|
|
3712
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
3713
|
+
dragIndicator = _useState6[0],
|
|
3714
|
+
setDragIndicator = _useState6[1];
|
|
3715
|
+
// 框选功能
|
|
3716
|
+
var _useRowSelection = useRowSelection({
|
|
3717
|
+
editorData: editorData,
|
|
3718
|
+
rowHeight: _rowHeight,
|
|
3719
|
+
scrollTop: scrollTop,
|
|
3720
|
+
scrollLeft: scrollLeft,
|
|
3721
|
+
onSelectionChange: function onSelectionChange(selectedActionIds) {
|
|
3722
|
+
// 更新 editorData 中每个 action 的选中状态
|
|
3723
|
+
var updatedData = editorData.map(function (row) {
|
|
3724
|
+
return _objectSpread2(_objectSpread2({}, row), {}, {
|
|
3725
|
+
actions: row.actions.map(function (action) {
|
|
3726
|
+
return _objectSpread2(_objectSpread2({}, action), {}, {
|
|
3727
|
+
selected: selectedActionIds.includes(action.id)
|
|
3728
|
+
});
|
|
3729
|
+
})
|
|
3730
|
+
});
|
|
3731
|
+
});
|
|
3732
|
+
setEditorData(updatedData);
|
|
3733
|
+
},
|
|
3734
|
+
disabled: false,
|
|
3735
|
+
containerRef: editAreaRef
|
|
3736
|
+
}),
|
|
3737
|
+
DragSelection = _useRowSelection.DragSelection,
|
|
3738
|
+
selectedActionIds = _useRowSelection.selectedActionIds;
|
|
3739
|
+
var _useRowDrag = useRowDrag({
|
|
3740
|
+
selectedActionIds: selectedActionIds,
|
|
3741
|
+
editorData: editorData,
|
|
3742
|
+
containerRef: editAreaRef,
|
|
3743
|
+
scale: scale,
|
|
3744
|
+
scaleWidth: scaleWidth,
|
|
3745
|
+
startLeft: startLeft,
|
|
3746
|
+
setEditorData: setEditorData,
|
|
3747
|
+
allowCreateTrack: allowCreateTrack,
|
|
3748
|
+
rowHeight: _rowHeight
|
|
3749
|
+
}),
|
|
3750
|
+
onDragStart = _useRowDrag.onDragStart,
|
|
3751
|
+
onDragMove = _useRowDrag.onDragMove,
|
|
3752
|
+
onDragEnd = _useRowDrag.onDragEnd;
|
|
3753
|
+
// 监听拖拽位置指示器事件
|
|
3754
|
+
useEffect(function () {
|
|
3755
|
+
var handleDragMove = function handleDragMove(e) {
|
|
3756
|
+
setDragIndicator(e.detail);
|
|
3757
|
+
};
|
|
3758
|
+
var handleDragEnd = function handleDragEnd() {
|
|
3759
|
+
setDragIndicator(null);
|
|
3760
|
+
};
|
|
3761
|
+
window.addEventListener('row-drag-move', handleDragMove);
|
|
3762
|
+
window.addEventListener('row-drag-end', handleDragEnd);
|
|
3763
|
+
return function () {
|
|
3764
|
+
window.removeEventListener('row-drag-move', handleDragMove);
|
|
3765
|
+
window.removeEventListener('row-drag-end', handleDragEnd);
|
|
3766
|
+
};
|
|
3767
|
+
}, []);
|
|
3079
3768
|
// 处理拖拽上传事件
|
|
3080
3769
|
var handleDrop = function handleDrop(e) {
|
|
3081
3770
|
e.preventDefault();
|
|
@@ -3160,8 +3849,13 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3160
3849
|
allowCreateTrack: allowCreateTrack,
|
|
3161
3850
|
setDropPreview: setDropPreview,
|
|
3162
3851
|
containerRef: containerRef,
|
|
3852
|
+
selectedActionIds: selectedActionIds,
|
|
3163
3853
|
onActionMoveStart: function onActionMoveStart(data) {
|
|
3164
3854
|
handleInitDragLine(data);
|
|
3855
|
+
onDragStart({
|
|
3856
|
+
action: data.action,
|
|
3857
|
+
row: data.row
|
|
3858
|
+
});
|
|
3165
3859
|
return _onActionMoveStart && _onActionMoveStart(data);
|
|
3166
3860
|
},
|
|
3167
3861
|
onActionResizeStart: function onActionResizeStart(data) {
|
|
@@ -3170,6 +3864,20 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3170
3864
|
},
|
|
3171
3865
|
onActionMoving: function onActionMoving(data) {
|
|
3172
3866
|
handleUpdateDragLine(data);
|
|
3867
|
+
// 传递拖拽参数给多选拖拽处理
|
|
3868
|
+
onDragMove({
|
|
3869
|
+
actionId: data.action.id,
|
|
3870
|
+
left: data.left,
|
|
3871
|
+
width: data.width,
|
|
3872
|
+
top: data.top || 0,
|
|
3873
|
+
height: data.height || 0,
|
|
3874
|
+
dx: (data.left || 0) - (data.lastLeft || 0),
|
|
3875
|
+
dy: (data.top || 0) - (data.lastTop || 0),
|
|
3876
|
+
lastLeft: data.lastLeft,
|
|
3877
|
+
lastWidth: data.lastWidth,
|
|
3878
|
+
lastTop: data.lastTop,
|
|
3879
|
+
lastHeight: data.lastHeight
|
|
3880
|
+
});
|
|
3173
3881
|
return _onActionMoving && _onActionMoving(data);
|
|
3174
3882
|
},
|
|
3175
3883
|
onActionResizing: function onActionResizing(data) {
|
|
@@ -3182,13 +3890,22 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3182
3890
|
},
|
|
3183
3891
|
onActionMoveEnd: function onActionMoveEnd(data) {
|
|
3184
3892
|
disposeDragLine();
|
|
3893
|
+
// 传递拖拽结束参数给多选拖拽处理
|
|
3894
|
+
onDragEnd({
|
|
3895
|
+
actionId: data.action.id,
|
|
3896
|
+
left: data.left || 0,
|
|
3897
|
+
width: data.width || 0,
|
|
3898
|
+
top: data.top || 0,
|
|
3899
|
+
height: data.height || 0,
|
|
3900
|
+
up: data.up || 0
|
|
3901
|
+
});
|
|
3185
3902
|
return _onActionMoveEnd && _onActionMoveEnd(data);
|
|
3186
3903
|
}
|
|
3187
3904
|
}));
|
|
3188
|
-
if (canUpload || (row === null || row === void 0 ? void 0 : row.canUpload)) {
|
|
3905
|
+
if (!!row && (canUpload || (row === null || row === void 0 ? void 0 : row.canUpload))) {
|
|
3189
3906
|
return /*#__PURE__*/React.createElement(Upload, {
|
|
3190
3907
|
ref: uploadRef,
|
|
3191
|
-
key: key,
|
|
3908
|
+
key: key + 'upload',
|
|
3192
3909
|
style: _objectSpread2(_objectSpread2({
|
|
3193
3910
|
width: '100%',
|
|
3194
3911
|
display: 'block'
|
|
@@ -3224,7 +3941,9 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3224
3941
|
className: prefix('edit-area') + " ".concat((className || '').replace('timeline-editor', '') || ''),
|
|
3225
3942
|
style: {
|
|
3226
3943
|
height: isMulti ? _totalHeight : 'unset',
|
|
3227
|
-
maxHeight: isMulti ? _totalHeight : 'unset'
|
|
3944
|
+
maxHeight: isMulti ? _totalHeight : 'unset',
|
|
3945
|
+
width: isMulti ? Math.max(scaleCount * scaleWidth + startLeft, 0) : 'unset',
|
|
3946
|
+
minWidth: isMulti ? '100%' : 'unset'
|
|
3228
3947
|
}
|
|
3229
3948
|
}, /*#__PURE__*/React.createElement(AutoSizer, {
|
|
3230
3949
|
style: {
|
|
@@ -3271,9 +3990,30 @@ var EditArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3271
3990
|
_onScroll(param);
|
|
3272
3991
|
}
|
|
3273
3992
|
});
|
|
3274
|
-
}), dragLine && /*#__PURE__*/React.createElement(DragLines, _objectSpread2({
|
|
3993
|
+
}), /*#__PURE__*/React.createElement(DragSelection, null), dragLine && /*#__PURE__*/React.createElement(DragLines, _objectSpread2({
|
|
3275
3994
|
scrollLeft: scrollLeft
|
|
3276
|
-
}, dragLineData)),
|
|
3995
|
+
}, dragLineData)), dragIndicator && function () {
|
|
3996
|
+
// 计算拖拽位置指示器的位置
|
|
3997
|
+
var top = 0;
|
|
3998
|
+
var targetIndex = dragIndicator.targetIndex;
|
|
3999
|
+
for (var i = 0; i < Math.min(targetIndex, editorData.length); i++) {
|
|
4000
|
+
top += editorData[i].rowHeight || _rowHeight;
|
|
4001
|
+
}
|
|
4002
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
4003
|
+
style: {
|
|
4004
|
+
position: 'absolute',
|
|
4005
|
+
left: 0,
|
|
4006
|
+
right: 0,
|
|
4007
|
+
top: top - scrollTop + 16,
|
|
4008
|
+
height: '3px',
|
|
4009
|
+
backgroundColor: '#1890ff',
|
|
4010
|
+
boxShadow: '0 0 8px rgba(24, 144, 255, 0.6)',
|
|
4011
|
+
zIndex: 1001,
|
|
4012
|
+
pointerEvents: 'none',
|
|
4013
|
+
transition: 'top 0.05s ease-out'
|
|
4014
|
+
}
|
|
4015
|
+
});
|
|
4016
|
+
}(), dropPreview && function () {
|
|
3277
4017
|
// 计算预览指示器的位置
|
|
3278
4018
|
var top = 0;
|
|
3279
4019
|
for (var i = 0; i < editorData.length; i++) {
|
|
@@ -3667,7 +4407,7 @@ var Timeline = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
3667
4407
|
key: key,
|
|
3668
4408
|
isMulti: areaCount > 1
|
|
3669
4409
|
}, checkedProps), {}, {
|
|
3670
|
-
className: index !== 0 ? "no-flex ".concat(key, " ").concat(index) : "overflow-hidden ".concat(key, " ").concat(index),
|
|
4410
|
+
className: index !== 0 ? "no-flex ".concat(key, " ").concat(index, " overflow-hidden") : "overflow-hidden ".concat(key, " ").concat(index),
|
|
3671
4411
|
timelineWidth: width,
|
|
3672
4412
|
ref: function ref(_ref4) {
|
|
3673
4413
|
return areaRef.current = _ref4 === null || _ref4 === void 0 ? void 0 : _ref4.domRef.current;
|