Texture, CanvasTexture, Sprite로 이미지/텍스트 다루기
이미지와 텍스트는 2D editor에서 가장 까다로운 영역입니다. Three.js에서는 Texture, CanvasTexture, Sprite를 조합해 표시용 preview를 만들 수 있습니다.
image node는 texture로 본다
const texture = new THREE.Texture(imageBitmap);
texture.needsUpdate = true;
const material = new THREE.MeshBasicMaterial({ map: texture });
이미지 원본과 GPU texture는 별도 resource입니다. node가 삭제될 때 texture도 정리해야 합니다.
text preview는 CanvasTexture로 시작한다
const textCanvas = document.createElement("canvas");
drawTextToCanvas(textCanvas, textNode);
const texture = new THREE.CanvasTexture(textCanvas);
실제 텍스트 편집은 DOM input/contenteditable로 처리하고, canvas texture는 화면 표시용 preview로 쓰는 구성이 현실적입니다.
text preview texture를 갱신한다
function updateTextTexture(node, cache) {
let entry = cache.get(node.id);
if (!entry) {
const canvas = document.createElement("canvas");
const texture = new THREE.CanvasTexture(canvas);
texture.colorSpace = THREE.SRGBColorSpace;
entry = { canvas, texture };
cache.set(node.id, entry);
}
const ctx = entry.canvas.getContext("2d");
const dpr = Math.min(window.devicePixelRatio || 1, 2);
entry.canvas.width = Math.ceil(node.width * dpr);
entry.canvas.height = Math.ceil(node.height * dpr);
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
ctx.clearRect(0, 0, node.width, node.height);
ctx.font = `${node.fontWeight} ${node.fontSize}px ${node.fontFamily}`;
ctx.fillStyle = node.fill;
ctx.fillText(node.text, 0, node.fontSize);
entry.texture.needsUpdate = true;
return entry.texture;
}
텍스트가 바뀔 때마다 mesh를 새로 만드는 것이 아니라 texture만 갱신합니다. 편집 중에는 DOM overlay가 입력을 담당하고, 편집이 끝나면 preview texture를 갱신하는 흐름이 안정적입니다.
오늘의 핵심
Three.js가 텍스트 editor를 만들어주지는 않습니다. 표시용 texture와 편집용 DOM을 나누는 판단이 필요합니다.