최근 회사에서 canvas가 있는 div를 프린트 해야하는 상황이 필요했다.
canvas 요소를 이미지로 변환하지 않고 window.print()로 직접 인쇄하는 것은 일반적으로 어렵습니다.
window.print()는 현재 창의 내용을 인쇄 대화 상자에 표시하는 기능을 제공하며, 내용으로는 HTML 요소들이 포함될 수 있습니다.
그러나 canvas 요소는 이미지를 그리기 위한 비트맵 영역을 제공하고, 픽셀 단위로 그림을 그리기 때문에 일반적인 HTML 요소와는 다른 방식으로 동작합니다.
canvas태그를 불러와서 toDataURL()을 실행시켜 img태그를 만든것에 src로 넣어서 실행해야했다.
-문제-
근데 이걸 바로 window.print()를 했을때 빈 페이지가 나오는 문제가 발생했다.
처음엔, window.print()가 비동기로 동작하나했다.
근데, 가끔씩 바로 나오는 걸 보고 비동기 동작은 아니라는 결론이 났다.
-결론-
해결책은 img를 불러오는과정이 비동기로 동작한다.
그래서 img load가 되는 이벤트가 실행되기전에, window.print()가 실행되면서, 해당 이미지가 나오지 않았다.
그래서 create한 img element에 load 이벤트를 걸어서 window.print()를 실행하면 로드됐을때 정상작동한다.
해당 작업이 비동기작업이므로, 사이사이 로딩과정의 셋업은 필요해보인다.
function print() {
// map을 갖고있는 div
const modal = document.getElementById('modalMap')
// 출력할 section @media print를 통해 셋팅가능
let section = document.getElementById('print')
if (!section) {
section = document.createElement('div')
section.id = 'print'
document.body.appendChild(section)
}
//img 생성
const img = document.createElement('img')
img.src = modal.querySelector('canvas').toDataURL()
section.innerHTML = ''
section.appendChild(img)
//load시 실행
img.addEventListener('load', function () {
window.print()
})
}
//출력을 위한 미디어커리
@media print {
body * {
visibility: hidden;
}
#print,
#print * {
visibility: visible;
}
#print {
position: absolute;
margin-left: 30px;
width: 100%;
height: 100%;
top: 0;
}
}
코드첨부