@antv/s2-react
Version:
use S2 with react
167 lines • 7.81 kB
JavaScript
"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