From af53219dcc9e676e8efc34f33d836c87138d7a00 Mon Sep 17 00:00:00 2001 From: "hehihoho3@gmail.com" Date: Wed, 8 Jul 2026 17:57:37 +0900 Subject: [PATCH] =?UTF-8?q?feat(comment-cards):=20=EB=8B=A8=EC=96=B4=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EA=B0=80=EB=A6=AC=EA=B8=B0(=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EB=AA=A8=EC=9E=90=EC=9D=B4=ED=81=AC)=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기본은 댓글 단어 클릭 시 해당 단어만 블러(다시 클릭 해제). '🖍 단어 가리기' 토글을 끄면 카드 클릭=이미지 복사로 전환. 블러는 캡처 PNG에도 그대로 반영됨. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/main/resources/static/js/comment-cards.js | 35 ++++++++++++++++--- .../resources/templates/comment-cards.html | 10 ++++-- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/main/resources/static/js/comment-cards.js b/src/main/resources/static/js/comment-cards.js index 63a72f0..9466d17 100644 --- a/src/main/resources/static/js/comment-cards.js +++ b/src/main/resources/static/js/comment-cards.js @@ -2,8 +2,9 @@ window.__all = []; // 전체 수집 댓글(분석 기준) window.__cards = []; // 호환용 별칭 window.__videoId = null; // 타임라인 링크용 - let mosaicOn = true; // 모자이크 기본 ON + let mosaicOn = true; // 프로필·아이디 모자이크 기본 ON let roundedOn = false; // 모서리 둥글게 토글(기본: 각진 모서리) + let wordMaskOn = true; // 단어 가리기 기본 ON(단어 클릭=가림). 끄면 카드 클릭=복사. const DISPLAY_CAP = 2000; // 카드 DOM 렌더 상한(브라우저 보호). 분석은 전체 기준. @@ -66,6 +67,24 @@ return function () { clearTimeout(h); h = setTimeout(fn, ms); }; } + // 댓글 텍스트를 단어 span으로 분해(공백/줄바꿈 보존). 단어 가리기 ON일 때 클릭하면 해당 단어만 블러. + function buildWords(el, plain) { + el.textContent = ''; + for (const p of plain.split(/(\s+)/)) { + if (!p) continue; + if (/^\s+$/.test(p)) { el.appendChild(document.createTextNode(p)); continue; } + const s = document.createElement('span'); + s.className = 'cc-word'; + s.textContent = p; + s.addEventListener('click', (e) => { + if (!wordMaskOn) return; // 꺼짐 모드: 무시 → 이벤트 버블 → 카드 클릭=복사 + e.stopPropagation(); + s.classList.toggle('masked'); + }); + el.appendChild(s); + } + } + function applyFilterSort(cards) { const sort = $('ccSort').value; const minLikes = parseInt($('ccMinLikes').value, 10) || 0; @@ -91,6 +110,7 @@ if (capped) list = list.slice(0, DISPLAY_CAP); $('ccCount').textContent = total.toLocaleString() + '개' + (capped ? ' (상위 ' + DISPLAY_CAP.toLocaleString() + '개 표시)' : ''); + grid.classList.toggle('wordmask', wordMaskOn); grid.innerHTML = ''; list.forEach((c, i) => { const card = document.createElement('div'); @@ -115,11 +135,11 @@ ''; head.querySelector('.cc-author').textContent = c.authorName || ''; head.querySelector('.cc-time').textContent = timeAgo(c.publishedAt); - head.querySelector('.cc-text').textContent = toPlainText(c.text); + buildWords(head.querySelector('.cc-text'), toPlainText(c.text)); - // 카드 자체를 클릭하면 복사 (클립보드) - card.title = '클릭하면 이미지 복사 · 저장 버튼은 PNG 파일로 내려받기'; - card.addEventListener('click', () => window.copyCard(card)); + // 단어 가리기 ON: 카드 클릭 복사 잠금(단어 클릭으로 가림). OFF: 카드 클릭=복사. + card.title = '단어 클릭 = 가리기 · 토글을 끄면 카드 클릭 = 복사'; + card.addEventListener('click', () => { if (wordMaskOn) return; window.copyCard(card); }); // 저장(다운로드) 버튼 — cc-noexport라 캡처 이미지엔 안 찍힘. 캡컷엔 이 파일을 불러오기. const actions = document.createElement('div'); @@ -470,5 +490,10 @@ $('ccRounded').textContent = roundedOn ? '모서리 각지게' : '모서리 둥글게'; document.querySelectorAll('.comment-card').forEach(el => el.classList.toggle('rounded', roundedOn)); }); + $('ccWordMask').addEventListener('click', () => { + wordMaskOn = !wordMaskOn; + $('ccWordMask').textContent = wordMaskOn ? '🖍 단어 가리기: 켜짐' : '🖍 단어 가리기: 꺼짐(복사)'; + $('cardGrid').classList.toggle('wordmask', wordMaskOn); + }); }); })(); diff --git a/src/main/resources/templates/comment-cards.html b/src/main/resources/templates/comment-cards.html index 0837085..69bc37b 100644 --- a/src/main/resources/templates/comment-cards.html +++ b/src/main/resources/templates/comment-cards.html @@ -42,6 +42,11 @@ /* 모자이크 */ .comment-card.mosaic .cc-avatar { filter: blur(6px); } .comment-card.mosaic .cc-author { filter: blur(5px); } + /* 단어 가리기: '단어 가리기 켜짐'일 때 단어에 포인터, 클릭하면 .masked로 블러 */ + .cc-word { cursor: default; } + .cc-grid.wordmask .cc-word { cursor: pointer; } + .cc-grid.wordmask .comment-card { cursor: default; } + .cc-word.masked { filter: blur(4px); } .cc-empty { color:var(--text-3); padding:2rem 0; } /* ---- 분석 패널 ---- */ @@ -83,7 +88,7 @@

댓글 카드

유튜브 링크의 전체 댓글을 가져와 분석(많이 언급된 타임라인·자주 나온 단어·요약 통계)하고 카드로 만듭니다. - 모자이크는 기본 켜짐, 모서리 둥글게로 각진/라운드 전환. 카드 클릭=이미지 복사, ⬇ 저장=PNG 파일 다운로드(캡컷은 붙여넣기가 안 되니 저장한 파일을 "불러오기" 하세요). + 모자이크는 기본 켜짐, 모서리 둥글게로 각진/라운드 전환. 기본은 단어 클릭=가리기(블러), 🖍 단어 가리기를 끄면 카드 클릭=이미지 복사. ⬇ 저장=PNG 파일 다운로드(캡컷은 붙여넣기가 안 되니 저장한 파일을 "불러오기" 하세요).

@@ -105,6 +110,7 @@ 답글 있는 것만 +
@@ -117,7 +123,7 @@ - +