捕获包含内联svg的div并将其下载为图像

我编写代码来使用html5捕获页面的屏幕截图。 一切都很好,除非页面包含svg。 当我将svg转换为内联svg之后,该截图未捕获内联svg。

请检查https://jsfiddle.net/7bqukhff/4/

    

Scrrenshot

Generate Screenshot » $(function() { $('img').each(function() { var $img = jQuery(this); var imgID = $img.attr('id'); var imgClass = $img.attr('class'); var imgURL = $img.attr('src'); jQuery.get(imgURL, function(data) { // Get the SVG tag, ignore the rest var $svg = jQuery(data).find('svg'); // Add replaced image's ID to the new SVG if (typeof imgID !== 'undefined') { $svg = $svg.attr('id', imgID); } // Add replaced image's classes to the new SVG if (typeof imgClass !== 'undefined') { $svg = $svg.attr('class', imgClass + ' replaced-svg'); } // Remove any invalid XML tags as per http://validator.w3.org $svg = $svg.removeAttr('xmlns:a'); // Replace image with new SVG $img.replaceWith($svg); }, 'xml'); }); }); (function(exports) { function urlsToAbsolute(nodeList) { if (!nodeList.length) { return []; } var attrName = 'href'; if (nodeList[0].__proto__ === HTMLImageElement.prototype || nodeList[0].__proto__ === HTMLScriptElement.prototype) { attrName = 'src'; } nodeList = [].map.call(nodeList, function(el, i) { var attr = el.getAttribute(attrName); if (!attr) { return; } var absURL = /^(https?|data):/i.test(attr); if (absURL) { return el; } else { return el; } }); return nodeList; } function screenshotPage() { var wrapper = document.getElementById('wrapper'); html2canvas(wrapper, { onrendered: function(canvas) { canvas.toBlob(function(blob) { saveAs(blob, 'myScreenshot.png'); }); } }); } function addOnPageLoad_() { window.addEventListener('DOMContentLoaded', function(e) { var scrollX = document.documentElement.dataset.scrollX || 0; var scrollY = document.documentElement.dataset.scrollY || 0; window.scrollTo(scrollX, scrollY); }); } function generate() { screenshotPage(); } exports.screenshotPage = screenshotPage; exports.generate = generate; })(window);

对于这个特定的svg没有问题,但对于某些svg,捕获的图像与原始图像不同。

有没有使用html canvas捕获屏幕截图的方法? 如果不能如何更改我的代码以正确捕获svg元素?

我想现在每个人都熟悉很棒的屏幕截图扩展https://www.awesomescreenshot.com/ 。 他们如何进行此屏幕捕获?

在Angular 1(不是2或以上),React JS,Vue.js,Aurelia js或任何现代JavaScript库中是否有任何方法可以截取屏幕截图?

您可以使用名为canvg的JavaScript库(用于在canvas上正确呈现SVG)以及html2canvas来实现此目的

ᴡᴏʀᴋɪɴɢᴡᴏʀᴋɪɴɢxᴀᴍᴘʟᴇ

 $(function() { $('img').each(function() { var $img = jQuery(this); var imgID = $img.attr('id'); var imgClass = $img.attr('class'); var imgURL = $img.attr('src'); jQuery.get(imgURL, function(data) { // Get the SVG tag, ignore the rest var $svg = jQuery(data).find('svg'); // Add replaced image's ID to the new SVG if (typeof imgID !== 'undefined') { $svg = $svg.attr('id', imgID); } // Add replaced image's classes to the new SVG if (typeof imgClass !== 'undefined') { $svg = $svg.attr('class', imgClass + ' replaced-svg'); } // Remove any invalid XML tags as per http://validator.w3.org $svg = $svg.removeAttr('xmlns:a'); // Replace image with new SVG $img.replaceWith($svg); }, 'xml'); }); }); (function(exports) { function urlsToAbsolute(nodeList) { if (!nodeList.length) { return []; } var attrName = 'href'; if (nodeList[0].__proto__ === HTMLImageElement.prototype || nodeList[0].__proto__ === HTMLScriptElement.prototype) { attrName = 'src'; } nodeList = [].map.call(nodeList, function(el, i) { var attr = el.getAttribute(attrName); if (!attr) { return; } var absURL = /^(https?|data):/i.test(attr); if (absURL) { return el; } else { return el; } }); return nodeList; } function screenshotPage() { var wrapper = document.getElementById('wrapper'); html2canvas(wrapper, { onrendered: function(canvas) { function getOffset(el) { el = el.getBoundingClientRect(); return { left: el.left + window.scrollX, top: el.top + window.scrollY } } var cachedCanvas = canvas; var ctx = canvas.getContext('2d'); var svgs = document.querySelectorAll('svg'); svgs.forEach(function(svg) { var svgWidth = svg.width.baseVal.value; var svgHeight = svg.height.baseVal.value; var svgLeft = getOffset(svg).left - 40; var svgTop = getOffset(svg).top - 62; var offScreenCanvas = document.createElement('canvas'); offScreenCanvas.width = svgWidth; offScreenCanvas.height = svgHeight; canvg(offScreenCanvas, svg.outerHTML); ctx.drawImage(cachedCanvas, 0, 0); ctx.drawImage(offScreenCanvas, svgLeft, svgTop); }); canvas.toBlob(function(blob) { saveAs(blob, 'myScreenshot.png'); }); } }); } function addOnPageLoad_() { window.addEventListener('DOMContentLoaded', function(e) { var scrollX = document.documentElement.dataset.scrollX || 0; var scrollY = document.documentElement.dataset.scrollY || 0; window.scrollTo(scrollX, scrollY); }); } function generate() { screenshotPage(); } exports.screenshotPage = screenshotPage; exports.generate = generate; })(window); 
 @import url(https://fonts.googleapis.com/css?family=Merriweather); $red: #e74c3c; *, *:before, *:after { @include box-sizing(border-box); } html, body { background: #f1f1f1; font-family: 'Merriweather', sans-serif; padding: 1em; } h1 { text-align: center; color: #a8a8a8; @include text-shadow(1px 1px 0 rgba(white, 1)); } form { border: 2px solid blue; margin: 20px auto; max-width: 600px; padding: 5px; text-align: center; } input, textarea { border: 0; outline: 0; padding: 1em; @include border-radius(8px); display: block; width: 100%; margin-top: 1em; font-family: 'Merriweather', sans-serif; @include box-shadow(0 1px 1px rgba(black, 0.1)); resize: none; &:focus { @include box-shadow(0 0px 2px rgba($red, 1)!important); } } #input-submit { color: white; background: $red; cursor: pointer; &:hover { @include box-shadow(0 1px 1px 1px rgba(#aaa, 0.6)); } } textarea { height: 126px; } } .half { float: left; width: 48%; margin-bottom: 1em; } .right { width: 50%; } .left { margin-right: 2%; } @media (max-width: 480px) { .half { width: 100%; float: none; margin-bottom: 0; } } /* Clearfix */ .cf:before, .cf:after { content: " "; /* 1 */ display: table; /* 2 */ } .cf:after { clear: both; } .half.left.cf > input { margin: 5px; } 
     

Scrrenshot

Generate Screenshot »