fix: html2canvas oklch/oklab 색상 파싱 에러 수정 #71
@ -1,5 +1,45 @@
|
||||
import html2canvas from 'html2canvas'
|
||||
|
||||
/**
|
||||
* html2canvas가 oklch()/oklab()/color-mix() 등 최신 CSS 색상 함수를 지원하지 않으므로
|
||||
* 캡처 전 모든 요소의 색상을 브라우저 computed RGB 값으로 강제 인라인 적용.
|
||||
* 캡처 후 원래 스타일로 복원하는 클린업 함수를 반환한다.
|
||||
*/
|
||||
const COLOR_PROPS = [
|
||||
'color', 'background-color',
|
||||
'border-color', 'border-top-color', 'border-right-color',
|
||||
'border-bottom-color', 'border-left-color',
|
||||
'outline-color', 'text-decoration-color',
|
||||
]
|
||||
|
||||
function forceResolvedColors(root: HTMLElement): () => void {
|
||||
const saved: { el: HTMLElement; cssText: string }[] = []
|
||||
const allElements = [root, ...Array.from(root.querySelectorAll('*'))] as HTMLElement[]
|
||||
|
||||
for (const el of allElements) {
|
||||
saved.push({ el, cssText: el.style.cssText })
|
||||
const cs = getComputedStyle(el)
|
||||
|
||||
for (const prop of COLOR_PROPS) {
|
||||
const val = cs.getPropertyValue(prop)
|
||||
if (val && val !== 'transparent' && val !== 'rgba(0, 0, 0, 0)') {
|
||||
el.style.setProperty(prop, val)
|
||||
}
|
||||
}
|
||||
|
||||
const shadow = cs.getPropertyValue('box-shadow')
|
||||
if (shadow && shadow !== 'none') {
|
||||
el.style.setProperty('box-shadow', shadow)
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
for (const { el, cssText } of saved) {
|
||||
el.style.cssText = cssText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DOM 요소를 PNG로 캡처 후 다운로드
|
||||
* @param contentEl 캡처할 콘텐츠 영역 (헤더 제외)
|
||||
@ -23,6 +63,9 @@ export async function captureAndDownload(
|
||||
modal.style.maxHeight = 'none'
|
||||
modal.style.overflow = 'visible'
|
||||
|
||||
// oklch/oklab → RGB 강제 변환 (html2canvas 호환)
|
||||
const restoreColors = forceResolvedColors(contentEl)
|
||||
|
||||
try {
|
||||
const canvas = await html2canvas(contentEl, {
|
||||
backgroundColor: isDark ? '#141820' : '#ffffff',
|
||||
@ -41,6 +84,7 @@ export async function captureAndDownload(
|
||||
} catch (err) {
|
||||
console.error('[captureAndDownload] 이미지 저장 실패:', err)
|
||||
} finally {
|
||||
restoreColors()
|
||||
contentEl.style.overflow = saved.elOverflow
|
||||
modal.style.maxHeight = saved.modalMaxHeight
|
||||
modal.style.overflow = saved.modalOverflow
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user