简体   繁体   中英

Codemirror & html2canvas: Save iFrame as Image

Fiddle 1 (Using html2canvas ): http://liveweave.com/HM9hSY
Fiddle 2 (Using html2canvas without Codemirror ): http://liveweave.com/rS8yxI
Fiddle 3 (Using html2canvas with Codemirror ): http://liveweave.com/TF3Ono
Fiddle 4 (Using html2canvas with Codemirror ): http://liveweave.com/hqPoQg

Today I wanted to try and export an iframe as an Image. I did some research on this and came across a plugin called html2canvas which can save html as an image. (The documentation can be viewed here ).

Capture HTML Canvas as gif/jpg/png/pdf?
Using HTML5/Canvas/JavaScript to take in-browser screenshots

The first fiddle is just an experiment so save html as an image. (This fiddle is not using Codemirror )
The second fiddle saves the image but doesn't grab the iframe preview given from source. (This fiddle is not using Codemirror)
The third fiddle does not save an image. (This fiddle is not using Codemirror )

My problem is with the 2nd and 3rd fiddles where [html2canvas][17] does not save the iframe's preview.

I've been playing with this throughout yesterday and today and I haven't been successful.

Today I decided to try and use Codemirror's code editor to render what I want instead.

Basically I take a screenshot of the body and embed an image into it.

(This is Fiddle 4 I'm referring to).

I then open the image in a new window using window.open after that I reset the code editor back to where it was.

Is it possible to save an iframe's preview/source as an image? Am I doing anything wrong to achieve this effect?

 $(document).ready(function() { $("#saveimg").click(function() { html2canvas($("#preview"), { onrendered: function(canvas) { var myImage = canvas.toDataURL("image/png"); $("#imgprev").html("<img src='"+ myImage +"' />"); } }); }); }); 
 <script src="https://raw.github.com/niklasvh/html2canvas/gh-pages/build/html2canvas.js"></script> <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script> <link type='text/css' rel='stylesheet' href='http://necolas.github.io/normalize.css/3.0.1/normalize.css' /> <div align="center"> <p> <button id="saveimg"> Save as Image </button> </p> </div> <iframe id="preview" src="http://duckduckgo.com/"></iframe> <div id="imgprev"></div> <canvas id="mycanvas"></canvas> 

I suspect you are running into cross-origin restrictions. If you were able to open http://mybank.com in an iframe and get a screenshot of the resulting page, that might leak private information that was only meant for the user (whose session will be used). Thus, browser will not let you do this.

Fiddle: http://liveweave.com/LHfsld
Fiddle: http://jsbin.com/xutivucanaye/1/edit

It's not the best solution and a bit grotesque but I got it to work. Well kind of.

It doesn't work well with embedded images, iFrames, and it'll never have full CSS support (You can read why from html2canvas's FAQ )

Here's my entire snippet:

<!DOCTYPE html>
<html>
  <head>
    <title>Snap a Picture of Preview</title>
    <meta charset='utf-8'>
    <meta name='viewport' content='initial-scale=1.0'>
    <meta http-equiv='X-UA-Compatible' content='IE=9' />
    <link type='text/css' rel='stylesheet' href='http://necolas.github.io/normalize.css/3.0.1/normalize.css'/>
    <script type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js'></script>
    <script src='https://raw.github.com/niklasvh/html2canvas/gh-pages/build/html2canvas.js'></script>
    <script src='http://codemirror.net/lib/codemirror.js'></script>
    <script src='http://codemirror.net/mode/xml/xml.js'></script>
    <script src='http://codemirror.net/mode/javascript/javascript.js'></script>
    <script src='http://codemirror.net/mode/css/css.js'></script>
    <script src='http://codemirror.net/mode/htmlmixed/htmlmixed.js'></script>
    <link rel='stylesheet' href='http://codemirror.net/lib/codemirror.css'>
    <link rel='stylesheet' href='http://codemirror.net/doc/docs.css'>
    <script src='http://codemirror.net/mode/htmlmixed/htmlmixed.js'></script>
    <script src='http://codemirror.net/addon/edit/closetag.js'></script>
    <script src='http://codemirror.net/addon/edit/matchbrackets.js'></script>
    <script src='http://codemirror.net/addon/selection/active-line.js'></script>
    <style type='text/css'>
      .CodeMirror {
        float: left;
        width: 50%;
        border: 1px solid black;
      }

      iframe {
        width: 49%;
        float: left;
        height: 300px;
        border: 1px solid black;
        border-left: 0;
      }

      #beforeiframesnap {
        position: absolute;
        top: -500000px;
        left: -500000px;
        width: 0;
        height: 0;
        opacity: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div align='center'>
      <button class='snapFrame'>Snap</button>
    </div>
    <textarea id='code' name='code'><!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8>
    <title>HTML5 canvas demo</title>
    <style>p {font-family: monospace;}</style>
  </head>
  <body>
    <p>Canvas pane goes here:</p>
    <canvas id=pane width=300 height=200></canvas>

    <script>
      var canvas = document.getElementById('pane');
      var context = canvas.getContext('2d');

      context.fillStyle = 'rgb(250,0,0)';
      context.fillRect(10, 10, 55, 50);

      context.fillStyle = 'rgba(0, 0, 250, 0.5)';
      context.fillRect(30, 30, 55, 50);
    </script>
  </body>
</html></textarea>
    <textarea id='beforeiframesnap'></textarea>
    <iframe id='preview'></iframe>
    <div id='imgprev'></div>

    <script type='text/javascript'>
      $('#beforeiframesnap').val("");
      // Append JS library to HTML <head>
      function appendJSLib(txt) {
        var textArea = editor.getValue();
        var searchText = textArea.search('<head>');
        if(searchText>0) {
          txt = '<head>'+'\n'+txt;
          var updatedTextArea = textArea.replace('<head>',txt);
          editor.setValue(updatedTextArea);
        }
        else {
          reset();
          alert('WARNING! The &lt;head&gt tag seems to be missing in your HTML. Although your code may still work, we highly recommened that you have a valid HTML syntax. Please refer to the new document of correct formatted');
          txt = txt+textArea;
          htmlEditor.setLine(0, txt);
          return false;
        }
      }
      // Append script to HTML <body>
      function appendScript(txt) {
        var textArea = editor.getValue();
        var searchText = textArea.search('<body>');
        if(searchText>0) {
          txt = '<body>'+'\n'+txt;
          var updatedTextArea = textArea.replace('<body>',txt);
          editor.setValue(updatedTextArea);
        }
        else {
          reset();
          alert('WARNING! The <body> tag seems to be missing in your HTML. Although your code may still work, we highly recommened that you have a valid HTML syntax. Please refer to the new document of correct formatted');
          txt = txt+textArea;
          htmlEditor.setLine(0, txt);
          return false;
        }
      }

      $('.snapFrame').on('click', function() {
        $('#beforeiframesnap').val("").val(editor.getValue());
        txt = '<'+'script type=\'text/javascript\' src=\'http://code.jquery.com/jquery-latest.min.js\'>'+'</'+'script'+'>';
        appendJSLib(txt);
        txt = '<'+'script type=\'text/javascript\' src=\'https://raw.github.com/niklasvh/html2canvas/gh-pages/build/html2canvas.js\'>'+'</'+'script'+'>';
        appendJSLib(txt);
        txt = '<'+'script type=\'text/javascript\'>\n$(document).ready(function() {\n  html2canvas($(\'body\'), {\n    onrendered: function(canvas) {\n      var myImage = canvas.toDataURL(\'image/png\');\n      $(\'body\').html(\'<img src=\'+ myImage +\' />\');      window.open(\'javascript:document.write("<img src=\'+ myImage +\' />")\', \'Opened Page\', \'width=660, height=440\');\n    }\n  });\n});\n</'+'script'+'>';
        appendScript(txt);

        setTimeout(function() {
          editor.setValue($('#beforeiframesnap').val());
        }, 1200);
      });

      var delay;

      // Initialize CodeMirror editor
      var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
        mode: 'text/html',
        tabMode: 'indent',
        styleActiveLine: true,
        lineNumbers: true,
        lineWrapping: true,
        autoCloseTags: true
      });

      // Live preview
      editor.on('change', function() {
        clearTimeout(delay);
        delay = setTimeout(updatePreview, 300);
      });

      function updatePreview() {
        var previewFrame = document.getElementById('preview');
        var preview =  previewFrame.contentDocument ||  previewFrame.contentWindow.document;
        preview.open();
        preview.write(editor.getValue());
        preview.close();
      }
      setTimeout(updatePreview, 300);
    </script>
  </body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM