fix(comment-cards): 영상에서 확대 시 글자 깨지던 문제(저장 화질 상향)

캡처 배율이 2배 고정이라 카드(~320px)가 ~640px PNG로 저장돼 영상에서 확대하면
뭉개졌음. 화질 선택(2x/4x/6x/8x)을 추가하고 기본을 4배로 올림.
검정 배경 카드는 그레이스케일 안티에일리어싱을 적용해 색 번짐 제거.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
hehihoho3@gmail.com 2026-07-22 09:09:45 +09:00
parent 387cdc9400
commit fcfa4084e4
2 changed files with 22 additions and 3 deletions

View File

@ -7,6 +7,7 @@
let wordMaskOn = true; // 단어 가리기 기본 ON(단어 클릭=가림). 끄면 카드 클릭=복사.
let textScale = 1; // 내용 글자 크기 배율(카드 크기는 유지, .cc-text만 확대/축소)
let bgMode = 'black'; // 카드 배경 기본값: default|white|black (black이면 글자 흰색)
let exportScale = 4; // PNG 저장 배율(카드 CSS 픽셀 × 배율). 영상에서 확대해도 안 깨지게 기본 4배.
let dirHandle = null; // 저장 폴더(File System Access API). null이면 브라우저 다운로드 폴백.
let dirOptOut = false; // 사용자가 폴더 지정을 직접 해제 → '전체 저장' 시 다시 묻지 않음
const savedIds = new Set(); // 이미 저장한 댓글 id(재렌더·필터 변경에도 표시 유지)
@ -403,9 +404,10 @@
const wasSaved = cardEl.classList.contains('saved');
if (wasSaved) cardEl.classList.remove('saved');
try {
// scale = 저장 배율. 카드 폭이 ~320px라 2배로는 영상에서 확대 시 글자가 뭉개짐 → 기본 4배.
return await ms.domToBlob(cardEl, {
backgroundColor: null,
scale: 2,
scale: exportScale,
filter: (node) => !(node instanceof Element && node.classList.contains('cc-noexport')),
});
} finally {
@ -649,6 +651,11 @@
applyTextScale();
});
// 저장 화질(배율) — 캡처 시에만 쓰이므로 재렌더 불필요
$('ccScale').addEventListener('change', () => {
exportScale = parseInt($('ccScale').value, 10) || 4;
});
// 배경색: 기본 → 흰색 → 검정 순환. 검정이면 글자는 흰색(대비).
const BG_MODES = ['default', 'white', 'black'];
const BG_LABEL = { default: '배경: 기본', white: '배경: 흰색', black: '배경: 검정' };

View File

@ -47,7 +47,9 @@
.comment-card.bg-white { background:#ffffff; border-color:#e5e5e5; }
.comment-card.bg-white .cc-author, .comment-card.bg-white .cc-text { color:#0f0f0f; }
.comment-card.bg-white .cc-time, .comment-card.bg-white .cc-stats { color:#606060; }
.comment-card.bg-black { background:#000000; border-color:#333333; }
/* 어두운 배경 위 밝은 글자는 서브픽셀 AA에서 색 번짐이 생김 → 그레이스케일 AA로 또렷하게 */
.comment-card.bg-black { background:#000000; border-color:#333333;
-webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; }
.comment-card.bg-black .cc-author, .comment-card.bg-black .cc-text { color:#ffffff; }
.comment-card.bg-black .cc-time, .comment-card.bg-black .cc-stats { color:#aaaaaa; }
/* 글자 크기 스테퍼 */
@ -126,6 +128,7 @@
<p style="color:var(--text-3);margin-bottom:1.2rem;font-size:14px;">
유튜브 링크의 <b>전체 댓글</b>을 가져와 분석(많이 언급된 타임라인·자주 나온 단어·요약 통계)하고 카드로 만듭니다.
모자이크는 기본 켜짐, <b>모서리 둥글게</b>로 각진/라운드 전환. 기본은 <b>단어 클릭=가리기</b>(블러), <b>단어 가리기</b> 토글을 끄면 <b>카드 클릭=이미지 복사</b>. <b>저장 버튼=PNG 파일 다운로드</b>(캡컷은 붙여넣기가 안 되니 저장한 파일을 "불러오기" 하세요). <b>저장 폴더</b>를 고르면 저장·<b>전체 저장</b>이 그 폴더로 바로 갑니다(크롬/엣지).
영상에서 카드를 크게 확대해 쓸 거면 <b>화질</b>을 4x 이상으로 두세요(배율이 높을수록 저장이 느리고 파일이 큽니다).
</p>
<div class="cc-toolbar">
@ -155,6 +158,15 @@
<button class="cc-btn secondary" id="ccFontUp" aria-label="글자 크게" title="내용 글자 크게">A+</button>
</span>
<button class="cc-btn secondary active" id="ccBg" aria-pressed="true" title="배경색: 기본 → 흰색 → 검정 순환">배경: 검정</button>
<label style="font-size:13px;color:var(--text-2);display:flex;align-items:center;gap:.3rem;"
title="저장·복사되는 PNG의 배율. 영상에서 크게 확대할수록 높게">화질
<select id="ccScale" aria-label="저장 화질(배율)">
<option value="2">2x (가벼움)</option>
<option value="4" selected>4x (권장)</option>
<option value="6">6x</option>
<option value="8">8x (최고)</option>
</select>
</label>
<button class="cc-btn secondary" id="ccPickDir" aria-pressed="false"
title="클릭: 저장 폴더 지정 · 다시 클릭: 해제(브라우저 다운로드 폴더로 저장)"><i data-lucide="folder"></i> <span id="ccPickDirName">저장 폴더</span></button>
<button class="cc-btn secondary" id="ccSaveAll"><i data-lucide="download"></i> 전체 저장</button>
@ -170,7 +182,7 @@
<th:block layout:fragment="script">
<!-- DOM→이미지 캡처 (Task 5에서 사용). blur 필터 지원 위해 modern-screenshot 사용. -->
<script src="https://cdn.jsdelivr.net/npm/modern-screenshot@4/dist/index.js"></script>
<script th:src="@{/js/comment-cards.js(v=20260721b)}"></script>
<script th:src="@{/js/comment-cards.js(v=20260722)}"></script>
</th:block>
</body>
</html>