У меня есть div, содержащий все элементы, которые нужно преобразовать в изображение. И для этого div установлено значение « overflow: auto ». Я хочу знать, как я могу экспортировать все элементы (даже скрытые при прокрутке) в изображение. Я ценю и приветствую все ваши комментарии и ответы ...... Заранее спасибо ...
В настоящее время нет возможности визуализировать страницу с определенными параметрами, поэтому вам необходимо изменить страницу, чтобы она выглядела так, как вы хотите.
Другими словами, если вы удалите ограничение высоты / ширины, запустите html2canvas, а затем установите высоту / ширину обратно на прежнее значение, вы должны достичь того, что ищете.
Большое спасибо .... Я попробую то, что вы сказали ...
Я долго пытался ... Но это создает массу проблем ... Я не мог добиться того, что вы сказали. Я обнаружил, что он хорошо работает, когда это «тело», даже если есть прокрутка ... Я хочу добиться того же для div, у которого есть элементы с прокруткой ... Если бы вы могли помочь мне с этой проблемой, это было бы очень помогли мне ... Я с нетерпением жду ваших комментариев ...
@niklasvh , у меня такая же проблема, и я могу только уменьшить ширину целевого элемента перед вызовом html2canvas
(не всегда вариант) или вызвать html2canvas
дважды подряд для одного и того же элемента. Вот скрипка, чтобы продемонстрировать проблему:
http://jsfiddle.net/fMeRC/1/ (этот конкретный пример работает только для Chrome; вам нужно поиграть с шириной, чтобы увидеть проблему в других браузерах)
Это в основном происходит только тогда, когда элемент шире окна или (document.width - 8)
, я не уверен, что имеет более важное / прямое отношение, и это может измениться в других браузерах).
Вероятно, родственные: №199 и №108.
Пробовали childElement или установить «overflow = visible», а после установить «overflow = auto | hidden | inherit»?
childElement без стиля, только чтобы получить содержимое div с переполнением:
<div id="main"><!--// main div -->
<div class="mainContent"><!--// div without style (height: auto, width: auto, margin: 0, padding: 0) -->
...content...
html2canvas([$("#main div.mainContent").get(0)],...)
Спасибо за предложения, @brcontainer. Я пробовал подход overflow: visible
-> html2canvas( ... )
-> overflow: [old overflow]
, хотя вспышка скрытого / не скрытого / скрытого контента была слишком заметной (возможно, потому, что мой целевой элемент относительно сложно). Хотя я только что придумал слегка оптимизированный вариант обходного пути, который, кажется, имеет значение в этом отношении:
html2canvas( targetElement, {
onpreloaded: function(){ /* set parent overflow to visible */},
onparsed: function(){ /* reset parent overflow */ },
// ... onrendered, etc.
});
Это устанавливает переполнение как «видимое» только в течение (как мне кажется) самого короткого времени, необходимого h2c для правильного анализа цели, таким образом почти полностью устраняя вспышку, по крайней мере, в моем случае. То есть нам больше не нужно ждать завершения этапа рендеринга холста перед сбросом / повторным скрытием переполнения. Я понятия не имею, подойдет ли этот модифицированный подход для всех, но я считаю, что это более приятный обходной путь, чем вызов html2canvas( ... )
дважды подряд или добавление дополнительных материалов в DOM для обертывания целевого контента.
В любом случае, это все еще реальная ошибка, которую я хотел бы исправить. (Тем более, что ни один обходной путь, похоже, не работает для меня правильно в IE9 и 10, по крайней мере - не пробовал в IE11.)
_Примечание: вышеупомянутый обходной путь не будет работать с новейшей версией, которая в настоящее время находится в мастерской. Я не тестировал, но похоже, что вам нужно будет вместо этого использовать параметр oncloned
, и теперь в вашем обратном вызове будет вызываться сброс родительского переполнения на .then()
. (Также должна быть возможность сделать видимым только родительское переполнение внутри клонированного документа и не беспокоиться о сбросе чего-либо вообще.) _
Не понимаю, зачем вы так использовали, лучше бы так:
function SnapShotDOM(target,call){
var data = {};
//use jquery or getComputedStyle|style.overflow
data.overflow = /*get overflow property*/;
data.width = /*get width property*/;
data.height = /*get height property*/;
data.maxWidth = /*get maxWidth property*/;
data.maxHeight = /*get maxHeight property*/;
target.style.overflow="visible !important";
target.style.height="auto !important";
target.style.maxHeight="auto !important";
html2canvas(target, {
"onrendered": function(canvas) {
target.style.overflow = data.overflow;
target.style.width = data.width;
target.style.height = data.height;
target.style.maxWidth = data.maxWidth;
target.style.maxHeight = data.maxHeight;
call(canvas);
}
});
}
SnapShotDOM(document.body,function(canvas){
console.log(canvas);
});
или используйте класс:
<style>
*.html2canvasreset{
overflow: visible !important;
width: auto !important;
height: auto !important;
max-height: auto !important;
}
</style>
<script>
function SnapShotDOM(target,call){
var data = target.className;
target.className += " html2canvasreset";//set className - Jquery: $(target).addClass("html2canvasreset");
html2canvas(target, {
"onrendered": function(canvas) {
target.className = data;//old className - Jquery: $(target).removeClass("html2canvasreset");
call(canvas);
}
});
}
SnapShotDOM(document.body,function(canvas){
console.log(canvas);
});
</script>
Причина, по которой я не помещаю ничего, связанного с переполнением, в onrendered
заключается в том, что время между синтаксическим анализом и рендерингом может быть заметным, и сброс переполнения как можно скорее (т.е. сразу после анализа, перед рендерингом) предпочтительнее чтобы избежать видимой вспышки содержимого. Помещение сброса переполнения в onparsed
вместо этого выполняет это.
Я имел в виду "предварительную загрузку".
попробуй это:
function SnapShotDOM(target,call){
var data = target.className;
target.className += " html2canvasreset";//set className - Jquery: $(target).addClass("html2canvasreset");
html2canvas(target, {
"onparsed": function() {
target.className = data;//old className - Jquery: $(target).removeClass("html2canvasreset");
},
"onrendered": function(canvas) {
call(canvas);
}
});
}
SnapShotDOM(document.body,function(canvas){
console.log(canvas);
});
Я использую onpreloaded
по той же причине - это оптимизация, которая позволяет мне переместить скрытую часть переполнения в самый последний возможный момент, непосредственно перед этапом синтаксического анализа, тем самым минимизируя количество времени, в течение которого содержимое полностью видно на экране. Вы можете увидеть, как это работает, в коде здесь и здесь .
@niklasvh , эта проблема вообще связана с TODO, найденным здесь ( options.useOverflow
)?
какую версию вы, ребята, использовали? .. Я могу найти методы onparsed и onpreloaded в моей версии ..
Я использую html2canvas-0.5.0-alpha1
@ejlocop Эта проблема была зарегистрирована много лет назад для предыдущей версии и может не иметь отношения к вашему варианту использования (№ 511).
Решили проблему? paraa solution Я ищу что-то с моей диаграммой Ганта, вы мне нужны полностью ...
это не работает.
@pkpatels Почему не работает? Я запустил вашу скрипку, и предложения были воспроизведены без обрезания ...
У меня также была эта проблема, и решение, которое сработало для меня, предложено в: # 117
@uriklar Он работает для горизонтальной прокрутки, а не для вертикальной. Оформить заказ на мой div. Здесь есть три разных элемента.
@uriklar решение, которое вы предлагаете, также не работает, когда я прокручиваю div вниз и нажимаю полностью видимый.
Как насчет того, чтобы установить для высоты #text div значение auto перед рендерингом и сбросить его после? Это будет работать.
У меня все еще были проблемы с переполнением в самой последней версии (0.5.0-beta4). Я взял обходной путь примечании @usmonster ):
Примечание. Вышеупомянутый обходной путь не будет работать с новейшей версией, которая в настоящее время находится в мастерской. Я не тестировал, но похоже, что вам нужно будет вместо этого использовать опцию oncloned, и теперь в вашем обратном вызове для .then () будет вызываться сброс родительского переполнения. (Также должна быть возможность сделать исключительно видимым переполнение родителя внутри клонированного документа и вообще не беспокоиться о сбросе чего-либо.)
Таким образом, не изменяя фактический DOM вашей веб-страницы, вы можете изменить клонированный документ, используемый для рендеринга h2c, используя обратный вызов onclone
. На самом деле это довольно просто, вот мой вызов h2c:
var renderingPromise = html2canvas($(item), {
width: item.clientWidth,
height: item.clientHeight,
onclone: function(clone) {
$(clone).find('.grid-stack-item-content')
.css('overflow-x', 'auto')
.css('overflow-y', 'auto');
return true;
}
}).then(
function(c) {/* success */},
function() {/* fail */}
);
Единственное, что сработало для меня, - это поместить холст в iframe, вызвать внутри него html2canvas, вызвать toDataURL () на холсте, а затем передать это изображение обратно в верхнее окно с помощью обратного вызова. Я полагаю, вы также можете передать объект холста.
return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
if (typeof(options.onrendered) === "function") {
log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
options.onrendered(canvas);
}
return canvas;
});
изменить на
var width = options.width != null ? options.width : node.ownerDocument.defaultView.innerWidth;
var height = options.height != null ? options.height+node.ownerDocument.defaultView.innerHeight : node.ownerDocument.defaultView.innerHeight;
return renderDocument(node.ownerDocument, options, width, height, index).then(function (canvas) {
if (typeof(options.onrendered) === "function") {
log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
options.onrendered(canvas);
}
return canvas;
});
Это может решить вопрос о переполнении экрана (как по ширине, так и по высоте).
У xzw123 плохое решение: установка ownerDocument.defaultView.innerHeight
вручную заставляет его отвязаться от фактических событий изменения размера окна. Думаю, лучше всего это сделать в iframe. Я очень хочу попробовать решение Джордана.
Джордан, как вы в итоге использовали холст в iframe? Я пытаюсь это сделать сейчас. Я думаю, что это должно быть окончательное решение в html2canvas ... связь iframe должна быть невидимой вне API.
Ах да, выполнение этого в iframe с window.postMessage(myData, ... )
делает свое дело. Вы можете отправить обратно весь URL-адрес данных отрисованных пикселей. Я просто помещаю свой код рендеринга в HTML iframe, передаю данные, необходимые для рендеринга источника HTML, передаю его на холст, а затем возвращаю данные toDataUrl обратно.
+1
Привет. После поиска решений и наблюдения за тем, как работает код, я пишу собственное непростое решение.
https://gist.github.com/simonmysun/c6da13ce2827a374e71ccf07d9f08e2d
Это работает для меня, и я надеюсь, что это поможет кому-то, кто в этом нуждается.
Тем не менее, я все еще надеюсь, что в будущем он будет поддерживаться в этой библиотеке.
Я до сих пор не понимаю, но моя проблема в том, что изображение обрезается. при использовании хром версии 54.0.2840,99 м
(половина изображения сделана скриншотом, но другая половина имеет черный экран)
// the timeline show up 100%, but cut off, cause its static and not dynamic.
// (its cut off from the screen,but the size, and picture show as normal, 100% show)
// after moving to the canvas, everthing that not in the screen will get blank in chrome
// it depends to the user screen, if i zoom out my chrome, i get 100% image.
но при использовании Mozilla 50.0.2 он работает нормально без уменьшения масштаба. (100% изображение),
я не знаю почему.
код:
var zenleft = $("#leftPanel").width(); //calculate left side
var zenright = $(".dataPanel").width(); //calculate right side
var after = zenright + zenleft + 250; // add all
//add the css, even after add overflow still not working
$("#timelineTarget").css({"background-color":"white","width":after});
html2canvas(canvTimeline, {
onrendered: function (canvas) {
$("#previewImage").html(canvas);
getCanvas = canvas;
}
});
Наконец, я решил эту проблему, добавив
$("body").css({"width": "+="+after}); //after is a total of the width of the element i want to view
так
var zenleft = $("#leftPanel").width(); //calculate left side
var zenright = $(".dataPanel").width(); //calculate right side
var after = zenright + zenleft + 250; // add all
$("body").css({"width": "+="+after}); //add the body
//add the css
$("#timelineTarget").css({"background-color":"white","width":after});
html2canvas(canvTimeline, {
onrendered: function (canvas) {
$("#previewImage").html(canvas);
$("#timelineTarget").css({"background-color":"white","width":old}); //turn it back
$("body").css({"width": "-="+after}); //turn it back
getCanvas = canvas;
}
});
надеюсь, что это решит вашу проблему.
onclone может быть правильным методом. Вы можете изменить css, чтобы получить то, что хотите ....
Привет всем, у меня есть div, который можно прокручивать. Когда я отправляю ввод div как параметр холста, он просто отображает то, что доступно во вьюпорте. Я перебрал все решения. Я не понял. Может ли кто-нибудь сказать, как взять весь контент в div как снимок экрана.
@ruthraprakash , у меня была аналогичная проблема. Это работает для моих простых целей в последней версии:
function fullhtml2canvas(el) {
return new Promise(resolve => {
html2canvas(el, {
width: el.scrollWidth,
height: el.scrollHeight,
}).then(canvas => {
resolve(canvas);
});
});
}
У меня не получается сделать снимок экрана с временной шкалой. Я не получаю значение оси x. это просто создание образа временной диаграммы.
`demoFromHTML (e) {
e.preventDefault ();
let input = window.document.getElementById('divToPDF');
html2canvas(input)
.then((canvas) => {
const imgData = canvas.toDataURL('image/jpeg');
const pdf = new pdfConverter("l", "pt");
pdf.addImage(imgData, 'JPEG', 15, 110, 800, 250);
pdf.save('test.pdf');
});
}
`
Я долго пытался ... Но это создает массу проблем ... Я не мог добиться того, что вы сказали. Я обнаружил, что он хорошо работает, когда это «тело», даже если есть прокрутка ... Я хочу добиться того же для div, у которого есть элементы с прокруткой ... Если бы вы могли помочь мне с этой проблемой, это было бы очень помогли мне ... Я с нетерпением жду ваших комментариев ...
Пожалуйста, покажи мне, как твое тело работает
Самый полезный комментарий
@ruthraprakash , у меня была аналогичная проблема. Это работает для моих простых целей в последней версии: