[2D labeling] add ruler line to cvat-canvas

1. Scenario overview

When using cvat-canvas2D annotation development, sometimes we need to add some ruler lines to the 2D graphics, such as the distance ruler from the front to the current camera. At this time we need to add ruler lines.

Based on cvat-canvasthe existing framework design pattern, the implementation logic is as follows:

  1. When canvasView.tsexecuting the constructor, create 10 hidden ruler lines
  2. Add an api entry for setting the ruler line, calling method:canvas.showRulerLines([10,20])
  3. canvasView.tsAdded a method to create a ruler line in

2. Development

1、canvas.ts

Path: src/typescript/canvas.ts
New showRulerLines method:

public showRulerLines(coordYs: number[]): void {
    
    
    this.model.showRulerLines(coordYs);
}

In this way, when we call on the business side, we can use this form:

//表示我们要在Y坐标30,50,70,90的地方添加标尺线
canvas.showRulerLines([30, 50, 70, 90]);

2、canvasModel.ts

path:src/typescript/canvasModel.ts

//新增showRulerLines方法
public showRulerLines(coordYs: number[]): void {
    
    
    this.data.rulerLines = coordYs;

    this.notify(UpdateReasons.RULER_LINE_UPDATED);
}
//UpdateReasons中添加事件枚举
export enum UpdateReasons {
    
    
	...
    RULER_LINE_UPDATED = 'ruler_line_updated'
}
//CanvasModel接口添加rulerLines坐标数组,showRulerLines显示标尺线方法
export interface CanvasModel {
    
    
	rulerLines:number[];
	showRulerLines(coordYs: number[]):void;
}
//data变量类型申明添加rulerLines
private data: {
    
    
    ...
    rulerLines:number[]
};

//constructor构造函数初始化时,添加rulerLines
public constructor() {
    
    
	this.data={
    
    
		...
		rulerLines:[]
	};
}
//添加rulerLines的get 操作拦截器
public get rulerLines(): number[] {
    
    
    return this.data.rulerLines;
}

3、canvasController.ts

path:src/typescript/canvasController.ts

//CanvasController接口添加rulerLines
export interface CanvasController {
    
    
	...
	rulerLines:number[];
}

//添加rulerlines的get拦截器
public get rulerLines(): any {
    
    
    return this.model.rulerLines;
}

4、canvasView.ts

path:src/typescript/canvasView.ts

export class CanvasViewImpl implements CanvasView, Listener {
    
    
	private rulerLines:SVGSVGElement;
	constructor(){
    
    
		// 标尺线
	    this.rulerLines = window.document.createElementNS('http://www.w3.org/2000/svg', 'svg');
	    this.rulerLines.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
	    this.rulerLines.setAttribute('version', '1.1');
	    this.rulerLines.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
	    this.rulerLines.setAttribute('xmlns:svgjs', 'http://svgjs.dev/svgjs');
	    this.rulerLines.setAttribute('id', 'cvat_canvas_rulerlines');
	    const colors=["red","orange","yellow","green","cyan","lightgray"];
	    new Array(10).fill(1).map((item,i)=>this.rulerLines.appendChild(createRulerLine(i,colors[i])))
	    //添加到canvas Dom节点下。
	    this.canvas.appendChild(this.rulerLines);  
	    
	    function createRulerLine(index:number,color="lightgray") {
    
       
	        const line = window.document.createElementNS('http://www.w3.org/2000/svg', "rect");
	        line.setAttribute('id', `cvat_canvas_ruler_line${
      
      index}`);
	        line.setAttribute('width', '100%');
	        line.setAttribute('height', '1');
	        line.setAttribute('y', '0');
	        line.setAttribute('fill', color);
	        //默认隐藏,外部调用canvas.showRulerLines([30, 50, 70, 90])时,设置位置并且显示。
	        line.setAttribute('visibility', 'hidden');
	        return line;
	    }
	}
	
	notify(){
    
    
		...
		//添加相应RULER_LINE_UPDATED
		else if (reason === UpdateReasons.RULER_LINE_UPDATED) {
    
    
            const coordYs=this.controller.rulerLines;
            Array.prototype.forEach.call(this.rulerLines.children,(line:any)=>{
    
    
                line.setAttribute('visibility', 'hidden');
            });
            if(coordYs&&coordYs.length){
    
    
                coordYs.forEach((y:number,i:number)=>{
    
    
                    const line=this.rulerLines.children[i];
                    line.setAttribute('y', `${
      
      coordYs[i]}`);
                    line.setAttribute('visibility', 'visible');
                });
            }
        }
	}
	private transformCanvas(): void {
    
    
		...
		//在作放大缩小时,同步更新标尺线的尺寸
		Array.prototype.forEach.call(this.rulerLines.children,(line:any)=>{
    
    
	        line.setAttribute('height', `${
      
      consts.BASE_GRID_WIDTH / this.geometry.scale/2}`);
	    })
	}
}

5、canvas.scss

path:src/scss/canvas.scss

//添加标尺线样式
#cvat_canvas_rulerlines {
    
    
    position: absolute;
    z-index: 1;
    pointer-events: none;
    width: 100%;
    height: 100%;
}

3. The final effect

normal size:
insert image description here
scaled up:
insert image description here
scaled down:
insert image description here
when run:
insert image description here

4. Resources

cvat official website
cvat-canvas source code

Guess you like

Origin blog.csdn.net/bobo789456123/article/details/129909966