1. Blob의 미디어 유형은 "image/svg+xml
"여야 합니다. image/svg+xml
"
2.需要一个 svg 元素
3.在 svg 元素里面插入一个 foreignObject
元素
4.在 foreignObject 元素里面放入符合规范的 html
把dom转成canvas就这么简单,就上面几个步骤。下面是文档给出的一上简单的demo:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <canvas id="canvas" width="200" height="200"> </canvas> <script> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' + '<foreignObject width="100%" height="100%">' + '<div xmlns="http://www.w3.org/1999/xhtml" >' + '<em>I</em> like ' + '<span >' + 'cheese</span>' + '</div>' + '</foreignObject>' + '</svg>'; var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); var svg = new Blob([data], {type: 'image/svg+xml'}); var url = DOMURL.createObjectURL(svg); img.onload = function() { ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); } img.src = url; </script> </body> </html>
复制代码,运行一下,哇,帅呆了,浏览器上出现了超酷的两行艺术字呢!
嗯,原来dom转成canvas这么简单啊?那我通过 document.body.innerHTML
把body里面的所有dom取出来,然后放到 foreignObject 元素里面,不就OK了、把整个页面都截取下来了吗?
demo仅仅是个Hello World,但是实际项目中的Dom结构比这个复杂多了,比如,引入了外部样式表、图片、而且还可能某些标签不符合xml规范(如缺少闭合标签等)。下面的举个简单的例子,.container不是使用行内样式的,而是在style标签里面定义,字体红色,转成图片后,样式不生效。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> .container { color: red; } </style> </head> <body> <div class="container" > Hello World! </div> <canvas id="canvas" width=200" height="200"> </canvas> <script> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' + '<foreignObject width="100%" height="100%">' + '<div xmlns="http://www.w3.org/1999/xhtml" >' + document.querySelector('.container').innerHTML + '</div>' + '</foreignObject>' + '</svg>'; var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); var svg = new Blob([data], {type: 'image/svg+xml'}); var url = DOMURL.createObjectURL(svg); img.onload = function() { ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); } img.src = url; </script> </body> </html>
既然外部样式不生效,那我们可以通过JS遍历所有的dom元素,把全部的样式通过element.style对象添加到行内样式啊。这个思路听起来不错,但是,实现这个把外部样式转成行内样式的函数我还真写不出来啊。需求比较紧,也没有那 多时间去瞎折腾了,所以,就想找找有没有现成的库。于是又去google一下。很幸运, 一下子就搜到了一个叫做html2canvas的库,非常棒的一个库,很强大、但用法非常简单.就这么简单的方法,就可以把我的整个页面截图下来了:
function convertHtml2Canvas() { html2canvas(document.body, { allowTaint: false, taintTest: true }).then(function(canvas) { document.body.appendChild(canvas); }).catch(function(e) { console.error('error', e); }); }
目前还有一个问题,就是这种方法默认是把整个页面截取下来的(就是说,会以你的innerHeight和innerWidth为边界,会存在大量的空白),可是,我的卡组只是占了页面的一小部分,我只想要卡组的部分啊。其实已经有了canvas就好办了,我们可以对它进行处理啊。大概思路是:1.把上面得到的canvas对象转成Blob并放到一个img元素。然后再把img.src绘制到canvas里面。这时候调用canvas.drawImage
// Converts canvas to an image function convertCanvasToImage(canvas) { var image = new Image(); image.src = canvas.toDataURL("image/png", 0.1); return image; } // Converts image to canvas; returns new canvas element function convertImageToCanvas(image, startX, startY, width, height) { var canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; canvas.getContext("2d").drawImage(image, startX, startY, width, height, 0, 0, width, height); return canvas; }
document.body.innerHTML
을 사용하여 본문의 DOM을 모두 꺼낸 다음 foreignObject 요소에 넣으면 괜찮지 않나요? 전체 페이지가 캡처됩니다. function convertHtml2Canvas() { html2canvas(document.body, { allowTaint: false, taintTest: true }).then(function(canvas) { var img = convertCanvasToImage(canvas); document.body.appendChild(img); img.onload = function() { img.onload = null; canvas = convertImageToCanvas(img, 0, 0, 384, 696); img.src = convertCanvasToImage(canvas).src; $(img).css({ display: 'block', position: 'absolute', top: 0, left: 400 + 'px' }); } }).catch(function(e) { console.error('error', e); }); }
canvas.drawImage
메소드를 호출하면 우리가 원하는 콘텐츠를 가로챌 수 있습니다. 다음 두 함수는 캔버스를 이미지로 변환하거나 그 반대로 변환합니다. 🎜rrreee🎜그런 다음 위에 작성한 ConvertHtml2Canvas를 다음과 같이 변경합니다. 🎜rrreee🎜 이때 페이지 내용의 일부가 가로채질 수 있습니다. 효과는 데크 공유 테스트 페이지와 같습니다. 페이지의 왼쪽 부분은 DOM 구조이고, 오른쪽 부분은 html2canvas를 이용하여 변환한 이미지입니다. 🎜위 내용은 JavaScript를 사용하여 스크린샷 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!