> 운영 및 유지보수 > 안전 > JavaScript를 사용하여 스크린샷 기능을 구현하는 방법

JavaScript를 사용하여 스크린샷 기능을 구현하는 방법

WBOY
풀어 주다: 2023-05-16 14:07:06
앞으로
1948명이 탐색했습니다.

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

2. svg 요소가 필요합니다.

3. svg 요소

4. 사양에 맞는 HTML을 foreignObject 요소에 넣습니다.🎜🎜dom을 캔버스로 변환하는 것은 위 단계만큼 간단합니다. 다음은 문서에 제공된 간단한 데모입니다. 🎜
// 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;
 }
로그인 후 복사
🎜 코드를 복사하고 실행해 보세요. 와, 브라우저에 두 줄의 멋진 워드 아트가 나타납니다! 🎜🎜글쎄, DOM을 캔버스로 변환하는 것이 그렇게 쉬운 줄 알았어요? 그런 다음 document.body.innerHTML을 사용하여 본문의 DOM을 모두 꺼낸 다음 foreignObject 요소에 넣으면 괜찮지 않나요? 전체 페이지가 캡처됩니다.
🎜🎜데모는 단지 Hello World이지만 실제 프로젝트의 Dom 구조는 이보다 훨씬 더 복잡합니다. 예를 들어 외부 스타일 시트, 그림 및 일부 태그가 xml 사양을 따르지 않을 수 있습니다. 닫는 태그가 없기 때문에) 잠깐만요). 다음은 간단한 예입니다. .container는 인라인 스타일을 사용하지 않지만 스타일 태그에 정의되어 있습니다. 글꼴은 이미지로 변환된 후에는 스타일이 적용되지 않습니다. 🎜
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);
  });
 }
로그인 후 복사
🎜외부 스타일은 적용되지 않으므로 JS를 통해 모든 DOM 요소를 탐색하고 element.style 개체를 통해 모든 스타일을 인라인 스타일에 추가할 수 있습니다. 이 아이디어는 좋은 것 같지만 외부 스타일을 인라인 스타일로 변환하는 함수를 실제로 작성할 수 없습니다. 수요도 빡빡하고, 여기저기 돌아다닐 시간도 별로 없어서 기성 라이브러리라도 찾아보고 싶어요. 그래서 다시 구글로 갔습니다. 다행히도 html2canvas라는 라이브러리를 단번에 찾았습니다. 매우 강력하면서도 사용하기 매우 간단한 라이브러리입니다. 이렇게 간단한 방법으로 전체 페이지의 스크린샷을 찍을 수 있습니다. 🎜rrreee🎜현재 문제는 다음과 같습니다. 이 메서드는 기본적으로 전체 페이지를 가로챕니다(즉, innerHeight와 innerWidth를 경계로 사용하고 공백이 많이 발생합니다). 그러나 내 데크는 페이지의 작은 부분만 차지합니다. 그냥 데크 부분을 원해요. 실제로 캔버스가 이미 있으면 처리하기가 더 쉽습니다. 일반적인 아이디어는 다음과 같습니다. 1. 위에서 얻은 캔버스 객체를 Blob으로 변환하고 img 요소에 넣습니다. 그런 다음 img.src를 캔버스에 그립니다. 이때 canvas.drawImage 메소드를 호출하면 우리가 원하는 콘텐츠를 가로챌 수 있습니다. 다음 두 함수는 캔버스를 이미지로 변환하거나 그 반대로 변환합니다. 🎜rrreee🎜그런 다음 위에 작성한 ConvertHtml2Canvas를 다음과 같이 변경합니다. 🎜rrreee🎜 이때 페이지 내용의 일부가 가로채질 수 있습니다. 효과는 데크 공유 테스트 페이지와 같습니다. 페이지의 왼쪽 부분은 DOM 구조이고, 오른쪽 부분은 html2canvas를 이용하여 변환한 이미지입니다. 🎜

위 내용은 JavaScript를 사용하여 스크린샷 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿