Skip to content

Commit

Permalink
feat: add image cell icon
Browse files Browse the repository at this point in the history
  • Loading branch information
Rui-Sun committed Jul 3, 2024
1 parent cfcdeee commit 1738d23
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 9 deletions.
5 changes: 5 additions & 0 deletions packages/vtable/src/event/media-click.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export function bindMediaClick(table: BaseTableAPI): void {
table.on(TABLE_EVENT_TYPE.CLICK_CELL, (e: MousePointerCellEvent) => {
//如果目前是在某个icon上,如收起展开按钮 则不进行其他点击逻辑
const { col, row } = e;

if (e.target.type === 'image' && (e.target as any).role && (e.target as any).role.startsWith('icon')) {
// click icon
return;
}
let cellType;
if (table.internalProps.layoutMap.isHeader(col, row)) {
cellType = table.isPivotTable()
Expand Down
4 changes: 4 additions & 0 deletions packages/vtable/src/scenegraph/group-creater/cell-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,10 @@ export function createCell(
padding,
textAlign,
textBaseline,
mayHaveIcon,
table,
cellTheme,
range,
isAsync
);
} else if (type === 'video') {
Expand All @@ -235,8 +237,10 @@ export function createCell(
padding,
textAlign,
textBaseline,
mayHaveIcon,
table,
cellTheme,
range,
isAsync
);
} else if (type === 'chart') {
Expand Down
102 changes: 96 additions & 6 deletions packages/vtable/src/scenegraph/group-creater/cell-type/image-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { isValid } from '@visactor/vutils';
import { getQuadProps } from '../../utils/padding';
import { getCellBorderStrokeWidth } from '../../utils/cell-border-stroke-width';
import type { BaseTableAPI } from '../../../ts-types/base-table';
import type { CellRange } from '../../../ts-types';
import { dealWithIconLayout } from '../../utils/text-icon-layout';

export function createImageCellGroup(
columnGroup: Group,
Expand All @@ -25,8 +27,10 @@ export function createImageCellGroup(
padding: [number, number, number, number],
textAlign: CanvasTextAlign,
textBaseline: CanvasTextBaseline,
mayHaveIcon: boolean,
table: BaseTableAPI,
cellTheme: IThemeSpec,
range: CellRange | undefined,
isAsync: boolean
) {
const headerStyle = table._getCellStyle(col, row); // to be fixed
Expand Down Expand Up @@ -94,12 +98,64 @@ export function createImageCellGroup(
columnGroup?.addCellGroup(cellGroup);
}

let cellIcons;
if (mayHaveIcon) {
let iconCol = col;
let iconRow = row;
if (range) {
iconCol = range.start.col;
iconRow = range.start.row;
}
cellIcons = table.getCellIcons(iconCol, iconRow);
}

let iconWidth = 0;
let cellLeftIconWidth = 0;
let cellRightIconWidth = 0;
if (Array.isArray(cellIcons) && cellIcons.length !== 0) {
const { leftIconWidth, rightIconWidth, absoluteLeftIconWidth, absoluteRightIconWidth } = dealWithIconLayout(
cellIcons,
cellGroup,
range,
table
);

iconWidth = leftIconWidth + rightIconWidth;
cellLeftIconWidth = leftIconWidth;
cellRightIconWidth = rightIconWidth;

// 更新各个部分横向位置
cellGroup.forEachChildren((child: any) => {
if (child.role === 'icon-left') {
child.setAttribute('x', child.attribute.x + padding[3]);
} else if (child.role === 'icon-right') {
child.setAttribute('x', child.attribute.x + width - rightIconWidth - padding[1]);
} else if (child.role === 'icon-absolute-right') {
child.setAttribute('x', child.attribute.x + width - absoluteRightIconWidth - padding[1]);
}
});

// 更新各个部分纵向位置
cellGroup.forEachChildren((child: any) => {
if (textBaseline === 'middle') {
child.setAttribute('y', (height - child.AABBBounds.height()) / 2);
} else if (textBaseline === 'bottom') {
child.setAttribute('y', height - child.AABBBounds.height() - padding[2]);
} else {
child.setAttribute('y', padding[0]);
}
});

(cellGroup as any)._cellLeftIconWidth = cellLeftIconWidth;
(cellGroup as any)._cellRightIconWidth = cellRightIconWidth;
}

// image
const value = table.getCellValue(col, row);
const image: IImage = createImage({
x: padding[3],
y: padding[0],
width: width - padding[1] - padding[3],
width: width - padding[1] - padding[3] - iconWidth,
height: height - padding[0] - padding[2],
image: value, //?? (regedIcons.damage_pic as any).svg,
cursor: 'pointer' as Cursor
Expand Down Expand Up @@ -147,10 +203,10 @@ export function createImageCellGroup(
image.resources.has(image.attribute.image) &&
image.resources.get(image.attribute.image).state === 'success'
) {
updateImageCellContentWhileResize(cellGroup, col, row, table);
updateImageCellContentWhileResize(cellGroup, col, row, 0, 0, table);
} else {
image.successCallback = () => {
updateImageCellContentWhileResize(cellGroup, col, row, table);
updateImageCellContentWhileResize(cellGroup, col, row, 0, 0, table);
};
}
}
Expand Down Expand Up @@ -231,7 +287,14 @@ export function _adjustWidthHeight(
return false;
}

export function updateImageCellContentWhileResize(cellGroup: Group, col: number, row: number, table: BaseTableAPI) {
export function updateImageCellContentWhileResize(
cellGroup: Group,
col: number,
row: number,
deltaX: number,
deltaY: number,
table: BaseTableAPI
) {
const image = cellGroup.getChildByName('image') as Image;
if (!image) {
return;
Expand Down Expand Up @@ -260,6 +323,9 @@ export function updateImageCellContentWhileResize(cellGroup: Group, col: number,
const colEnd = cellGroup.mergeEndCol ?? cellGroup.col;
const rowEnd = cellGroup.mergeEndCol ?? cellGroup.row;

const leftIconWidth = (cellGroup as any)._cellLeftIconWidth ?? 0;
const rightIconWidth = (cellGroup as any)._cellRightIconWidth ?? 0;

if ((image as any).keepAspectRatio) {
const { width: imageWidth, height: imageHeight } = calcKeepAspectRatioSize(
originImage.width || (originImage as any).videoWidth,
Expand Down Expand Up @@ -302,11 +368,11 @@ export function updateImageCellContentWhileResize(cellGroup: Group, col: number,
const cellGroup = table.scenegraph.getCell(col, row);
const image = cellGroup.getChildByName('image') as Image;
image?.setAttributes({
x: padding[3],
x: leftIconWidth + padding[3],
y: padding[0],
// width: cellGroup.attribute.width - padding[1] - padding[3],
// height: cellGroup.attribute.height - padding[0] - padding[2]
width: cellWidth - padding[1] - padding[3],
width: cellWidth - padding[1] - padding[3] - rightIconWidth - leftIconWidth,
height: cellHeight - padding[0] - padding[2]
});
}
Expand Down Expand Up @@ -341,6 +407,30 @@ export function updateImageCellContentWhileResize(cellGroup: Group, col: number,
}
}

// 更新x方向位置
cellGroup.forEachChildren((child: any) => {
if (child.role === 'icon-left') {
// do nothing
} else if (child.role === 'icon-right') {
child.setAttribute('x', child.attribute.x + deltaX);
} else if (child.role === 'icon-absolute-right') {
child.setAttribute('x', child.attribute.x + deltaX);
}
});

// 更新y方向位置
cellGroup.forEachChildren((child: any) => {
if (child.type !== 'rect' && (!child.role || !child.role.startsWith('icon'))) {
// do nothing
} else if (textBaseline === 'middle') {
child.setAttribute('y', padding[0] + (cellHeight - padding[0] - padding[2] - child.AABBBounds.height()) / 2);
} else if (textBaseline === 'bottom') {
child.setAttribute('y', padding[0] + cellHeight - padding[0] - padding[2] - child.AABBBounds.height());
} else {
child.setAttribute('y', padding[0]);
}
});

if (isMerge) {
updateImageDxDy(
cellGroup.mergeStartCol,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { isValid } from '@visactor/vutils';
import type { BaseTableAPI } from '../../../ts-types/base-table';
import { getCellBorderStrokeWidth } from '../../utils/cell-border-stroke-width';
import { getQuadProps } from '../../utils/padding';
import type { CellRange } from '../../../ts-types';
import { dealWithIconLayout } from '../../utils/text-icon-layout';

const regedIcons = icons.get();

Expand All @@ -28,8 +30,10 @@ export function createVideoCellGroup(
padding: [number, number, number, number],
textAlign: CanvasTextAlign,
textBaseline: CanvasTextBaseline,
mayHaveIcon: boolean,
table: BaseTableAPI,
cellTheme: IThemeSpec,
range: CellRange | undefined,
isAsync: boolean
) {
const headerStyle = table._getCellStyle(col, row); // to be fixed
Expand Down Expand Up @@ -97,6 +101,58 @@ export function createVideoCellGroup(
columnGroup?.addCellGroup(cellGroup);
}

let cellIcons;
if (mayHaveIcon) {
let iconCol = col;
let iconRow = row;
if (range) {
iconCol = range.start.col;
iconRow = range.start.row;
}
cellIcons = table.getCellIcons(iconCol, iconRow);
}

let iconWidth = 0;
let cellLeftIconWidth = 0;
let cellRightIconWidth = 0;
if (Array.isArray(cellIcons) && cellIcons.length !== 0) {
const { leftIconWidth, rightIconWidth, absoluteLeftIconWidth, absoluteRightIconWidth } = dealWithIconLayout(
cellIcons,
cellGroup,
range,
table
);

iconWidth = leftIconWidth + rightIconWidth;
cellLeftIconWidth = leftIconWidth;
cellRightIconWidth = rightIconWidth;

// 更新各个部分横向位置
cellGroup.forEachChildren((child: any) => {
if (child.role === 'icon-left') {
child.setAttribute('x', child.attribute.x + padding[3]);
} else if (child.role === 'icon-right') {
child.setAttribute('x', child.attribute.x + width - rightIconWidth - padding[1]);
} else if (child.role === 'icon-absolute-right') {
child.setAttribute('x', child.attribute.x + width - absoluteRightIconWidth - padding[1]);
}
});

// 更新各个部分纵向位置
cellGroup.forEachChildren((child: any) => {
if (textBaseline === 'middle') {
child.setAttribute('y', (height - child.AABBBounds.height()) / 2);
} else if (textBaseline === 'bottom') {
child.setAttribute('y', height - child.AABBBounds.height() - padding[2]);
} else {
child.setAttribute('y', padding[0]);
}
});

(cellGroup as any)._cellLeftIconWidth = cellLeftIconWidth;
(cellGroup as any)._cellRightIconWidth = cellRightIconWidth;
}

// video
const value = table.getCellValue(col, row);
const video = document.createElement('video');
Expand Down
2 changes: 1 addition & 1 deletion packages/vtable/src/scenegraph/layout/update-height.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export function updateCellHeight(
false
);
} else if (type === 'image' || type === 'video') {
updateImageCellContentWhileResize(cell, col, row, scene.table);
updateImageCellContentWhileResize(cell, col, row, 0, detaY, scene.table);
} else if (cell.firstChild?.name === 'axis') {
(cell.firstChild as any)?.originAxis.resize(cell.attribute.width, cell.attribute.height);
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/vtable/src/scenegraph/layout/update-width.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ function updateCellWidth(
// // 只更新背景边框
// const rect = cell.firstChild as Rect;
// rect.setAttribute('width', cell.attribute.width);
updateImageCellContentWhileResize(cellGroup, col, row, scene.table);
updateImageCellContentWhileResize(cellGroup, col, row, detaX, 0, scene.table);
} else if (cellGroup.firstChild?.name === 'axis') {
// recreate axis component
const axisConfig = scene.table.internalProps.layoutMap.getAxisConfigInPivotChart(col, row);
Expand Down
2 changes: 1 addition & 1 deletion packages/vtable/src/scenegraph/scenegraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1544,7 +1544,7 @@ export class Scenegraph {
const type = this.table.getBodyColumnType(col, row);
const cellGroup = this.getCell(col, row);
if (type === 'image' || type === 'video') {
updateImageCellContentWhileResize(cellGroup, col, row, this.table);
updateImageCellContentWhileResize(cellGroup, col, row, 0, 0, this.table);
}
}

Expand Down

0 comments on commit 1738d23

Please sign in to comment.