stephanrauh / ngx-extended-pdf-viewer

A full-blown PDF viewer for Angular 16, 17, and beyond
https://pdfviewer.net
Apache License 2.0
473 stars 181 forks source link

Popover remove or modification #2164

Open farisshomali opened 7 months ago

farisshomali commented 7 months ago

Hi, I have multiple questions...

  1. How to customize the toolbar icons ?
  2. How to change the Draw,Text, and stamp annotations popovers ? Screen Shot 2024-02-19 at 9 39 30 AM Screen Shot 2024-02-19 at 9 39 19 AM Screen Shot 2024-02-19 at 9 39 09 AM

3, How can i detect events when user add annotation ?

Many thanks :)

stephanrauh commented 7 months ago
  1. That's one of the things hard to describe - but I've tried here: https://pdfviewer.net/extended-pdf-viewer/customization and I've added a demo here: https://pdfviewer.net/extended-pdf-viewer/custom-toolbar. The idea is replacing the entire toolbar with your own toolbar. You can use my components, so it's not as bad as it sounds. Nonetheless, if you want to replace an icon, you need to replace the entire toolbar button. Have a look at the source code in this folder: https://github.com/stephanrauh/ngx-extended-pdf-viewer/tree/main/projects/ngx-extended-pdf-viewer/src/lib/toolbar.

  2. The popovers are part of the toolbar, via <pdf-toolbar> --> <pdf-editor> -> <pdf-stamp-editor>. Once you've figured out how to customize the toolbar, you know how to customize the popovers. It's a bit cumbersome, but it's not difficult.

  3. You can't. I haven't implemented this feature yet. It just didn't cross my mind. But you're right, it makes sense. Maybe. I'd have to emit an event every time the user modifies the annotation. That's a whole bunch of events, so it might result in a performance penalty. I'll keep your request in mind. At the moment, I focus on maintaining the library without developing new features because I don't know what the EU Cyber Resilience Act means. That's an upcoming regulation I appreciate - but it might force me to abandon the project. That's not likely, but even so, it slows me down.

By the way, your upper-most screenshot shows you've got a CSS problem. The latest version of ngx-extended-pdf-viewer aligns the icon and the text nicely:

image
farisshomali commented 7 months ago

@stephanrauh Thank you!, i really appreciate your help

stephanrauh commented 6 months ago

I've started to investigate your third issue. That's quite a rabbit hole. At the moment I've identified roughly 16 different events. Maybe that's 32, if I consider the undo function.

Is it OK if the events fire after finishing the operation? I didn't find a good hook to fire an event when the user clicks the menu to add an annotation. But I think that'd be useless, anyways, because it's only an empty annotation.

farisshomali commented 6 months ago

@stephanrauh First.. thank you for your effort, i would like to point on some few things i did might help..

1) We can detect when the user click on the menu to add annotation by making a custom function that triggers eventbus event name like this:

const PDFViewerApplication: IPDFViewerApplication = (window as any).PDFViewerApplication PDFViewerApplication.eventBus.dispatch('switchannotationeditormode', {mode: 15})

so in this case we know that user wanted to draw... and if i want to turn that draw mode off simply i will change the mode to ZERO.

2) we can know if the user done with the annotationLayer editing by handling page click, We create onPageClick method and we pass a MouseEvent event, then we get the clicked element like this

const current = document.elementFromPoint(event.x, event.y)

if the the current class list contains a class called 'stampEditing' for example, now we know that the text layer is not available at this moment and user still adding annotations.

For me i found this solution helpful, maybe it's not optimal but it does the job and i can wrap up every thing around me to make decisions about what the user should do after adding the annotation like fetching the serialized annotations and send them using API for example after the annotation mode changed to zero.

Please Check this out, i did this using ngx extended pdf viewer

https://github.com/stephanrauh/ngx-extended-pdf-viewer/assets/61110881/5a6affd9-6048-4e3d-b811-27e6f196978b

The last thing i need to know is when i triggered annotation mode 9 (Highlighting) i saw that it sets a multi span selected lines as one annotation, can i ask you how you did that ? i mean how did you applied that highlight style to that selected lines because i want to expand this thing and i want to add Underline, Squiggle and Strikethrough.

I know i went too far with my questions but i'm really enjoying this library

stephanrauh commented 6 months ago

can i ask you how you did that ?

I didn't. :) @Calixtheman implemented this. If you want to implement underline, squiggle, and strikethrough, it might be a good idea to have a chat with them. Maybe they're ready to pick up the idea and to implement it in the base library (or to accept a PR doing that).

stephanrauh commented 6 months ago

How did you implement the sticky notes?

farisshomali commented 6 months ago

Adding sticky notes process comes in two stages..

1) Create the sticky note using this library

2) After making sure that sticky note annotation is exist on the PDF document annotation collection we can now append the sticky note as HTML element to current page text layer to make things more reactive (Faking the experience) without reloading the pdf file to write the new Uint8Array data.

Why i append it to text layer ? because i'm enabling text layer in order to select and highlight some text so in this case the first thing user will hit when the page being clicked is the text layer :)

Now he can select it and see it's content or apply Drag&Drop events so he can change the original annotation Rectangle values.

How did i get the current user click position based on the pdf page ?

    const PDFViewerApplication: IPDFViewerApplication = (window as any).PDFViewerApplication;
    const pageIndex = annotation.page;
    const pageView = PDFViewerApplication.pdfViewer.getPageView(pageIndex);
    const currentCanvas = pageView.canvas!.parentElement
    const currentTextLayer = pageView.textLayer
    const screenRect = pageView.viewport.convertToViewportRectangle(annotation.rect)
    const viewportWidth = pageView.viewport.width;
    const viewportHeight = pageView.viewport.height;
    const xPercent = (screenRect[0] / viewportWidth) * 100;
    const yPercent = (screenRect[1] / viewportHeight) * 100;
    const fakeStickyNote = document.createElement('section')
    let isDragging = false;
    let shouldAppend = true
    let initialX = 0
    let initialY = 0;
      fakeStickyNote.style.setProperty('left', `${xPercent - 2}%`);
      fakeStickyNote.style.setProperty('top', `${yPercent - 2}%`);
      fakeStickyNote.style.position = 'absolute';
      fakeStickyNote.style.cursor = 'grab'
      fakeStickyNote.draggable = true;
roshrj-hue commented 6 months ago

@farisshomali how to implement the sticky note and how to add the sticky note by downloading pdf after adding the sticky note

farisshomali commented 5 months ago

@roshrj-hue Please read my response above, i described the process in two steps