skip to Main Content

I am working on an Angular node-based application, the nodes in which are html tables containing <textarea>. When I try to generate project previews using html2canvas, neither the text in <textarea> nor <mat-icons> are rendered, maybe it’s the same problem.

Demo: https://stackblitz.com/edit/stackblitz-starters-zjkz5q

Here is the expectation/result:

And also the html structure of the component:

2

Answers


  1. Chosen as BEST ANSWER

    Another solution I just found is to use dom-to-image package:

    @Component({
        selector: 'app-root',
        standalone: true,
        template: `
            <vflow id="flow" #flow [nodes]="nodes" [background]="{type: 'dots'}">
                <ng-template nodeHtml let-ctx>
                    <table style="background: red; padding: 20px;">
                        <tr>
                            <textarea></textarea>
                        </tr>
                    </table>
                </ng-template>
            </vflow>
            <button (click)="captureWithDomToImage()">dom-to-image</button>
            <img [src]="capturedImage" *ngIf="capturedImage">
    
        `,
        imports: [VflowModule, NgIf],
    })
    export class App {
        capturedImage: string = '';
        nodes: Node[] = [
            {
                id: '1',
                point: {x: 100, y: 100},
                type: 'html-template',
            },
        ];
    
        captureWithDomToImage(): void {
            domtoimage.toPng(document.getElementById('flow')!)
                .then((dataUrl) => this.capturedImage = dataUrl);
        }
    }
    
    bootstrapApplication(App);
    

  2. Please try to use the below code:

      import {
      ChangeDetectorRef,
      Component,
      ElementRef,
      ViewChild,
    } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import 'zone.js';
    import html2canvas from 'html2canvas';
    import { Node, VflowComponent, VflowModule } from 'ngx-vflow';
    import { NgIf } from '@angular/common';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      template: `
        <div #contentContainer>
          <vflow [nodes]="nodes" [background]="{type: 'dots'}">
            <ng-template nodeHtml let-ctx>
              <table>
                <tr>
                  <textarea #textArea>Initial Text</textarea>
                </tr>
              </table>
            </ng-template>
          </vflow>
        </div>
        <button (click)="capture()">Capture</button>
        <ng-content *ngIf="capturedImage">
          <img width="100%" [src]="capturedImage">
        </ng-content>
      `,
      imports: [VflowModule, NgIf],
    })
    export class App {
      @ViewChild('contentContainer') screen!: ElementRef;
      @ViewChild('textArea') textArea!: ElementRef;
      nodes: Node[] = [
        {
          id: '1',
          point: { x: 100, y: 100 },
          type: 'html-template',
        },
      ];
      capturedImage: string = '';
    
      constructor(private changeDetectorRef: ChangeDetectorRef) {}
    
      capture(): void {
        // Update the textarea's value before capturing
        const textarea = this.screen.nativeElement.querySelector('textarea');
        if (textarea) {
          textarea.innerHTML = textarea.value;
        }
    
        html2canvas(this.screen.nativeElement, {
          useCORS: true,
          foreignObjectRendering: true,
        }).then((canvas) => {
          this.capturedImage = canvas.toDataURL('image/png');
          this.changeDetectorRef.detectChanges();
        });
      }
    }
    
    bootstrapApplication(App);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search