Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help] Some help required on how to implement the clear, undo and redo functionality. #25

Open
justpankajdotcom opened this issue Dec 13, 2024 · 0 comments

Comments

@justpankajdotcom
Copy link

justpankajdotcom commented Dec 13, 2024

Hi,

Thanks so much for you help here. However, I need a bit more help from you in extending your already awesome library. Your help is deeply appreciated.

What am I trying to do?

I am trying to add basically 4 new features -

  1. CLEAR (clear the canvas and comments, basically empty everything)
  2. UNDO (Maintain a history of annotations, and ability to undo a particular extension)
  3. REDO (From the same history of annotations, ability to redo a particular extension)
  4. SET ANNOTATIONS (Instead of read from file, write the annotations from server)

What I have tried?

My approach was to extend your toolbar for more buttons to trigger the above mentioned operations(except the set annotations). Here is what I did step by step,

  1. First I extended src/const/icon.ts to export 3 more icons through SVG for - clear, undo, redo.
  2. Imported the icons inside the toolbar something like this,
 <li title={t('normal.clear')} onClick={props.onClear}>
                    <div className="icon">
                        <ClearIcon />
                    </div>
                    <div className="name">{t('normal.clear')}</div>
</li>
  1. Passing the onClear and other functions from parent i.e src/index.tsx.
  2. This is how implementation is on my src/index.tsx
// This is passed on to the toolbar as argument onClear()

private async clearAnnotations() {
        this.painter.clear()
        this.painter.reDrawAllAnnotations() // Re-draw all annotations
        const updatedAnnotations = this.painter.getData()
        console.log('Clear ', updatedAnnotations)
    }

Inside src/painter/index.ts -

public clear(): void {
        this.store.clear() // calling store clear which is defined below
        this.konvaCanvasStore.clear()
}

public reDrawAllAnnotations(): void {
        console.log('Redrawing')
        this.konvaCanvasStore.forEach(({ pageNumber }) => {
            this.reDrawAnnotation(pageNumber)  // call reDrawAnnotation for each page
        })
    }

Finally, inside the src/painter/store.ts -

public clear(): void {
        const annotationIds = Array.from(this.annotationStore.keys())
        annotationIds.forEach(id => this.delete(id))
    }

This is for my implementation for CLEAR, for undo and redo, I am doing something like this -

Inside src/painter/store.ts -

 private annotationStore: Map<string, IAnnotationStore> = new Map()
    private originalAnnotationStore: Map<string, IAnnotationStore> = new Map()
    private pdfViewerApplication: PDFViewerApplication
    private history: IAnnotationStore[][] = []
    private future: IAnnotationStore[][] = []
    
    
    .....
    .....
    
    public undo() {
        if (this.history.length > 0) {
            this.future.push(this.annotaions)
            const previousState = this.history.pop()
            this.annotationStore = new Map(previousState.map(annotation => [annotation.id, annotation]))
        }
    }

    public redo() {
        if (this.future.length > 0) {
            this.history.push(this.annotaions)
            const nextState = this.future.pop()
            this.annotationStore = new Map(nextState.map(annotation => [annotation.id, annotation]))
        }
    }
    

Then triggering it from src/index.tsx -

private undoAnnotations() {
        this.painter.undo()
        this.painter.reDrawAllAnnotations() // Re-draw all annotations
        const updatedAnnotations = this.painter.getData()

        console.log('Undo ', updatedAnnotations)
    }

    private redoAnnotations() {
        this.painter.redo()
        this.painter.reDrawAllAnnotations() // Re-draw all annotations
        const updatedAnnotations = this.painter.getData()
        console.log('Redo ', updatedAnnotations)
    }

What is not working?

When I press the clear button, it does trigger the functions and the updateAnnotations inside my clearAnnotations function inside src/index.tsx, I can see annotations being cleared.

console.log('Clear ', updatedAnnotations) // Empty

but the annotations still stays on the top of canvas/pdf. I tried to redraw also, as you can see in my this.painter.reDrawAllAnnotations, but I am not seeing any changes with this.

Where I need help?

Sorry for such a long message, I wanted to make it detailed and easy for you to understand as well. I was hoping if you could help me with the SET_ANNOTATIONS, where I can send the stored annotations to a clear canvas, as well as UNDO,REDO, CLEAR methods.

For that I wanted to clear everything and then initialize the annotations. Steps I am taking - 1. CLEAR 2. SET_ANNOTATIONS from parent through postMessage api from window.content.

Inside my src/index.tsx

if (event.data.type === 'SET_ANNOTATIONS') {
            const annotations = event.data.annotations  // Read annotations in the parent from server, then pass it to iframe through postMessage api
            this.setAnnotations(annotations)
 }
 
 private async setAnnotations(annotations: object) {
        const annotationsArray = Object.values(annotations) as IAnnotationStore[]
        await this.store.clear()
        await this.painter.initAnnotations(annotationsArray, false)
        this.painter.reDrawAllAnnotations()
        const updatedAnnotations = this.painter.getData()
        console.log('Set ', updatedAnnotations)
    }

Thank you so much for making to this far, any help appreciated. Happy to host the library if you want to see the code as well 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant