구현 방향
글상자안에서 작성이 끝나면 캔버스 이미지를 만들어서 썸네일 역할을 하려고한다.
구현
// Drawing DOM Objects into a canvas
function draw(target) {
if (target.attributes[2] || target.attributes[3])
target.setAttribute("width", 0)
target.setAttribute("height", 0)
const canvas = target;
const dpr = window.devicePixelRatio;
let ctx = canvas.getContext('2d');
if (!ctx)
return
const htmlMeta = CKEDITOR.instances.introduction.getData()
const data = `
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<style> div { font-family: MalgunGothic; font-size: 14px; } table { table-layout: fixed; border-spacing: 0; border-collapse: collapse;} p { margin: 0 0 10px; }</style>
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">
${htmlMeta}
</div>
</foreignObject>
</svg>`;
const DOMURL = window.URL || window.webkitURL || window;
const img = new Image();
const svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
const url = DOMURL.createObjectURL(svg);
ctx.canvas.style.border = (document.querySelector(`#${Object.getOwnPropertyNames(CKEDITOR.instances)[0]}`).style.border === '' ?
'1px hidden black' : document.querySelector(`#${Object.getOwnPropertyNames(CKEDITOR.instances)[0]}`).style.border)
ctx.canvas.style.background = document.querySelector(`#${Object.getOwnPropertyNames(CKEDITOR.instances)[0]}`).style.background
ctx.canvas.width = editingArea.offsetWidth * dpr
ctx.canvas.height = editingArea.offsetHeight * dpr
ctx.canvas.style.width = `${editingArea.offsetWidth}px` //css
ctx.canvas.style.height = `${editingArea.offsetHeight}px`
img.onerror = function () {
console.log('That image was not loaded')
}
img.onload = function () {
ctx.scale(dpr, dpr);
ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height)
DOMURL.revokeObjectURL(url)
}
img.src = url
}
위 코드는 아래와 같은 단계를 거치고 있다.
- 캔버스 엘리먼트 및 id 선언
- 2d 컨버스 객체 그리기
- svg요소 + foreignObject요소 + editor에서 작성한 html 메타데이터 가져오기
- Blob(Binary Large Object)을 이용하여 이미지 생성
- URL.createObjectURL() 사용하여 DOMString 으로 변환
- url을 할당하고 이미지 로드 시 컨텍스트에 이미지 띄우기
구현 중 해상도가 높은 모니터에서 텍스트가 흐릿하게 보이는 현상(text blurry)이 발생했다.
Canvas 크기와 화면에 표시(디스플레이) 되는 크기는 다르며, 디스플레이 크기는 DPR의 영향을 받는다는 사실을 알게되었다.
DPR는 웹 브라우저에서 전역변수 window.devicePixelRatio 로 확인해볼 수 있는데, CSS 픽셀을 구성하는데 필요한 물리적 픽셀 수 를 의미한다.Canvas 요소의 width, height 속성을 DPR 배율로 계산해 주고 디스플레이 크기(CSS에서 지정해 준 width, height 값)와 맞춰주기 위해 scale을 조정 했다.
'웹개발 관련' 카테고리의 다른 글
Creating a Simple CKEditor4 Plugin (0) | 2022.05.12 |
---|---|
한글 웹 폰트 경량화해보기 (0) | 2022.04.27 |
Visual Studio Cod Extension - Better Comments (0) | 2021.07.27 |
Web Server와 WAS(Web Application Server) 및 Apache Http Server 설치 (0) | 2021.07.15 |
CSR(Client Side Rendering)과 SSR(Server Side Rendering)의 차이 (0) | 2021.05.30 |