UNPKG

@antv/s2-react

Version:
167 lines 7.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DragCopyMask = void 0; const tslib_1 = require("tslib"); const s2_1 = require("@antv/s2"); const lodash_1 = require("lodash"); const react_1 = tslib_1.__importStar(require("react")); const SpreadSheetContext_1 = require("../../../../context/SpreadSheetContext"); require("./drag-copy-mask.less"); exports.DragCopyMask = (0, react_1.memo)(({ onCopyFinished }) => { const s2 = (0, SpreadSheetContext_1.useSpreadSheetInstance)(); const [startCell, setStartCell] = (0, react_1.useState)(); const [maskPosition, setMaskPosition] = (0, react_1.useState)({ right: 0, bottom: 0 }); const [dragPoint, setDragPoint] = (0, react_1.useState)(); const isInCell = (point, cell) => { const cellMeta = (0, lodash_1.pick)(cell.getMeta(), [ 'x', 'y', 'width', 'height', 'fieldValue', ]); const scrollOffset = s2.facet.getScrollOffset(); const sampleColNode = s2.facet.getColNodes()[0]; const sampleColNodeHeight = (sampleColNode === null || sampleColNode === void 0 ? void 0 : sampleColNode.height) || 0; // 点位偏移 const pointX = point.x; const pointY = point.y; const scrollOffsetY = (scrollOffset === null || scrollOffset === void 0 ? void 0 : scrollOffset.scrollY) - sampleColNodeHeight; const cellMaxX = cellMeta.x - scrollOffset.scrollX + cellMeta.width + 4; const cellMinX = cellMeta.x - scrollOffset.scrollX; const cellMaxY = cellMeta.y - scrollOffsetY + cellMeta.height + 4; const cellMinY = cellMeta.y - scrollOffsetY; return (cellMaxX >= pointX && cellMinX < pointX && cellMaxY >= pointY && cellMinY < pointY); }; /** 判断当前位置是否在表格可视区域内 */ const judgePointInView = (point) => { const rect = s2.getCanvasElement().getBoundingClientRect(); const frozenGroupAreas = s2.facet.frozenGroupAreas; const viewMinX = rect.x; const viewMaxX = rect.x + rect.width; // 减去列头高度 const viewMinY = rect.y + frozenGroupAreas[s2_1.FrozenGroupArea.Row].height; const viewMaxY = rect.y + rect.height; return (point.x <= viewMaxX && point.x >= viewMinX && point.y <= viewMaxY && point.y >= viewMinY); }; const getCurrentHoverCell = (event) => { const rect = s2.getCanvasElement().getBoundingClientRect(); const allCells = s2.facet.getDataCells(); return allCells.find((dataCell) => isInCell({ y: event.y - rect.y, x: event.x - rect.x }, dataCell)); }; const getSelectedCellRange = (startCell, endCell) => { const startCellMeta = startCell.getMeta(); const endCellMeta = endCell === null || endCell === void 0 ? void 0 : endCell.getMeta(); const minX = Math.min(startCellMeta.colIndex, endCellMeta.colIndex); const maxX = Math.max(startCellMeta.colIndex, endCellMeta.colIndex); const maxY = Math.max(startCellMeta.rowIndex, endCellMeta.rowIndex); const minY = Math.min(startCellMeta.rowIndex, endCellMeta.rowIndex); const allCells = s2.facet.getDataCells(); return allCells.filter((item) => { const itemMeta = item.getMeta(); return (itemMeta.rowIndex <= maxY && itemMeta.rowIndex >= minY && itemMeta.colIndex <= maxX && itemMeta.colIndex >= minX); }); }; // 利用闭包记录最近一次hover位置,防止鼠标拖拽越界报错 const lastHoverPoint = { x: 0, y: 0 }; const dragMove = (0, lodash_1.throttle)((event) => { if (!startCell) { return; } let targetCell = getCurrentHoverCell(event); let newX = event.x - dragPoint.x; let newY = event.y - dragPoint.y; // 判断鼠标是否在表格可视区域,不在的话使用最近一次hover位置 if (!judgePointInView(event)) { targetCell = getCurrentHoverCell(lastHoverPoint); newX = lastHoverPoint.x - dragPoint.x; newY = lastHoverPoint.y - dragPoint.y; } else { lastHoverPoint.x = event.x; lastHoverPoint.y = event.y; } setMaskPosition({ right: newX, bottom: newY }); const selectedRange = getSelectedCellRange(startCell, targetCell); // 更改选中状态 s2.interaction.changeState({ cells: selectedRange.map((v) => v.getMeta()), stateName: s2_1.InteractionStateName.PREPARE_SELECT, force: true, }); }, 10); const dragMouseUp = (event) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { if (!startCell) { return; } const targetCell = getCurrentHoverCell(event) || getCurrentHoverCell(lastHoverPoint); const displayData = s2.dataSet.getDisplayDataSet(); const selectedRange = getSelectedCellRange(startCell, targetCell); const { fieldValue } = startCell.getMeta(); const changedCells = selectedRange.map((item) => { const { rowIndex, valueField } = item.getMeta(); if (displayData[rowIndex] && typeof displayData[rowIndex][valueField] !== 'undefined') { displayData[rowIndex][valueField] = fieldValue; } return item; }); // 更改选中状态 s2.interaction.changeState({ cells: changedCells.map((v) => v.getMeta()), stateName: s2_1.InteractionStateName.PREPARE_SELECT, force: true, }); yield s2.render(true); setMaskPosition({ right: 0, bottom: 0 }); s2.off(s2_1.S2Event.GLOBAL_MOUSE_MOVE, dragMove); s2.off(s2_1.S2Event.GLOBAL_MOUSE_UP, dragMouseUp); setStartCell(undefined); onCopyFinished === null || onCopyFinished === void 0 ? void 0 : onCopyFinished(); }); (0, react_1.useEffect)(() => { if (startCell) { s2.on(s2_1.S2Event.GLOBAL_MOUSE_MOVE, dragMove); s2.on(s2_1.S2Event.GLOBAL_MOUSE_UP, dragMouseUp); } }, [startCell]); const dragMouseDown = (event) => { if ((0, lodash_1.get)(event, 'target.id') !== 'spreadsheet-drag-copy-point') { return; } const rect = event.target.getBoundingClientRect(); const { top, left } = (0, lodash_1.get)(event, 'target.style', {}); const allCells = s2.facet.getDataCells(); const targetCell = allCells.find((v) => isInCell({ y: parseFloat(top), x: parseFloat(left) }, v)); setDragPoint({ x: rect.x, y: rect.y }); setStartCell(targetCell); }; (0, react_1.useEffect)(() => { const pointElement = document.getElementById('spreadsheet-drag-copy-point'); if (pointElement && s2) { pointElement.addEventListener('mousedown', dragMouseDown); } return () => { pointElement === null || pointElement === void 0 ? void 0 : pointElement.removeEventListener('mousedown', dragMouseDown); }; }, [s2]); return (react_1.default.createElement("div", { className: `${s2_1.S2_PREFIX_CLS}-drag-copy-mask`, style: { right: maskPosition.right > 0 ? maskPosition.right : 0, bottom: maskPosition.bottom > 0 ? maskPosition.bottom : 0, left: maskPosition.right <= 0 ? maskPosition.right : 0, top: maskPosition.bottom <= 0 ? maskPosition.bottom : 0, width: Math.abs(maskPosition.right), height: Math.abs(maskPosition.bottom), } })); }); //# sourceMappingURL=drag-copy-mask.js.map