英文:
Angular - HTML Canvas turns black when I start drawing
问题
I'm building an Angular app where I intend to let the user draw text fields over PDF pages. For this, I'm using ng2-pdf-viewer
library and I have a PDF page component that will hold a PDF page, as well as its corresponding HTML canvas element.
The problem I'm facing is that the canvas turns black when I start drawing on the respective PDF page. Although I am able to draw successfully, this means the whole page background turns to black.
Here is how it looks (the PDF page with content is behind that black background):
My page component code is the following:
export class PdfPreviewPageComponent {
@Input() pdfSrc: string = '';
@Input() pdfPageNumber!: number;
@ViewChild('pdfViewer', { static: false, read: ElementRef }) pdfViewerRef!: ElementRef;
private canvas!: HTMLCanvasElement;
private ctx: 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();
}
}
}
...
...
}
How can I avoid the canvas turning completely black? I don't want to hide the content of the PDF page as the whole purpose is for the user to draw text fields (rectangles) where they may see fit.
Here is the stackblitz project.
英文:
I'm building an Angular app where I intend to let the user draw text fields over PDF pages. For this, I'm using ng2-pdf-viewer
library and I have a PDF page component that will hold a PDF page, as well as its corresponding HTML canvas element.
The problem I'm facing is that the canvas turns black when I start drawing on the respective PDF page. Although I am able to draw successfully, this means the whole page background turns to black.
Here is how it looks (the PDF page with content is behind that black background):
My page component code is the following:
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);
}
}
...
...
}
How can I avoid the canvas turning completely black? I don't want to hide the content of the PDF page as the whole purpose is for the user to draw text fields (rectangles) where they may see fit.
Here is the stackblitz project.
答案1
得分: 0
问题在于我试图使用和操作ng2-pdf-viewer
库在每个PDF查看器元素上使用的画布。这是呈现PDF内容的画布,因此一旦在此画布上调用任何清除画布的方法(如clearRect()
),您将不可避免地删除所有PDF页面内容。
正确的方法是创建自己的画布元素,并将它们叠加在各自的页面上,使用绝对或相对定位,并确保每个画布位于堆叠顺序的顶部,使用z-index
。
英文:
The problem is that I was trying to use and manipulate the canvas that the ng2-pdf-viewer
library uses on each of its PDF viewer elements. This is the canvas that renders the PDF content, so once you call any canvas clearing methods (such as clearRect()
) on this canvas, you will inevitably delete all of the PDF page content.
The correct approach is to create your own canvas elements and overlay them on top of their respective pages, using absolute or relative positioning and making sure each canvas is on top of the stacking order with z-index
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论