mark

I use Angular code to add markers so I can draw on a pdf file.

The problem that sometimes the markers are drawn below the drawings that I created on the pdf.

How to put the markers above the drawing in yellow.

I already tried with z-index but it doesn't work

this my Typescript code 

  public reloadPin(parentContext: TsfContext): void {
    if (this.planId()) {
      const currentPage =
        this.pdfViewerObj().currentPageNumber === 0
          ? 1
          : this.pdfViewerObj().currentPageNumber;

      const pdfInfos: IPdfInfos = {
        form: this.#planOptions,
        currentId: parentContext.formulaireId as string,
        planId: this.planId(),
        pdfId: this.pdfId,
      };

      // update markers
      const sub$ = this.#fileService
        .getMarkers(pdfInfos)
        .pipe(
          map((result: any) => {
            return result.markers;
          }),
          tap((markers: IPdfMarker[]) => {
            const pinsContainer = this.#elementRef.nativeElement.querySelector(
              `#${this.pdfId}_pageViewContainer`
            );
            if (pinsContainer && markers && markers.length > 0) {
              for (let p = currentPage - 1; p <= currentPage + 1; p += 1) {
                const page = this.#elementRef.nativeElement.querySelector(
                  `#${this.pdfId}_pageDiv_${p}`
                );
                if (page) {
                  for (const point of markers) {
                    if (point.page === p) {
                      // add icon
                      this.addIcon(point, pinsContainer, page);

                      // add Text
                      if (point.toString) {
                        this.addText(point, pinsContainer, page);
                      }
                    }
                  }
                }
              }
            }
          })
        )
        .subscribe();
      this.subToDestroy.add(sub$);
    }
  }

  private addIcon(point: IPdfMarker, container: HTMLElement, page: HTMLElement): void {
    const icon = document.createElement('i');
    icon.className = 'icon-required';
    icon.style.position = 'absolute';
    icon.style.fontSize = `${this.fontSize}px`;
    icon.style.zIndex = '3';
    icon.style.color = point.color;
    const top =
      (point.y * parseInt(page.style.height.replace('px', ''))) / 100 +
      parseInt(page.style.top.replace('px', '')) -
      this.fontSize / 2;

    icon.style.top = `${top}px`;
    const left =
      (point.x * parseInt(page.style.width.replace('px', ''))) / 100 +
      parseInt(page.style.left.replace('px', '')) -
      this.fontSize / 2;
    icon.style.left = `${left}px`;

    icon.addEventListener('click', () => {
      this.#pdfViewerService.setSelectedPoint(point);
      const rect = container.getBoundingClientRect();
      if (point.inputId) {
        this.contextMenu().open(rect.top + top + 15, rect.left + left);
      } else {
        this.#pdfViewerService.openMarker(
          this.category(),
          this.formId(),
          this.#planOptions.objectRelation1Option.relationObject,
          this.#planOptions.objectRelation1Option.view
        );
      }
    });
    container?.appendChild(icon);
  }
  public updateDrawing(parentContext: TsfContext): void {
    const drawing: { [key: string]: any } | null | undefined =
      (parentContext.model && parentContext.model['drawing']) ?? null;
    const currentPage =
      this.pdfViewerObj().currentPageNumber === 0
        ? 1
        : this.pdfViewerObj().currentPageNumber;
    if (drawing && Array.isArray(drawing)) {
      for (let i = 0; i < drawing.length; i += 1) {
        const pdfPage = drawing[i];
        if (parseInt(pdfPage.array_row_guid) === currentPage - 1) {
          let canvas = this.#elementRef.nativeElement.querySelector(
            `#${this.pdfId}_drawCanvas_${pdfPage.array_row_guid}`
          ) as HTMLCanvasElement;

          const ctx = canvas?.getContext('2d');
          ctx?.clearRect(0, 0, canvas.width, canvas.height);

          const pageDivParent = this.#elementRef.nativeElement.querySelector(
            `#${this.pdfId}_pageDiv_${pdfPage.array_row_guid}`
          );

          const pageDiv = pageDivParent?.querySelectorAll(
            `#${this.pdfId}${pdfPage.array_row_guid}_diagramAdornerLayer`
          );

          if (pageDiv) {
            const firstPageDiv = pageDiv[0] as HTMLElement;

            if (!canvas) {
              if (pageDiv && pageDiv.length && pageDiv.length > 0) {
                canvas = document.createElement('canvas');
                canvas.id = `${this.pdfId}_drawCanvas_${pdfPage.array_row_guid}`;
                canvas.style.position = 'absolute';
                canvas.style.top = '0';
                canvas.style.left = '0';

                canvas.width = parseInt(firstPageDiv.style.width.replace('px', '')); // '100%';
                canvas.height = parseInt(firstPageDiv.style.height.replace('px', '')); // '100%';

                pageDiv[0].appendChild(canvas);
              } else {
                // retry until div is loaded
                this.updateDrawing(parentContext);
                return;
              }
            } else if (pageDiv && pageDiv.length && pageDiv.length > 0) {
              canvas.width = parseInt(firstPageDiv.style.width.replace('px', '')); // '100%';
              canvas.height = parseInt(firstPageDiv.style.height.replace('px', '')); // '100%';
            }
          }

          const json = JSON.parse(pdfPage.drawingJson.drawJson);
          for (let j = 0; j < json.length; j += 1) {
            const drawObject: IDrawObject = {
              element: json[j],
              ratio: canvas.height / pdfPage.drawingJson.drawingHeight,
              canvas: canvas as HTMLCanvasElement,
            };
            this.#pdfViewerService.draw(drawObject);
          }
        }
      }
    }
  }

second problem

When I click on the print button, it only prints the pdf without the markers or drawings.


Attachment: pdfviewer_4572e550.zip

16 Replies

PA Priyadharshini Annamalai Syncfusion Team January 27, 2025 06:35 AM UTC

Hi


After analyzing the code snippet, it seems you are creating a canvas or element and appending it to the PDF viewer container or page div. If you print or save the PDF, these appended elements won't be visible, is that the issue you're mentioning. If this is the case, these elements won't be part of the PDF content. Instead, you can create a custom stamp or image annotation and add it to the PDF viewer. This approach will ensure that the added content is visible and properly embedded in the PDF. Kindly refer the sample below.

Sample: Ug6zy6 (forked) - StackBlitz


Regards,

Priyadharshini



AA Aitbouhou Adam January 27, 2025 07:57 AM UTC

Thak you for your replay 

and how about firt probléme ? 


Thanks



PA Priyadharshini Annamalai Syncfusion Team January 28, 2025 07:58 AM UTC

Hi Aitbouhou Adam,


As per the provided code snippet, you have added the element as an image. As previously mentioned, you can create a custom stamp or image annotation and add it to the PDF viewer. The solution remains the same for both scenarios.


Regards,

Priyadharshini



AA Aitbouhou Adam January 28, 2025 04:35 PM UTC

Hello


How to add un hyperLInkText with AddAnottaion Stamp ? 


Thank

addAnnotation


PA Priyadharshini Annamalai Syncfusion Team January 29, 2025 10:51 AM UTC

Hi Aitbouhou Adam,


Currently, Syncfusion PDF Viewer does not directly support adding a hyperlink. However, you add the hyperlink using PDF Library. We have provided the documentation below for your reference.

 

Documentation: Working with Hyperlinks | Syncfusion


Regards,

Priyadharshini



AA Aitbouhou Adam January 30, 2025 04:47 PM UTC

Hello, I am in the process of modifying my code to comply with your recommendations.

and when I test I find that my elements are not well positioned.


Could you help me?


Here is the world and an example

  public updateDrawing(parentContext: TsfContext): void {
    const drawing: { [key: string]: any } | null | undefined =
      (parentContext.model && parentContext.model['drawing']) ?? null;
    const currentPage =
      this.pdfViewerObj().currentPageNumber === 0
        ? 1
        : this.pdfViewerObj().currentPageNumber;
    if (drawing && Array.isArray(drawing)) {
      for (let i = 0; i < drawing.length; i += 1) {
        const pdfPage = drawing[i];
        if (parseInt(pdfPage.array_row_guid) === currentPage - 1) {
          let canvas = this.#elementRef.nativeElement.querySelector(
            `#${this.pdfId}_drawCanvas_${pdfPage.array_row_guid}`
          ) as HTMLCanvasElement;

          const ctx = canvas?.getContext('2d');
          ctx?.clearRect(0, 0, canvas.width, canvas.height);

          const pageDivParent = this.#elementRef.nativeElement.querySelector(
            `#${this.pdfId}_pageDiv_${pdfPage.array_row_guid}`
          );

          const pageDiv = pageDivParent?.querySelectorAll(
            `#${this.pdfId}${pdfPage.array_row_guid}_diagramAdornerLayer`
          );

          if (pageDiv) {
            const firstPageDiv = pageDiv[0] as HTMLElement;
            console.log(firstPageDiv);
            if (!canvas) {
              if (pageDiv && pageDiv.length && pageDiv.length > 0) {
                canvas = document.createElement('canvas');
                canvas.id = `${this.pdfId}_drawCanvas_${pdfPage.array_row_guid}`;
                canvas.style.position = 'absolute';
                canvas.style.top = '0';
                canvas.style.left = '0';

                canvas.width = parseInt(firstPageDiv.style.width.replace('px', '')); // '100%';
                canvas.height = parseInt(firstPageDiv.style.height.replace('px', '')); // '100%';

                pageDiv[0].appendChild(canvas);
                console.log(pageDiv);
              } else {
                // retry until div is loaded
                this.updateDrawing(parentContext);
                return;
              }
            } else if (pageDiv && pageDiv.length && pageDiv.length > 0) {
              canvas.width = parseInt(firstPageDiv.style.width.replace('px', '')); // '100%';
              canvas.height = parseInt(firstPageDiv.style.height.replace('px', '')); // '100%';
            }
          }
          console.log(canvas);
          const json = JSON.parse(pdfPage.drawingJson.drawJson);
          for (let j = 0; j < json.length; j += 1) {
            const drawObject: IDrawObject = {
              element: json[j],
              ratio: 1,
              canvas: canvas as HTMLCanvasElement,
            };
            this.#pdfViewerService.draw(drawObject);
          }

          const imageData = canvas.toDataURL('image/png');

          this.pdfViewerObj().annotation.addAnnotation('Stamp', {
            left: 0,
            top: 0,
            pageNumber: currentPage,
            width: 750, // how i can fix the width
            height: 763, // how i can fix the height

            customStamps: [
              {
                customStampName: 'Custom Stamp',

                customStampImageSource: imageData,
              },
            ],
          } as CustomStampSettings);
          console.log(this.pdfViewerObj().annotationCollection);
        }
      }
    }
  }
  public draw(drawObject: IDrawObject) {
    switch (drawObject.element.type) {
      case EDrawShape.ArrowShape:
        this.ArrowShape(drawObject);
        break;
      case EDrawShape.CircleShape:
        this.CircleShape(drawObject);
        break;
      case EDrawShape.PenShape:
        this.PenShape(drawObject);
        break;
      case EDrawShape.RectangleShape:
        this.RectangleShape(drawObject);
        break;
      case EDrawShape.OvaleShape:
        this.OvaleShape(drawObject);
        break;
      case EDrawShape.TextShape:
        this.TextShape(drawObject);
        break;
      case EDrawShape.LineShape:
        this.LineShape(drawObject);
        break;

      default:
        break;
    }
  }

  private TextShape(drawObject: IDrawObject): void {
    const ctx = drawObject?.canvas?.getContext('2d');
    if (ctx) {
      const color = this.decimalToHexString(drawObject.element.color);
      ctx.font = `${drawObject.element.size * drawObject.ratio}px Arial`;
      ctx.fillStyle = color;
      ctx.fillText(drawObject.element.text, drawObject.element.x1, drawObject.element.y2);
    }
  }


Attachment: pdfviewers_a86ad175.zip


PA Priyadharshini Annamalai Syncfusion Team January 31, 2025 09:54 AM UTC

Hi 

Kindly let us know whether you are specifying the width and height in pixels or points. Our component is fully loaded based on pixels, so if you are using points, please convert them to pixels and try again.

 

Additionally, please specify whether the issue is related to the image's X and Y position or its width and height. If the issue persists after converting points to pixels, kindly provide the image data and the PDF file so we can analyze the problem and provide a solution.

 

Code Snippet:

 

public ConvertPointToPixel(number: any): number {

       return (number * (96 / 72));

   }


Regards,

Priyadharshini



AA Aitbouhou Adam February 3, 2025 03:02 PM UTC

Hello 


based on the example below. How we can add a click event to the text we added.


https://stackblitz.com/edit/angular-iykefk-8x2aboum?file=package.json,src%2Fapp.component.ts


Thank you very mutch

Have a nice day



PA Priyadharshini Annamalai Syncfusion Team February 4, 2025 07:56 AM UTC

Hi Aitbouhou Adam,

If you're adding text as free text annotations, you can utilize the annotation select event, which is triggered when you click on the added annotation (e.g., free text or any other supported annotation). However, if your requirements differ from what has been mentioned above, please provide more details about the exact scenario you are working with. This will help us offer more targeted guidance. 

API reference: Angular PDF Viewer API component - Syncfusion 


Regards,

Priyadharshini



AA Aitbouhou Adam February 4, 2025 03:02 PM UTC

Hello 

I will explain my problem to you.


in a PDF, sometimes I need to add drawings (stamps) and many text (freeText) this text must be clickable (listnerEvent) and redirect to another page. (PJ)


the texts must be on the images if they intersect.


Attachment: prints_190c8f49.zip


PA Priyadharshini Annamalai Syncfusion Team February 5, 2025 01:13 PM UTC

Hi Aitbouhou Adam,


We have provided a sample in which selecting a stamp annotation redirects to page 5 using the annotation select event. Similarly, you can modify it as needed to suit your requirements based on the annotation types. Please review it and let us know if it meets your needs or if any further modifications are required. 

Sample: Ug6zy6 (forked) - StackBlitz 


Regards,

Priyadharshini



AA Aitbouhou Adam February 11, 2025 10:56 AM UTC

Good morning


How can I display my annotations only when I click on the print button on the pdfview? so that they can be printed?


thanks



PA Priyadharshini Annamalai Syncfusion Team February 12, 2025 05:57 PM UTC

Hi Aitbouhou Adam


We are checking on the reported query and will provide further details later tomorrow.


Regards,

Priyadharshini



PA Priyadharshini Annamalai Syncfusion Team February 13, 2025 08:01 AM UTC

Hi Aitbouhou Adam,


We have provided a sample based on your requirements. In this sample, the printStart event is used to add annotations using the addAnnotation API, and the printEnd event removes the added annotations after a timeout. This ensures that the annotations are visible only in the print window.

Please review the sample and let us know if it meets your expectations or if you require any further clarification.

Sample: Aj3usxru (forked) - StackBlitz


Regards,

Priyadharshini




AA Aitbouhou Adam February 17, 2025 09:50 AM UTC

Hello


I use this code to create points in pdf.


It works but when I click on the zoom button or zoom out. it redraws the points, but it keeps the old points even though I deleted container.


Here is my code


Thanks you


------------------------------------------------------------------------------------------------------------------------------------------------


public clearMarkersAndShapes(): void {


    const pinsContainer = this.#elementRef.nativeElement.querySelector(


      `#${this.pdfId}_pageViewContainer`


    );


    while (pinsContainer?.hasChildNodes()) {


      const lastChild = pinsContainer.lastChild;


      const nodeName = lastChild?.nodeName.toLowerCase();






      if (nodeName === 'i' || nodeName === 'span') {


        pinsContainer.removeChild(lastChild as Node);


      } else {


        break;


      }


    }


  }




  public addMarkersToPage(): void {


    if (!this.planId() || !this.markersList || this.markersList.length === 0) return;




    const pageCount = this.pdfViewerObj().pageCount;




    const pinsContainer = this.#elementRef.nativeElement.querySelector(


      `#${this.pdfId}_pageViewContainer`


    );




    if (!pinsContainer) {


      return;


    }




    for (let p = 0; p <= pageCount; p += 1) {


      const page = this.#elementRef.nativeElement.querySelector(


        `#${this.pdfId}_pageDiv_${p}`


      );




      if (!page) return;




      const pageMarkers = this.markersList.filter(marker => marker.page === p);


      if (!pageMarkers || pageMarkers.length === 0) return;




      pageMarkers.forEach(marker => {


        // add icon


        this.addIcon(marker, pinsContainer, page);


        // add Text


        if (marker.toString) {


          this.addText(marker, pinsContainer, page);


        }


      });


    }


  }




  private addIcon(point: IPdfMarker, container: HTMLElement, page: HTMLElement): void {


    const icon = document.createElement('i');


    icon.className = 'icon-required';


    icon.style.position = 'absolute';


    icon.style.fontSize = `${this.fontSize}px`;


    icon.style.zIndex = '3';


    icon.style.color = point.color;


    const top =


      (point.y * parseInt(page.style.height.replace('px', ''))) / 100 +


      parseInt(page.style.top.replace('px', '')) -


      this.fontSize / 2;




    icon.style.top = `${top}px`;


    const left =


      (point.x * parseInt(page.style.width.replace('px', ''))) / 100 +


      parseInt(page.style.left.replace('px', '')) -


      this.fontSize / 2;


    icon.style.left = `${left}px`;




    icon.addEventListener('click', () => {


      this.#pdfViewerService.setSelectedPoint(point);


      const rect = container.getBoundingClientRect();


      if (point.inputId) {


        this.contextMenu().open(rect.top + top + 15, rect.left + left);


      } else {


        this.#pdfViewerService.openMarker(


          this.category(),


          this.formId(),


          this.#planOptions.objectRelation1Option.relationObject,


          this.#planOptions.objectRelation1Option.view


        );


      }


    });




    container?.appendChild(icon);


  }





PA Priyadharshini Annamalai Syncfusion Team February 18, 2025 08:00 AM UTC

Hi


You can update the size of the created element by adjusting its dimensions according to the zoom value. For example, you can multiply the element's width and height by the current zoom factor to scale it proportionally. This will ensure that the element's size is consistent with the zoom level. Please let me know if you need further assistance with the implementation. Additionally, please share the video reference so that I can analyze it further and provide a solution.


Regards,

Priyadharshini



Loader.
Up arrow icon