Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    rendering pdf in the browser

    Hi,

    Smartcient version: Version v10.1p_2016-02-02/Enterprise Development Only (2016-02-02)
    Browser version: Chrome Version 50.0.2661.94 m

    We have a requirement to display pdf content in the browser. For business reasons we've decided to use a javascript library to display the content. This library is capable of rendering a base64 dataurl directly into a HTML5 <canvas>. So I have managed to do this by simply creating a Smartclient canvas object and setting the contents to a "canvas" as seen below.

    Code:
    this.newsStoryPDF = isc.Canvas.create({
                overflow: "auto",
                height: "*",
                getInnerHTML: function(){
                    return "<canvas id='" + this.getID() + "_pdfcanvas' style='border: 1px solid blue;'></canvas>";
                }
            });
    In a separate method I'm then able to get this canvas (with a unique id) and it's context and pass that to the pdf renderer as follows:
    Code:
    ...
    // get the JS canvas and canvas context
    var canvasForPDF = this.newsStoryPDF.getContentElement().getElementsByTagName("canvas")[0];
    var canvasContextForPDF = canvasForPDF.getContext("2d");
    // object required by the pdf renderer method which contains a property for the canvas context
    var renderContext = {
      context: canvasContextForPDF 
      viewport: someViewport    // just for illustration, 
    };
    ...
    load the pdf dataURL etc
    ...
    // finaly pass the canvas context to the pdf library method to render it
    pdflibrary.page.render(renderContext);  // this successfully renders the pdf to the canvas
    ...
    The problem I have with the above is that if the canvas gets redrawn or re-arranged etc, the rendered pdf disappears (because it's not part of the newsStoryPDF widget I suppose).
    So my question is, is this the right way of going about the problem or are there better ways of rendering pdfs using other Smartclient classes?

    #2
    You're essentially doing a Third party component integration. We'd definitely recommend you give that documentation a good read.

    As covered in that documentation - a redraw of the widget will re-generate the inner html, leading to the problem you're describing.
    Typically your options are:
    - avoid redraws (by setting redrawOnResize to false and possibly using logging to track whatever application code is leading to redraws unnecessarily).
    - if this isn't possible, add logic to reinsert the 3rd party element after a redraw completes or similar.

    However one thing to bear in mind - the Img class does render out an HTML img tag so this third party component may not be necessary -- you could possibly have an Img and simply set the src to a base64 encoded string ('data:image/gif,base64,<...>).

    Let us know if you encounter further problems here

    Regards
    Isomorphic Software

    Comment


      #3
      Alright thanks, that gives me a few ideas. An Img component won't suffice on it's own though because something needs to decode and render the pdf (base64 url). So I would still need the pdf library. A somewhat messy workaround for the moment is to render the pdf to a DrawPane (which has it's own <canvas>), then call DrawPane.getDataURL() and use this dataurl in an Img object by calling Img.setSrc(dataurl). It's not very efficient but the Img is then managed by Smartclient and redrawing/resizing etc is taken care of without the rendered pdf image disappearing.

      Comment


        #4
        Just to clarify - is the base64 URL that you are delivering to the browser actually just image data (that is, an encoded PNG for instance)? If so, the browser itself can render these as part of a plain HTML <img> tag. That's effectively what we're suggesting you do, by way of using our Img class.

        If your PDF library actually does base64 decoding client-side, and then uses <canvas> APIs to render a bunch of shape definitions that are found within the decoded base64 data, then yes, using DrawPane.getDataURL() is the right approach.

        Comment


          #5
          The base64 URL is a PDF which is only decoded on the client side by the PDF library. So yes I think we're on the same page and I can't simply use an Img object.

          Comment

          Working...
          X