#javascript #leaflet #webgl #html2canvas
#javascript #листовка #webgl #html2canvas
Вопрос:
У меня есть карта, отображаемая с помощью leaflet
.
Мне нужно сделать снимок экрана этой карты с помощью html2canvas
.
Чтобы использовать html2canvas
, мне нужно предоставить элемент DOM для capture ( elementToCapture
) и необязательную конфигурацию ( html2canvasConfiguration
) .
var html2canvasConfiguration = {
useCORS: true,
width: map._size.x,
height: map._size.y,
backgroundColor: null,
logging: true,
imageTimeout: 0
};
var elementToCapture = map._container.getElementsByClassName('leaflet-pane leaflet-map-pane')[0];
html2canvas(elementToCapture, html2canvasConfiguration).then(function (canvas) {
var link = document.createElement('a');
link.download = 'test.png';
link.href = canvas.toDataURL();
link.click();
link.remove();
})
Я извлекаю элемент по leaflet-pane leaflet-map-pane
классу, который в основном представляет всю карту, включая элементы управления (кнопки увеличения / уменьшения масштаба, масштабирование и т. Д.), Пользовательские маркеры, всплывающие подсказки, наложения, всплывающие окна.
Весь DOM выглядит так
<div class="leaflet-pane leaflet-map-pane">
<div class="leaflet-pane leaflet-tile-pane">
<div class="leaflet-gl-layer mapboxgl-map">
<div class="mapboxgl-canvas-container">
<canvas class="mapboxgl-canvas leaflet-image-layer leaflet-zoom-animated"></canvas>
</div>
<div class="mapboxgl-control-container"></div>
</div>
</div>
<div class="leaflet-pane leaflet-shadow-pane"></div>
<div class="leaflet-pane leaflet-overlay-pane"></div>
<div class="leaflet-pane leaflet-marker-pane"></div>
<div class="leaflet-pane leaflet-tooltip-pane"></div>
<div class="leaflet-pane leaflet-popup-pane"></div>
<div class="leaflet-control-container"></div>
Проблема, с которой я столкнулся, заключается leaflet-pane leaflet-tile-pane
в том, что элемент (в частности, содержимое внутреннего canvas
) не захватывается html2canvas
. Проще говоря, я вижу все на карте, но я не вижу саму карту.
ОБНОВЛЕНИЕ 1:
Версия, которую я использую в настоящее время, является 1.0.0-rc.1
(последней).
ОБНОВЛЕНИЕ 2:
Природа холста такова webgl
. Может ли это быть проблемой? В соответствии с этим они поддерживают webgl
холсты.
ОБНОВЛЕНИЕ 3:
Я попытался получить холст программно и вызвать toDataURL
его. Это привело к пустому скриншоту, даже при preserveDrawingBuffer
взломе.
ОБНОВЛЕНИЕ 4:
Как ни странно, он захватывает не только определенные холсты. Я создал 2d
холст (путем добавления preferCanvas
в конфигурацию карты), и он был показан.
Комментарии:
1. github.com/niklasvh/html2canvas/issues/1311 Может ли это быть как-то связано? Они добавили возможность
removeContainer: false
временно исправить это.2. Проблема должна быть исправлена в последней версии от 4/10/2019: github.com/niklasvh/html2canvas/releases/tag/v1.0.0-rc.1
3. @TheBlackIPs Спасибо. Я только что попробовал, и это ничего не изменило. Я использую последнюю версию.
4. Когда вы вызываете html2canvas? Вы уверены, что у страницы было время для рендеринга? Есть ли какой-либо способ, которым вы могли бы предоставить пример в виде фрагмента?
5. @TheBlackIPs да, я уверен. Код выполняется при нажатии кнопки. Кнопка отображается на слое управления картой.
Ответ №1:
Попробуйте это, добавьте это в начало своей страницы перед любыми другими сценариями
<script>
HTMLCanvasElement.prototype.getContext = function(origFn) {
return function(type, attribs) {
attribs = attribs || {};
attribs.preserveDrawingBuffer = true;
return origFn.call(this, type, attribs);
};
}(HTMLCanvasElement.prototype.getContext);
</script>
Помогает ли это?
Комментарии:
1. Я хочу поцеловать тебя 🙂 Не могли бы вы подробнее рассказать о том, почему это работает? Принудительно ли он
html2canvas
устанавливаетсяpreserveDrawingBuffer
каждый раз, когда извлекает контекст холста?2. Вы не можете установить атрибуты canvas после получения контекста. Они могут быть установлены только один раз во время создания
3. должно ли это быть встроено или есть какое-либо более приятное / чистое решение?
4. Вы можете поместить это в сценарий и включить его.
5. Хороший! Я был в тупике