我正在构建一个 Angular 应用程序,我打算让用户在 PDF 页面上绘制文本字段。为此,我使用
ng2-pdf-viewer
库,并且有一个 PDF 页面组件,它将保存 PDF 页面及其相应的 HTML 画布元素。
我面临的问题是,当我开始在相应的 PDF 页面上绘图时,画布会变黑。虽然我能够绘制成功,但这意味着整个页面背景变成黑色。
它的外观如下(包含内容的 PDF 页面位于黑色背景后面):
我的页面组件代码如下:
export class PdfPreviewPageComponent {
@Input() pdfSrc: string = '';
@Input() pdfPageNumber!: number;
@ViewChild('pdfViewer', { static: false, read: ElementRef }) pdfViewerRef!: ElementRef;
private canvas!: HTMLCanvasElement;
private cx: CanvasRenderingContext2D | null = null;
private isDrawing: boolean = false;
private startX!: number;
private startY!: number;
// UPDATE: changed from getting the canvas via input and using ngOnChanges to
// using the (page-rendered) event provided by ng2-pdf-viewer library
onPageLoaded(event: Event) {
if (!this.canvas) {
this.canvas = this._document.getElementsByTagName('canvas')[this.pdfPageNumber - 1];
this.ctx = this.canvas.getContext('2d');
if (this.ctx) {
this.ctx.fillStyle = 'red';
this.ctx.lineWidth = 2;
this.handleCanvasEvent();
}
}
}
private handleCanvasEvent() {
this.canvas.addEventListener('mousemove', (event) => this.onMouseMove(event));
this.canvas.addEventListener('mousedown', (event) => this.onMouseDown(event));
this.canvas.addEventListener('mouseup', (event) => this.onMouseUp(event));
}
private onMouseDown(event: MouseEvent) {
this.isDrawing = true;
this.startX = event.clientX - this.canvas.getBoundingClientRect().left;
this.startY = event.clientY - this.canvas.getBoundingClientRect().top;
}
private onMouseMove(event: MouseEvent) {
if (!this.isDrawing) {
return;
}
const currentX = event.clientX - this.canvas.getBoundingClientRect().left;
const currentY = event.clientY - this.canvas.getBoundingClientRect().top;
const width = currentX - this.startX;
const height = currentY - this.startY;
this.clearCanvas();
this.drawRectangle(this.startX, this.startY, width, height);
}
private onMouseUp(event: MouseEvent) {
this.isDrawing = false;
}
private clearCanvas() {
if (this.cx) {
this.cx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
private drawRectangle(x: number, y: number, width: number, height: number) {
if (this.cx) {
this.cx.strokeRect(x, y, width, height);
}
}
...
...
}
如何避免画布完全变黑?我不想隐藏 PDF 页面的内容,因为整个目的是让用户在他们认为合适的地方绘制文本字段(矩形)。
这是 stackblitz 项目。
问题是我试图使用和操作
ng2-pdf-viewer
库在其每个 PDF 查看器元素上使用的画布。这是渲染 PDF 内容的画布,因此一旦您在此画布上调用任何画布清除方法(如clearRect()
),您将不可避免地删除所有 PDF 页面内容。
正确的方法是创建自己的画布元素并将它们覆盖在各自页面的顶部,使用绝对或相对定位,并使用
z-index
确保每个画布位于堆叠顺序的顶部。