From 6c1b9aada2101146fd0a6b99ab95364e03d28b13 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Thu, 6 Feb 2025 16:14:31 +0800 Subject: [PATCH 1/8] test: test1 test: test 2 --- .../canvas-float-dom-manager.service.ts | 60 ++++++------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts index 18e2688602a..fcb37a562e5 100644 --- a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts +++ b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts @@ -123,16 +123,16 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce }; } const { left, right, top, bottom } = posOfFloatObject; - let { top: topBoundOfViewArea, left: leftBoundViewArea, viewportScrollX, viewportScrollY } = viewMain; - + let { top: topOfViewMain, left: leftOfViewMain, viewportScrollX, viewportScrollY } = viewMain; // specify edge of viewbound. if not specify, use viewMain. const { boundsOfViewArea, scrollDirectionResponse } = floatDomInfo || {}; + if (boundsOfViewArea) { if (Tools.isDefine(boundsOfViewArea.top)) { - topBoundOfViewArea = boundsOfViewArea.top; + topOfViewMain = boundsOfViewArea.top; } if (Tools.isDefine(boundsOfViewArea.left)) { - leftBoundViewArea = boundsOfViewArea.left; + leftOfViewMain = boundsOfViewArea.left; } } if (scrollDirectionResponse === ScrollDirectionResponse.HORIZONTAL) { @@ -142,43 +142,21 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce viewportScrollX = 0; } - let offsetLeft: number; - let offsetRight: number; - - // viewMain or viewTop - if (left < leftBoundViewArea) { - absolute.left = true; - offsetLeft = ((leftBoundViewArea) + (left - leftBoundViewArea)) * scaleX; - offsetRight = Math.max( - Math.min( - ((leftBoundViewArea) + (right - leftBoundViewArea)) * scaleX, - (leftBoundViewArea) * scaleX - ), - (right - viewportScrollX) * scaleX); - } else { - absolute.left = false; - offsetLeft = Math.max((left - viewportScrollX) * scaleX, (leftBoundViewArea) * scaleX); - offsetRight = Math.max((right - viewportScrollX) * scaleX, (leftBoundViewArea) * scaleX); - } - - let offsetTop: number; - let offsetBottom: number; - // viewMain or viewTop - if (top < topBoundOfViewArea) { - absolute.top = true; - offsetTop = ((topBoundOfViewArea) + (top - topBoundOfViewArea)) * scaleY; - offsetBottom = Math.max( - Math.min( - ((topBoundOfViewArea) + (right - topBoundOfViewArea)) * scaleY, - (topBoundOfViewArea) * scaleY - ), - (bottom - viewportScrollY) * scaleY - ); - } else { - absolute.top = false; - offsetTop = Math.max((top - viewportScrollY) * scaleY, (topBoundOfViewArea) * scaleY); - offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, (topBoundOfViewArea) * scaleY); - } + absolute.left = left * scaleX < leftOfViewMain; + const offsetLeft = absolute.left + ? leftOfViewMain * scaleX + (left - leftOfViewMain) * scaleX + : Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); + const offsetRight = right < leftOfViewMain + ? right * scaleX + : Math.max(leftOfViewMain, (right - viewportScrollX) * scaleX); + + absolute.top = top * scaleY < topOfViewMain; + const offsetTop = absolute.top + ? topOfViewMain * scaleY + (top - topOfViewMain) * scaleY + : Math.max((top - viewportScrollY) * scaleY, topOfViewMain); + const offsetBottom = bottom < topOfViewMain + ? bottom * scaleY + : Math.max(topOfViewMain, (bottom - viewportScrollY) * scaleY); return { left: offsetLeft, From 0cb4b94e793adfa4657b1a69d3d4ed75becf367f Mon Sep 17 00:00:00 2001 From: lumixraku Date: Thu, 6 Feb 2025 21:27:41 +0800 Subject: [PATCH 2/8] test: test 3 --- packages/core/src/sheets/typedef.ts | 7 +- .../sheets/sheet.render-skeleton.ts | 51 ++++++++ packages/engine-render/src/viewport.ts | 5 +- .../canvas-float-dom-manager.service.ts | 119 +++++++++++++++--- .../freeze.render-controller.ts | 30 +++++ 5 files changed, 190 insertions(+), 22 deletions(-) diff --git a/packages/core/src/sheets/typedef.ts b/packages/core/src/sheets/typedef.ts index 6e00ff075e6..97bf5dcdad8 100644 --- a/packages/core/src/sheets/typedef.ts +++ b/packages/core/src/sheets/typedef.ts @@ -16,11 +16,12 @@ import type { IResources } from '../services/resource-manager/type'; import type { IObjectArrayPrimitiveType, IObjectMatrixPrimitiveType, Nullable } from '../shared'; +import type { BooleanNumber } from '../types/enum'; import type { LocaleType } from '../types/enum/locale-type'; import type { IDocumentData } from '../types/interfaces'; import type { ICellCustomRender } from '../types/interfaces/i-cell-custom-render'; import type { IStyleData } from '../types/interfaces/i-style-data'; -import { type BooleanNumber, CellValueType } from '../types/enum'; +import { CellValueType } from '../types/enum'; /** * Snapshot of a workbook. @@ -378,12 +379,12 @@ export interface IFreeze { */ ySplit: number; /** - * scrollable start row + * scrollable start row(viewMain start row) */ startRow: number; /** - * scrollable start column + * scrollable start column(viewMain start column) */ startColumn: number; } diff --git a/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts b/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts index c6ea9bab01b..8b4a8dfe7af 100644 --- a/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts +++ b/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts @@ -1437,6 +1437,57 @@ export class SpreadsheetSkeleton extends SheetSkeleton { }; } + /** + * New version to get merge data. + * @param row + * @param column + * @returns {ISelectionCell} The cell info with merge data + */ + private _getCellMergeInfo(row: number, column: number): ISelectionCell { + return this.worksheet.getCellInfoInMergeData(row, column); + } + + getDistanceFromTopLeft(row: number, col: number): IPoint { + return { + x: this._offsetXToCol(col), + y: this._offsetYToRow(row), + }; + } + + /** + * Distance from top left to row + * @param row + */ + private _offsetYToRow(row: number): number { + const arr = this._rowHeightAccumulation; + const i = Math.max(0, row - 1); + return arr[i]; + } + + /** + * Distance from top left to col + * @param col + */ + private _offsetXToCol(col: number): number { + const arr = this._columnWidthAccumulation; + const i = Math.max(0, col - 1); + return arr[i]; + } + + colStartX(col: number): number { + const arr = this._columnWidthAccumulation; + const i = col - 1; + if(i == - 1) return 0; + return arr[i]; + } + + rowStartY(row: number): number { + const arr = this._rowHeightAccumulation; + const i = row - 1; + if(i == - 1) return 0; + return arr[i]; + } + getHiddenRowsInRange(range: IRowRange) { const hiddenRows = []; for (let i = range.startRow; i <= range.endRow; i++) { diff --git a/packages/engine-render/src/viewport.ts b/packages/engine-render/src/viewport.ts index 5fd6774051f..8863af89f54 100644 --- a/packages/engine-render/src/viewport.ts +++ b/packages/engine-render/src/viewport.ts @@ -206,7 +206,7 @@ export class Viewport { /** * bound of visible area */ - private _viewBound: IBoundRectNoAngle; + private _viewBound: IBoundRectNoAngle = { top: 0, left: 0, bottom: 0, right: 0 }; private _preViewBound: IBoundRectNoAngle; /** @@ -449,6 +449,9 @@ export class Viewport { this._active = false; } + /** + * canvas resize & freeze change would invoke this method + */ resetCanvasSizeAndUpdateScroll() { this._resizeCacheCanvas(); this._updateScrollByViewportScrollValue(); diff --git a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts index fcb37a562e5..291e5e36273 100644 --- a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts +++ b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts @@ -102,17 +102,21 @@ export interface ILimitBound extends IBoundRectNoAngle { /** * Adjust dom bound size when scrolling (dom bound would shrink when scrolling if over the edge of viewMain) - * @param posOfFloatObject + * @param posOfFloatObject The position of float object, relative to sheet content, scale & scrolling does not affect it. * @param scene * @param skeleton * @param worksheet * @returns ILimitBound */ +// eslint-disable-next-line max-lines-per-function export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, scene: Scene, skeleton: SpreadsheetSkeleton, worksheet: Worksheet, floatDomInfo?: ICanvasFloatDomInfo): ILimitBound { const { scaleX, scaleY } = scene.getAncestorScale(); const viewMain = scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN); + + const freeze = worksheet.getFreeze(); + const { startColumn: viewMainStartColumn, startRow: viewMainStartRow, xSplit: freezedCol, ySplit: freezedRow } = freeze; const absolute = { - left: true, + left: true, // left means the left of pic is in a viewMainLeft top: true, }; @@ -142,29 +146,108 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce viewportScrollX = 0; } - absolute.left = left * scaleX < leftOfViewMain; - const offsetLeft = absolute.left - ? leftOfViewMain * scaleX + (left - leftOfViewMain) * scaleX - : Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); - const offsetRight = right < leftOfViewMain - ? right * scaleX - : Math.max(leftOfViewMain, (right - viewportScrollX) * scaleX); - - absolute.top = top * scaleY < topOfViewMain; - const offsetTop = absolute.top - ? topOfViewMain * scaleY + (top - topOfViewMain) * scaleY - : Math.max((top - viewportScrollY) * scaleY, topOfViewMain); - const offsetBottom = bottom < topOfViewMain - ? bottom * scaleY - : Math.max(topOfViewMain, (bottom - viewportScrollY) * scaleY); + let offsetLeft: number = 0; + let offsetRight: number = 0; + + const freezeStartY = skeleton.rowStartY(viewMainStartRow - freezedRow); + const freezeStartX = skeleton.colStartX(viewMainStartColumn - freezedCol); + const freezeEndY = skeleton.rowStartY(viewMainStartRow); + const freezeEndX = skeleton.colStartX(viewMainStartColumn); + // const { x: freezeEndX, y: freezeEndY } = skeleton.getDistanceFromTopLeft(viewMainStartRow, viewMainStartColumn); + const { rowHeaderWidth, columnHeaderHeight } = skeleton; + + if (freezedCol === 0) { + console.log('freezedCol === 0'); + absolute.left = false; + offsetLeft = Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); + offsetRight = Math.max((right - viewportScrollX) * scaleX, leftOfViewMain); + } else { + // freeze + // viewMainLeft may not start at col = 0 + // DO NOT use viewMainLeft?.viewBound.right. It's not accurate. delay! + console.log('freezed', freezeEndX); + const leftToCanvas = left - freezeStartX;// - viewMainLeft.viewBound.left; + const rightToCanvas = right - freezeStartX;// - viewMainLeft.viewBound.left; + if (right < freezeEndX) { + console.log('freezed1'); + offsetLeft = leftToCanvas * scaleX; + offsetRight = rightToCanvas * scaleX; + } else if (left < freezeEndX && right > freezeEndX) { + console.log('freezed2'); + offsetLeft = leftToCanvas * scaleX; + offsetRight = Math.max(leftOfViewMain, (right - viewportScrollX) * scaleX); + } else if (left > freezeEndX) { + console.log('freezed3'); + absolute.left = false; + offsetLeft = Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); + offsetRight = Math.max((right - viewportScrollX) * scaleX, leftOfViewMain); + } + } + // if (left * scaleX < viewMain.viewBound.left) { + // absolute.left = true; + // offsetLeft = ((leftOfViewMain) + (left - leftOfViewMain)) * scaleX; + // offsetLeft = Math.max(leftOfViewMain, (left - viewportScrollX) * scaleX); + // if (right < leftOfViewMain) { + // offsetRight = right * scaleX; + // } else { + // offsetRight = Math.max(leftOfViewMain, (right - viewportScrollX) * scaleX); + // } + // } else { + // absolute.left = false; + // offsetLeft = Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); + // offsetRight = Math.max((right - viewportScrollX) * scaleX, leftOfViewMain); + // } + let offsetTop: number = 0; + let offsetBottom: number = 0; + if (freezedRow === 0) { + absolute.top = false; + offsetTop = Math.max((top - viewportScrollY) * scaleY, topOfViewMain); + offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, topOfViewMain); + } else { + console.log('freezed', freezeEndY); + const topToCanvas = top - freezeStartY;// - viewMainLeft.viewBound.left; + const bottomToCanvas = bottom - freezeStartY;// - viewMainLeft.viewBound.left; + if(bottom < freezeEndY) { + offsetTop = topToCanvas * scaleY; + offsetBottom = bottomToCanvas * scaleY; + } else if (top < freezeEndY && bottom > freezeEndY) { + offsetTop = topToCanvas * scaleY; + offsetBottom = Math.max(topOfViewMain, (bottom - viewportScrollY) * scaleY); + } else if (top > freezeEndY) { + absolute.top = false; + offsetTop = Math.max((top - viewportScrollY) * scaleY, topOfViewMain); + offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, topOfViewMain); + } + } - return { + // if (top * scaleY < topOfViewMain) { + // absolute.top = true; + // offsetTop = ((topOfViewMain) + (top - topOfViewMain)) * scaleY; + // if (bottom < topOfViewMain) { + // offsetBottom = bottom * scaleY; + // } else { + // offsetBottom = Math.max(topOfViewMain, (bottom - viewportScrollY) * scaleY); + // } + // } else { + // absolute.top = false; + // offsetTop = Math.max((top - viewportScrollY) * scaleY, topOfViewMain); + // offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, topOfViewMain); + // } + + offsetLeft = Math.max(offsetLeft, rowHeaderWidth); + offsetTop = Math.max(offsetTop, columnHeaderHeight); + offsetRight = Math.max(offsetRight, rowHeaderWidth); + offsetBottom = Math.max(offsetBottom, columnHeaderHeight); + + const rs = { left: offsetLeft, right: offsetRight, top: offsetTop, bottom: offsetBottom, absolute, }; + console.log('rs', rs); + return rs; } /** diff --git a/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts b/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts index 6e72d1fc888..b84bb40bfee 100644 --- a/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts +++ b/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts @@ -884,6 +884,36 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderM right: 0, }); viewMain.resetPadding(); + viewMainLeft.resizeWhenFreezeChange({ + left: rowHeaderWidthAndMarginLeft, + top: columnHeaderHeightAndMarginTop, + bottom: 0, + width: 0, + }); + viewMainTop.resizeWhenFreezeChange({ + left: rowHeaderWidthAndMarginLeft, + top: columnHeaderHeightAndMarginTop, + height: 0, + right: 0, + }); + viewMainLeftTop.resizeWhenFreezeChange({ + left: rowHeaderWidthAndMarginLeft, + top: columnHeaderHeightAndMarginTop, + width: 0, + height: 0, + }); + viewRowTop.resizeWhenFreezeChange({ + left: 0, + top: columnHeaderHeightAndMarginTop, + width: rowHeaderWidthAndMarginLeft, + height: 0, + }); + viewColumnLeft.resizeWhenFreezeChange({ + left: 0, + top: 0, + height: columnHeaderHeightAndMarginTop, + width: 0, + }); } else if (isTopView === true && isLeftView === false) { // freeze row const topGap = endSheetView.startY - startSheetView.startY; From 83012219d30bd0c96a8dc335201b36c3950540b3 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 11:43:59 +0800 Subject: [PATCH 3/8] fix: dom limit by spec viewBounds --- .../sheets/sheet.render-skeleton.ts | 44 ++----- .../canvas-float-dom-manager.service.ts | 115 +++++++----------- 2 files changed, 54 insertions(+), 105 deletions(-) diff --git a/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts b/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts index 8b4a8dfe7af..483b75c39fe 100644 --- a/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts +++ b/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts @@ -40,7 +40,7 @@ import type { } from '@univerjs/core'; import type { IDocumentSkeletonColumn } from '../../basics/i-document-skeleton-cached'; import type { ITransformChangeState } from '../../basics/interfaces'; -import type { IBoundRectNoAngle, IViewportInfo } from '../../basics/vector2'; +import type { IBoundRectNoAngle, IPoint, IViewportInfo } from '../../basics/vector2'; import type { Scene } from '../../scene'; import type { BorderCache, IFontCacheItem, IStylesCache } from './interfaces'; import { @@ -1437,54 +1437,24 @@ export class SpreadsheetSkeleton extends SheetSkeleton { }; } - /** - * New version to get merge data. - * @param row - * @param column - * @returns {ISelectionCell} The cell info with merge data - */ - private _getCellMergeInfo(row: number, column: number): ISelectionCell { - return this.worksheet.getCellInfoInMergeData(row, column); - } - getDistanceFromTopLeft(row: number, col: number): IPoint { return { - x: this._offsetXToCol(col), - y: this._offsetYToRow(row), + x: this.colStartX(col), + y: this.rowStartY(row), }; } - /** - * Distance from top left to row - * @param row - */ - private _offsetYToRow(row: number): number { - const arr = this._rowHeightAccumulation; - const i = Math.max(0, row - 1); - return arr[i]; - } - - /** - * Distance from top left to col - * @param col - */ - private _offsetXToCol(col: number): number { - const arr = this._columnWidthAccumulation; - const i = Math.max(0, col - 1); - return arr[i]; - } - colStartX(col: number): number { - const arr = this._columnWidthAccumulation; + const arr = this.columnWidthAccumulation; const i = col - 1; - if(i == - 1) return 0; + if (i === -1) return 0; return arr[i]; } rowStartY(row: number): number { - const arr = this._rowHeightAccumulation; + const arr = this.rowHeightAccumulation; const i = row - 1; - if(i == - 1) return 0; + if (i === -1) return 0; return arr[i]; } diff --git a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts index 291e5e36273..c9cc7457d79 100644 --- a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts +++ b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts @@ -94,6 +94,11 @@ export interface IDOMAnchor { } export interface ILimitBound extends IBoundRectNoAngle { + /** + * Actually, it means fixed. + * When left is true, dom is fixed to left of dom pos when dom width is shrinking. or dom is fixed to right of dom pos when dom width is shrinking. + * When top is true, dom is fixed to top of dom pos when dom height is shrinking. or dom is fixed to bottom of dom pos when dom height is shrinking. + */ absolute: { left: boolean; top: boolean; @@ -115,6 +120,9 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce const freeze = worksheet.getFreeze(); const { startColumn: viewMainStartColumn, startRow: viewMainStartRow, xSplit: freezedCol, ySplit: freezedRow } = freeze; + /** + * Actually, it means fixed. + */ const absolute = { left: true, // left means the left of pic is in a viewMainLeft top: true, @@ -127,16 +135,20 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce }; } const { left, right, top, bottom } = posOfFloatObject; - let { top: topOfViewMain, left: leftOfViewMain, viewportScrollX, viewportScrollY } = viewMain; + let { top: viewBoundsTop, left: viewBoundsLeft, viewportScrollX, viewportScrollY } = viewMain; // specify edge of viewbound. if not specify, use viewMain. - const { boundsOfViewArea, scrollDirectionResponse } = floatDomInfo || {}; - - if (boundsOfViewArea) { + const { boundsOfViewArea: specBoundsOfViewArea, scrollDirectionResponse } = floatDomInfo || {}; + const { rowHeaderWidth, columnHeaderHeight } = skeleton; + const boundsOfViewArea = { + top: columnHeaderHeight, + left: rowHeaderWidth, + }; + if (specBoundsOfViewArea) { if (Tools.isDefine(boundsOfViewArea.top)) { - topOfViewMain = boundsOfViewArea.top; + boundsOfViewArea.top = specBoundsOfViewArea.top; } if (Tools.isDefine(boundsOfViewArea.left)) { - leftOfViewMain = boundsOfViewArea.left; + boundsOfViewArea.left = specBoundsOfViewArea.left; } } if (scrollDirectionResponse === ScrollDirectionResponse.HORIZONTAL) { @@ -153,91 +165,56 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce const freezeStartX = skeleton.colStartX(viewMainStartColumn - freezedCol); const freezeEndY = skeleton.rowStartY(viewMainStartRow); const freezeEndX = skeleton.colStartX(viewMainStartColumn); - // const { x: freezeEndX, y: freezeEndY } = skeleton.getDistanceFromTopLeft(viewMainStartRow, viewMainStartColumn); - const { rowHeaderWidth, columnHeaderHeight } = skeleton; if (freezedCol === 0) { - console.log('freezedCol === 0'); absolute.left = false; - offsetLeft = Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); - offsetRight = Math.max((right - viewportScrollX) * scaleX, leftOfViewMain); + offsetLeft = (left - viewportScrollX) * scaleX; + offsetRight = (right - viewportScrollX) * scaleX; } else { // freeze // viewMainLeft may not start at col = 0 - // DO NOT use viewMainLeft?.viewBound.right. It's not accurate. delay! - console.log('freezed', freezeEndX); + // DO NOT use viewMainLeft?.viewBound.right. It's not accurate. there is a delay to set viewBound! const leftToCanvas = left - freezeStartX;// - viewMainLeft.viewBound.left; const rightToCanvas = right - freezeStartX;// - viewMainLeft.viewBound.left; if (right < freezeEndX) { - console.log('freezed1'); offsetLeft = leftToCanvas * scaleX; offsetRight = rightToCanvas * scaleX; } else if (left < freezeEndX && right > freezeEndX) { - console.log('freezed2'); offsetLeft = leftToCanvas * scaleX; - offsetRight = Math.max(leftOfViewMain, (right - viewportScrollX) * scaleX); + offsetRight = Math.max(viewBoundsLeft, (right - viewportScrollX) * scaleX); } else if (left > freezeEndX) { - console.log('freezed3'); absolute.left = false; - offsetLeft = Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); - offsetRight = Math.max((right - viewportScrollX) * scaleX, leftOfViewMain); + offsetLeft = Math.max((left - viewportScrollX) * scaleX, viewBoundsLeft); + offsetRight = Math.max((right - viewportScrollX) * scaleX, viewBoundsLeft); } } - // if (left * scaleX < viewMain.viewBound.left) { - // absolute.left = true; - // offsetLeft = ((leftOfViewMain) + (left - leftOfViewMain)) * scaleX; - // offsetLeft = Math.max(leftOfViewMain, (left - viewportScrollX) * scaleX); - // if (right < leftOfViewMain) { - // offsetRight = right * scaleX; - // } else { - // offsetRight = Math.max(leftOfViewMain, (right - viewportScrollX) * scaleX); - // } - // } else { - // absolute.left = false; - // offsetLeft = Math.max((left - viewportScrollX) * scaleX, leftOfViewMain); - // offsetRight = Math.max((right - viewportScrollX) * scaleX, leftOfViewMain); - // } + let offsetTop: number = 0; let offsetBottom: number = 0; if (freezedRow === 0) { absolute.top = false; - offsetTop = Math.max((top - viewportScrollY) * scaleY, topOfViewMain); - offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, topOfViewMain); + offsetTop = (top - viewportScrollY) * scaleY; + offsetBottom = (bottom - viewportScrollY) * scaleY; } else { - console.log('freezed', freezeEndY); - const topToCanvas = top - freezeStartY;// - viewMainLeft.viewBound.left; - const bottomToCanvas = bottom - freezeStartY;// - viewMainLeft.viewBound.left; - if(bottom < freezeEndY) { + const topToCanvas = top - freezeStartY; + const bottomToCanvas = bottom - freezeStartY; + if (bottom < freezeEndY) { offsetTop = topToCanvas * scaleY; offsetBottom = bottomToCanvas * scaleY; } else if (top < freezeEndY && bottom > freezeEndY) { offsetTop = topToCanvas * scaleY; - offsetBottom = Math.max(topOfViewMain, (bottom - viewportScrollY) * scaleY); + offsetBottom = Math.max(viewBoundsTop, (bottom - viewportScrollY) * scaleY); } else if (top > freezeEndY) { absolute.top = false; - offsetTop = Math.max((top - viewportScrollY) * scaleY, topOfViewMain); - offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, topOfViewMain); + offsetTop = Math.max((top - viewportScrollY) * scaleY, viewBoundsTop); + offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, viewBoundsTop); } } - // if (top * scaleY < topOfViewMain) { - // absolute.top = true; - // offsetTop = ((topOfViewMain) + (top - topOfViewMain)) * scaleY; - // if (bottom < topOfViewMain) { - // offsetBottom = bottom * scaleY; - // } else { - // offsetBottom = Math.max(topOfViewMain, (bottom - viewportScrollY) * scaleY); - // } - // } else { - // absolute.top = false; - // offsetTop = Math.max((top - viewportScrollY) * scaleY, topOfViewMain); - // offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, topOfViewMain); - // } - - offsetLeft = Math.max(offsetLeft, rowHeaderWidth); - offsetTop = Math.max(offsetTop, columnHeaderHeight); - offsetRight = Math.max(offsetRight, rowHeaderWidth); - offsetBottom = Math.max(offsetBottom, columnHeaderHeight); + offsetLeft = Math.max(offsetLeft, boundsOfViewArea.left); + offsetTop = Math.max(offsetTop, boundsOfViewArea.top); + offsetRight = Math.max(offsetRight, boundsOfViewArea.left); + offsetBottom = Math.max(offsetBottom, boundsOfViewArea.top); const rs = { left: offsetLeft, @@ -246,7 +223,6 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce bottom: offsetBottom, absolute, }; - console.log('rs', rs); return rs; } @@ -789,6 +765,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable { }; } + // eslint-disable-next-line max-lines-per-function, complexity addFloatDomToRange(range: IRange, config: ICanvasFloatDom, domAnchor: Partial, propId?: string) { const target = getSheetCommandTarget(this._univerInstanceService, { unitId: config.unitId, @@ -857,8 +834,8 @@ export class SheetCanvasFloatDomManagerService extends Disposable { if (!skMangerService) { return; } - const skeleton = skMangerService.getWorksheetSkeleton(subUnitId); - if (!skeleton) { + const skeletonParam = skMangerService.getWorksheetSkeleton(subUnitId); + if (!skeletonParam) { return; } @@ -931,9 +908,11 @@ export class SheetCanvasFloatDomManagerService extends Disposable { const disposableCollection = new DisposableCollection(); const viewMain = scene.getMainViewport(); + const { rowHeaderWidth, columnHeaderHeight } = skeletonParam.skeleton; + const boundsOfViewArea: IBoundRectNoAngle = { - top: viewMain.top, - left: viewMain.left, + top: columnHeaderHeight, + left: rowHeaderWidth, bottom: viewMain.bottom, right: viewMain.right, }; @@ -947,7 +926,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable { subUnitId, } as unknown as ICanvasFloatDomInfo; - const initedPosition = calcPosition(domRect, renderObject.renderUnit, skeleton.skeleton, target.worksheet, floatDomInfo); + const initedPosition = calcPosition(domRect, renderObject.renderUnit, skeletonParam.skeleton, target.worksheet, floatDomInfo); const position$ = new BehaviorSubject(initedPosition); floatDomInfo.position$ = position$; @@ -1004,7 +983,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable { height: domAnchor.height ?? newRangePos.height, zIndex: this._drawingManagerService.getDrawingOrder(unitId, subUnitId).length - 1, }); - const newPos = calcPosition(newRect, renderObject.renderUnit, skeleton.skeleton, target.worksheet, floatDomInfo); + const newPos = calcPosition(newRect, renderObject.renderUnit, skeletonParam.skeleton, target.worksheet, floatDomInfo); position$.next(newPos); })); const skm = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService); @@ -1017,7 +996,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable { }); const listener = domRect.onTransformChange$.subscribeEvent(() => { - const newPosition = calcPosition(domRect, renderObject.renderUnit, skeleton.skeleton, target.worksheet, floatDomInfo); + const newPosition = calcPosition(domRect, renderObject.renderUnit, skeletonParam.skeleton, target.worksheet, floatDomInfo); position$.next( newPosition ); From 2edfc94d6c5f1dd67d733f84358869da99e881db Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 15:08:57 +0800 Subject: [PATCH 4/8] chore: better code --- packages/engine-render/src/viewport.ts | 6 ------ .../render-controllers/sheet.render-controller.ts | 2 ++ .../src/services/sheet-skeleton-manager.service.ts | 4 ++++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/engine-render/src/viewport.ts b/packages/engine-render/src/viewport.ts index 8863af89f54..677bda31797 100644 --- a/packages/engine-render/src/viewport.ts +++ b/packages/engine-render/src/viewport.ts @@ -354,8 +354,6 @@ export class Viewport { set viewportScrollY(val: number) { this._viewportScrollY = val; - // const { y } = this.transViewportScroll2ScrollValue(this._viewportScrollX, this._viewportScrollY); - // this.scrollY = y; } get viewportScrollY() { @@ -364,14 +362,10 @@ export class Viewport { set scrollX(val: number) { this._scrollX = val; - // const { x } = this.transScroll2ViewportScrollValue(this._scrollX, this._scrollY); - // this._viewportScrollX = x; } set scrollY(val: number) { this._scrollY = val; - // const { y } = this.transScroll2ViewportScrollValue(this._scrollX, this._scrollY); - // this._viewportScrollY = y; } get scrollX() { diff --git a/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts b/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts index 6545fc43d0c..d566a818dba 100644 --- a/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts +++ b/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts @@ -413,6 +413,8 @@ export class SheetRenderController extends RxDisposable implements IRenderModule commandId, }, true); + // TODO @lumixraku + // This is insane !!! Tons changes would call sk.setCurrent. this._sheetSkeletonManagerService.setCurrent({ sheetId: worksheetId, commandId, diff --git a/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts b/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts index df0cc75c7c8..52e94633ccc 100644 --- a/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts +++ b/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts @@ -131,6 +131,10 @@ export class SheetSkeletonManagerService extends Disposable implements IRenderMo return param; } + /** + * Command in COMMAND_LISTENER_SKELETON_CHANGE would cause setCurrent, see @packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts + * @param searchParam + */ setCurrent(searchParam: ISheetSkeletonManagerSearch): Nullable { this._setCurrent(searchParam.sheetId); } From 92bd061c036dffb375c3153ca94459eb98f4b81c Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 15:22:59 +0800 Subject: [PATCH 5/8] fix: bug by changing the judgment condition from < to <= --- .../canvas-float-dom-manager.service.ts | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts index c9cc7457d79..c22c36ad184 100644 --- a/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts +++ b/packages/sheets-drawing-ui/src/services/canvas-float-dom-manager.service.ts @@ -161,10 +161,13 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce let offsetLeft: number = 0; let offsetRight: number = 0; - const freezeStartY = skeleton.rowStartY(viewMainStartRow - freezedRow); - const freezeStartX = skeleton.colStartX(viewMainStartColumn - freezedCol); - const freezeEndY = skeleton.rowStartY(viewMainStartRow); - const freezeEndX = skeleton.colStartX(viewMainStartColumn); + /** + * freezed viewport start & end position + */ + const freezeStartY = skeleton.rowStartY(viewMainStartRow - freezedRow) + columnHeaderHeight; + const freezeStartX = skeleton.colStartX(viewMainStartColumn - freezedCol) + rowHeaderWidth; + const freezeEndY = skeleton.rowStartY(viewMainStartRow) + columnHeaderHeight; + const freezeEndX = skeleton.colStartX(viewMainStartColumn) + rowHeaderWidth; if (freezedCol === 0) { absolute.left = false; @@ -174,12 +177,12 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce // freeze // viewMainLeft may not start at col = 0 // DO NOT use viewMainLeft?.viewBound.right. It's not accurate. there is a delay to set viewBound! - const leftToCanvas = left - freezeStartX;// - viewMainLeft.viewBound.left; - const rightToCanvas = right - freezeStartX;// - viewMainLeft.viewBound.left; + const leftToCanvas = left - (freezeStartX - rowHeaderWidth); + const rightToCanvas = right - (freezeStartX - rowHeaderWidth); if (right < freezeEndX) { offsetLeft = leftToCanvas * scaleX; offsetRight = rightToCanvas * scaleX; - } else if (left < freezeEndX && right > freezeEndX) { + } else if (left <= freezeEndX && right >= freezeEndX) { offsetLeft = leftToCanvas * scaleX; offsetRight = Math.max(viewBoundsLeft, (right - viewportScrollX) * scaleX); } else if (left > freezeEndX) { @@ -196,12 +199,12 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce offsetTop = (top - viewportScrollY) * scaleY; offsetBottom = (bottom - viewportScrollY) * scaleY; } else { - const topToCanvas = top - freezeStartY; - const bottomToCanvas = bottom - freezeStartY; + const topToCanvas = top - (freezeStartY - columnHeaderHeight); + const bottomToCanvas = bottom - (freezeStartY - columnHeaderHeight); if (bottom < freezeEndY) { offsetTop = topToCanvas * scaleY; offsetBottom = bottomToCanvas * scaleY; - } else if (top < freezeEndY && bottom > freezeEndY) { + } else if (top <= freezeEndY && bottom >= freezeEndY) { offsetTop = topToCanvas * scaleY; offsetBottom = Math.max(viewBoundsTop, (bottom - viewportScrollY) * scaleY); } else if (top > freezeEndY) { From 0ccce69698b7f3746fbd63bd7464a25f2110c904 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 15:47:24 +0800 Subject: [PATCH 6/8] chore: better code --- packages/core/src/index.ts | 1 + .../sheets-ui/src/services/sheet-skeleton-manager.service.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 0d76eace4e3..f7ddce93bf1 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -204,3 +204,4 @@ export { isNodeEnv } from './shared/tools'; export { Skeleton } from './skeleton.ts'; export type { IGetRowColByPosOptions } from './sheets/sheet-skeleton'; export type { IPosition } from './sheets/typedef.ts'; +export * from './sheets/sheet-skeleton'; diff --git a/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts b/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts index 52e94633ccc..f4dda865f54 100644 --- a/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts +++ b/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts @@ -44,7 +44,7 @@ export interface ISheetSkeletonManagerSearch { export class SheetSkeletonManagerService extends Disposable implements IRenderModule { private _sheetId: string = ''; - // @TODO lumixraku, why need this? How about put dirty & sheetId & unitId in skeleton itself z? + // @TODO lumixraku, why need this? How about put dirty & sheetId & unitId in skeleton itself? private _sheetSkeletonParamStore: Map = new Map(); private readonly _currentSkeleton$ = new BehaviorSubject>(null); From 7d1cd0980d9a1c100f01b741fb67f78cdc557482 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 16:35:51 +0800 Subject: [PATCH 7/8] fix: mem leak --- .../sheets-ui/src/services/sheet-skeleton-manager.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts b/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts index f4dda865f54..28ba3b57c06 100644 --- a/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts +++ b/packages/sheets-ui/src/services/sheet-skeleton-manager.service.ts @@ -68,6 +68,7 @@ export class SheetSkeletonManagerService extends Disposable implements IRenderMo this._currentSkeletonBefore$.complete(); this._currentSkeleton$.complete(); this._sheetSkeletonParamStore = new Map(); + this._sheetSkService.deleteSkeleton(this._context.unitId, this._sheetId); }); this._initRemoveSheet(); From 4acf22b98b4de59cc8e1f5840bf3045ab7bafcf9 Mon Sep 17 00:00:00 2001 From: lumixraku Date: Fri, 7 Feb 2025 16:39:32 +0800 Subject: [PATCH 8/8] fix: get renderUnit by Id not type --- .../controllers/format-painter/format-painter.controller.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/sheets-ui/src/controllers/format-painter/format-painter.controller.ts b/packages/sheets-ui/src/controllers/format-painter/format-painter.controller.ts index 34d00434aeb..a8ce5da6c82 100644 --- a/packages/sheets-ui/src/controllers/format-painter/format-painter.controller.ts +++ b/packages/sheets-ui/src/controllers/format-painter/format-painter.controller.ts @@ -59,7 +59,10 @@ export class FormatPainterController extends Disposable { } private _commandExecutedListener() { - const selectionRenderService = this._renderManagerService.getCurrentTypeOfRenderer(UniverInstanceType.UNIVER_SHEET)!.with(ISheetSelectionRenderService); + const unitId = this._univerInstanceService.getFocusedUnit()?.getUnitId() || ''; + const renderUnit = this._renderManagerService.getRenderById(unitId); + if (!renderUnit) return; + const selectionRenderService = renderUnit.with(ISheetSelectionRenderService); this.disposeWithMe( selectionRenderService.selectionMoveEnd$.subscribe((selections) => {