JavaScript: сделать скриншот страницы или его части
Нужно сделать возможность наподобие той, что имеется у гугла - Send feedback, а конкретно часть со скриншотом страницы. Пробовал использовать html2canvas и dom-to-image, так они не умеют работать с svg (я использую fontawesome в своем приложении). Без svg тоже не везде скриншоты создает, часто вываливает ошибку Uncaught (in promise).
Event {isTrusted: true, type: "error", target: null, currentTarget: null, eventPhase: 0, …}
isTrusted: true
type: "error"
target: null
currentTarget: null
eventPhase: 0
bubbles: false
cancelable: false
defaultPrevented: false
composed: false
timeStamp: 8231.119999999919
srcElement: null
returnValue: true
cancelBubble: false
path: [img]
В перспективе, мне в целом не нужны метки, как у гугла, достаточно просто сделать скриншот страницы + кроп изображения по желанию пользователя. Что можно сделать в моей ситуации?
На всякий случай кусочек кода, где создается скриншот, но вряд ли он о чем-то скажет, я пока изучаю возможности:
$("#bugReportTakeScreenshot").click(function() {
domtoimage.toPng($(".wrapper")[0]).then(function (dataUrl) {
let image = new Image();
image.src = dataUrl;
$("#bugReportModalBlock").append(image);
});
});
Ответы (1 шт):
Разобрался в чем была проблема, на странице имелись элементы svg, помимо самого fontawesome (сам пак тоже перевел в обычные шрифты, отказавшись от svg), а именно от bootstrap'а (например, иконка для кастомного select, а также иконки прокрутки carousel). Из плагинов остановился на dom-to-image, поскольку с html2canvas страница превращается в какую-то мясорубку. В том же dom-to-image отфильтровал оставшиеся svg элементы, скрывая их на время генерации скриншота. Для кроппинга изображения использовал cropperjs. А еще dom-to-image не любит теги изображений без сурса. В общем, вот что вышло:
let restrictedNodes = [];
domtoimage.toJpeg($('.wrapper')[0], {
quality: 0.95,
bgcolor: $("body").css('background-color'),
filter: function (node) {
let $node = $(node);
if ($node.hasClass('custom-select')) {
$node.css('background-image', 'none');
restrictedNodes.push($(node));
} else if ($node.prop('tagName') == 'IMG' && ($node.attr('src') == undefined || $node.attr('src') == '')) {
return false;
} else if ($node.hasClass('carousel-control-prev') || $node.hasClass('carousel-control-next')) {
return false;
}
return true;
}
}).then(function(dataUrl) {
...
for (let node of restrictedNodes) {
node.css('background-image', '');
}
}