Skip to content

Commit

Permalink
feat: TopView Performance Optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
Original-Recipe committed Dec 16, 2024
1 parent 17f5e84 commit 0626862
Show file tree
Hide file tree
Showing 12 changed files with 408 additions and 308 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class BasicToolOperation extends EventListener {

public zoomInfo = DEFAULT_ZOOM_INFO;

public offscreenCanvas!: HTMLCanvasElement;

constructor(props: IBasicToolOperationProps) {
super();
this.container = props.container;
Expand Down Expand Up @@ -265,6 +267,10 @@ class BasicToolOperation extends EventListener {
return this.basicCanvas?.getContext('2d');
}

get offscreenCtx() {
return this.offscreenCanvas?.getContext('2d');
}

get rotate() {
return this.basicImgInfo?.rotate ?? 0;
}
Expand Down Expand Up @@ -420,23 +426,29 @@ class BasicToolOperation extends EventListener {
const canvas = document.createElement('canvas');
this.updateCanvasBasicStyle(canvas, size, 10);

const offscreenCanvas = document.createElement('canvas');
this.updateCanvasBasicStyle(offscreenCanvas, size, 20);

// set Attribute
// this.container.style.position = 'relative';

if (isAppend) {
if (this.container.hasChildNodes()) {
this.container.insertBefore(offscreenCanvas, this.container.childNodes[0]);
this.container.insertBefore(canvas, this.container.childNodes[0]);
this.container.insertBefore(basicCanvas, this.container.childNodes[0]);
} else {
this.container.appendChild(basicCanvas);
this.container.appendChild(canvas);
this.container.appendChild(offscreenCanvas);
}
}

this.offscreenCanvas = offscreenCanvas;
this.canvas = canvas;
this.container.style.cursor = this.defaultCursor;
this.ctx?.scale(pixel, pixel);
this.basicCtx?.scale(pixel, pixel);
this.offscreenCtx?.scale(pixel, pixel);
if (this.ctx) {
this.ctx.imageSmoothingEnabled = false;
}
Expand All @@ -452,6 +464,10 @@ class BasicToolOperation extends EventListener {
this.container.removeChild(this.basicCanvas);
}

if (this.offscreenCanvas && this.container.contains(this.offscreenCanvas)) {
this.container.removeChild(this.offscreenCanvas);
}

// 恢复初始状态
this.clearInvalidPage();
this.clearImgDrag();
Expand Down Expand Up @@ -821,6 +837,10 @@ class BasicToolOperation extends EventListener {
this.basicCtx?.clearRect(0, 0, this.size.width, this.size.height);
}

public clearOffscreenCanvas() {
this.offscreenCtx?.clearRect(0, 0, this.size.width, this.size.height);
}

/** 事件绑定 */
public eventBinding() {
this.dblClickListener.addEvent(() => {}, this.onLeftDblClick, this.onRightDblClick);
Expand Down Expand Up @@ -883,7 +903,7 @@ class BasicToolOperation extends EventListener {
}
}

public onMouseMove(e: MouseEvent): boolean | void {
public onMouseMove(e: MouseEvent, isRender: boolean = true): boolean | void {
if (!this.canvas || this.isImgError) {
return true;
}
Expand Down Expand Up @@ -915,8 +935,9 @@ class BasicToolOperation extends EventListener {
// 拖拽信息触发
this.emit('dragMove', { currentPos, zoom: this.zoom, imgInfo: this.imgInfo });
}

this.render();
if (isRender) {
this.render();
}
} catch (error) {
console.error(error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,14 @@ class PointCloud2dOperation extends PolygonOperation {
};

public renderdrawTrackID(polygon: IPolygonData) {
const pointList = AxisUtils.changePointListByZoom(polygon.pointList, this.zoom, this.currentPos);
const endPoint = pointList[pointList.length - 1];
const trackID = polygon?.trackID;
DrawUtils.drawText(this.canvas, endPoint, `${trackID}`, {
if (!polygon?.pointList?.length) return; // 保护性校验

// 提取点云数据最后一个点并进行变换
const lastPoint = polygon.pointList[polygon.pointList.length - 1];
const transformedPoint = AxisUtils.changePointByZoom(lastPoint, this.zoom, this.currentPos);

const trackID = polygon?.trackID?.toString() || ''; // 确保trackID是字符串
DrawUtils.drawText(this.canvas, transformedPoint, trackID, {
textAlign: 'center',
color: 'white',
...DEFAULT_TEXT_OFFSET,
Expand Down
177 changes: 116 additions & 61 deletions packages/lb-annotation/src/core/toolOperation/polygonOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,6 @@ class PolygonOperation extends BasicToolOperation {
this.dragInfo!.dragPrevCoord = this.getCoordinateUnderZoom(e);

this.setPolygonList(newPolygonList);
this.render();
}

/**
Expand Down Expand Up @@ -1397,44 +1396,85 @@ class PolygonOperation extends BasicToolOperation {
return selectedPointList;
}

public onMouseMove(e: MouseEvent) {
if (super.onMouseMove(e) || this.forbidMouseOperation || !this.imgInfo) {
return;
private lastMouseMoveTime = 0; // 记录上次鼠标移动的时间

private mouseMoveThrottle = 16; // 节流时间(毫秒)

private determineTrigger(e: MouseEvent): string {
if (this.isDrag) {
return 'drag';
}

if (this.dragInfo) {
return 'dragSingle';
}

let trigger = '';
const newHoverID = this.getHoverID(e);
if (this.hoverID !== newHoverID) {
this.hoverID = newHoverID;
trigger = '';
} else {
trigger = 'move';
}

let hoverPointIndex = -1;
let hoverEdgeIndex = -1;

// 高亮逻辑判断完毕后需要判断当前选中的状态更新逻辑
const { selectedID } = this;
if (selectedID) {
this.hoverEdgeIndex = -1;
this.hoverPointIndex = -1;

hoverPointIndex = this.getHoverPointIndex(e);

// 注意: 点的优先级大于边
if (hoverPointIndex > -1) {
this.hoverPointIndex = hoverPointIndex;
if (this.hoverPointIndex !== hoverPointIndex) {
trigger = '';
} else {
// 在同一个点上进行移动的时候不需要更新和渲染
trigger = 'noRender';
}
} else {
hoverEdgeIndex = this.getHoverEdgeIndex(e);
this.hoverEdgeIndex = hoverEdgeIndex;
if (this.hoverEdgeIndex !== hoverEdgeIndex) {
trigger = '';
} else {
// 在同一条边上进行移动的时候不需要更新和渲染
trigger = 'noRender';
}
}
this.hoverEdgeIndex = hoverEdgeIndex;
this.hoverPointIndex = hoverPointIndex;
}

if (this.drawingPointList.length > 0) {
// 编辑中无需 hover操作
return;
}
return trigger;
}

const newHoverID = this.getHoverID(e);
if (this.hoverID !== newHoverID) {
this.hoverID = newHoverID;
this.render();
}
public onMouseMove(e: MouseEvent) {
requestAnimationFrame(() => {
const now = Date.now();

if (this.selectedIDs.length > 0 && this.dragInfo) {
this.onDragMove(e);
}
// 节流:如果上次调用时间未超过设定的时间间隔,则跳过
if (now - this.lastMouseMoveTime < this.mouseMoveThrottle) {
return;
}
this.lastMouseMoveTime = now;
if (super.onMouseMove(e, false) || this.forbidMouseOperation || !this.imgInfo) {
return;
}

if (this.drawingPointList.length > 0) {
// 编辑中无需 hover操作
this.render();
return;
}

const trigger = this.determineTrigger(e);

if (this.selectedIDs.length > 0 && this.dragInfo) {
this.onDragMove(e);
}

this.render(trigger);
});
}

/**
Expand Down Expand Up @@ -1741,9 +1781,11 @@ class PolygonOperation extends BasicToolOperation {
}
}

public renderPolygon() {
public renderPolygon(trigger?: string) {
// 1. 静态多边形
this.renderStaticPolygon();
if (trigger !== 'move') {
this.renderStaticPolygon();
}

// 2. hover 多边形
this.renderHoverPolygon();
Expand Down Expand Up @@ -1860,52 +1902,65 @@ class PolygonOperation extends BasicToolOperation {
return result;
}

public render() {
public render(trigger?: string) {
if (!this.ctx) {
return;
}

super.render();
this.renderPolygon();
if (trigger !== 'move') {
super.render();
}
if (trigger !== 'drag' && trigger !== 'dragSingle') {
this.renderPolygon(trigger);
}
if (trigger === 'dragSingle') {
this.renderSelectedPolygons();
}
this.renderCursorLine(this.getLineColor(this.defaultAttribute));
}

public renderCursorLine(lineColor: string) {
super.renderCursorLine(lineColor);
if (this.isCombined) {
requestAnimationFrame(() => {
this.clearOffscreenCanvas();
const { x, y } = this.coord;
const padding = 10; // 框的边界
const rectWidth = 186; // 框的宽度
const rectHeight = 32; // 框的高度
DrawUtils.drawRectWithFill(
this.canvas,
{
x: x + padding,
y: y - padding * 4 - 1,
width: rectWidth,
height: rectHeight,
} as IRect,
{ color: 'black' },
);

DrawUtils.drawText(this.canvas, { x, y }, i18n.t('ClickAnotherPolygon'), {
textAlign: 'center',
color: 'white',
offsetX: rectWidth / 2 + padding,
offsetY: -(rectHeight / 2 + padding / 2),
});
DrawUtils.drawLine(this.offscreenCanvas, { x: 0, y }, { x: 10000, y }, { color: lineColor });
DrawUtils.drawLine(this.offscreenCanvas, { x, y: 0 }, { x, y: 10000 }, { color: lineColor });
DrawUtils.drawCircleWithFill(this.offscreenCanvas, { x, y }, 1, { color: 'white' });

DrawUtils.drawRect(
this.canvas,
{
x: x - padding,
y: y - padding,
width: padding * 2,
height: padding * 2,
} as IRect,
{ lineDash: [6], color: 'white' },
);
}
if (this.isCombined) {
const padding = 10; // 框的边界
const rectWidth = 186; // 框的宽度
const rectHeight = 32; // 框的高度
DrawUtils.drawRectWithFill(
this.canvas,
{
x: x + padding,
y: y - padding * 4 - 1,
width: rectWidth,
height: rectHeight,
} as IRect,
{ color: 'black' },
);

DrawUtils.drawText(this.canvas, { x, y }, i18n.t('ClickAnotherPolygon'), {
textAlign: 'center',
color: 'white',
offsetX: rectWidth / 2 + padding,
offsetY: -(rectHeight / 2 + padding / 2),
});

DrawUtils.drawRect(
this.canvas,
{
x: x - padding,
y: y - padding,
width: padding * 2,
height: padding * 2,
} as IRect,
{ lineDash: [6], color: 'white' },
);
}
});
}

/** 撤销 */
Expand Down
Loading

0 comments on commit 0626862

Please sign in to comment.