HTML2Canvas DOM(角度)

Posted

技术标签:

【中文标题】HTML2Canvas DOM(角度)【英文标题】:HTML2Canvas DOM (Angular) 【发布时间】:2014-09-12 15:53:04 【问题描述】:

我是 JS 和一般开发的新手,但我希望能得到一些帮助来解决我几天来一直试图解决的问题。

基本上,我正在尝试让 html2Canvas 与 Angular 一起使用。我的部分 HTML 文件中有一个 div(ID 为“发票”),并且我的控制器中有以下内容:

sampleApp.controller('InvoiceController', function($scope) 
    $(document).ready(function()
    var source = document.getElementById('invoice');




        $( '.submit' ).click(function() 

          html2canvas(source, 
               logging: 'on',
              allowTaint: 'true',
             onrendered: function(canvas) 
                  var myImage = canvas.toDataURL("image/jpeg");
                 window.open(myImage);
            
         );



        );
);

我完全不知道为什么这不起作用。该脚本运行没有任何错误,但它只是踢出一个没有图像的空白页面。看起来它与 DOM 相关,因为这是我在控制台中得到的:

html2canvas: Preload starts: finding background-images html2canvas.js:21
html2canvas: Preload: Finding images html2canvas.js:21
html2canvas: Preload: Done. html2canvas.js:21
html2canvas: start: images: 0 / 0 (failed: 0) html2canvas.js:21
Finished loading images: # 0 (failed: 0) html2canvas.js:21
html2canvas: Renderer: Canvas renderer done - returning canvas obj 

编辑:我想补充一点,我知道它与 Angular 中的 DOM 加载方式有关的另一个原因是因为使用 document.body 作为 var 有效。不过,我只是想用单个 div 制作图像。

【问题讨论】:

console.log(source); 添加为点击处理程序的第一行,以确保您确实拥有源元素。 非常感谢您的及时回复,乔恩。我试过了,'source' div 正确地出现在控制台中。有什么想法吗? 仔细检查源console.log($(source).innerHTML());的内容。我不知道您是否在控制台中扩展了先前的源节点以检查其内容。这将明确地做到这一点。 好的,所以当我尝试 console.log(source);我能够在控制台中扩展它,并且它的内容都在那里,即使 HTML2Canvas 没有生成它们的图像。当我替换 console.log(source);使用 console.log($(source).innerHTML());它抛出一个错误:“Uncaught TypeError: undefined is not a function” 我的错...尝试console.log($(source).html());,但看起来您从描述中捕获source 很好。尝试捕获一个应用了很少 CSS 的简单块,例如 <div id="test"><p>Hello</p><p>World</p></div> 【参考方案1】:

以下是我在项目中使用的确切指令,它也适用于 svg,因此也可以渲染图表:

(function () 
    'use strict';

angular
    .module('myModule')
    .directive('camera', camera);

camera.$inject = ['$rootScope'];

/* @ngInject */
function camera($rootScope) 
    var directive = 
        link: link,
        restrict: 'A'
    ;

    return directive;

    function link(scope, element, attrs) 
        $rootScope.$on('capture', function (event, deferred) 
            event.stopPropagation();

            renderSvg(element);

            //method to render the SVG's using canvg
            function renderSvg(element) 
                // First render all SVGs to canvases
                var elements = element.find('svg').map(function () 
                    var svg = $(this);
                    var canvas = $('<canvas></canvas>');
                    svg.replaceWith(canvas);

                    // Get the raw SVG string and curate it
                    var content = svg.wrap('<p></p>').parent().html();
                    content = content.replace(/xlink:title="hide\/show"/g, "");
                    content = encodeURIComponent(content);
                    svg.unwrap();

                    // Create an image from the svg
                    var image = new Image();
                    image.src = 'data:image/svg+xml,' + content;
                    image.onload = function () 
                        canvas[0].width = image.width;
                        canvas[0].height = image.height;

                        // Render the image to the canvas
                        var context = canvas[0].getContext('2d');
                        context.drawImage(image, 0, 0);
                    ;
                    return 
                        svg: svg,
                        canvas: canvas
                    ;
                );

                    // At this point the container has no SVG, it only has HTML and Canvases.
                    html2canvas(element[0], 
                        useCORS: true,
                        allowTaint: true,
                        onrendered: function (canvas) 
                            // Put the SVGs back in place
                            elements.each(function () 
                                this.canvas.replaceWith(this.svg);
                            );

                            var dataURL = null;

                            try 
                                dataURL = canvas.toDataURL("image/png", 0.9);
                                deferred.resolve(dataURL);
                            
                            catch (e) 
                                deferred.reject(e);
                            
                        
                    );
            
        );
    

)();

引用上述指令并在控制器中使用以下代码来调用指令中的功能:

        var deferred = $q.defer();
        $scope.$emit('capture', deferred);

            deferred.promise.then(function (screenshot) 
                //do something with screenshot (Base64Url for .png type)
            );

【讨论】:

以上是关于HTML2Canvas DOM(角度)的主要内容,如果未能解决你的问题,请参考以下文章

html2canvas:将dom转换为画布

[JavaScript] 利用html2canvas实现dom元素转图片下载

网页中DOM元素转换成图片

js截图及绕过服务器图片保存至本地(html2canvas)

vue使用html2canvas

vue中dom节点转图片