Skip to content

웹 콘텐츠를 깔끔하게 정리하고, 마스코트 모구와 함께 몰입해 읽는 크롬 확장 도구

Notifications You must be signed in to change notification settings

faber-h/mogu-read-extension

Repository files navigation

MoguRead

mogu-read-icon

“먹히기 전에 읽자 – 모구와 함께하는 몰입 독서”


MoguRead는 덜 중요한 문장을 먼저 정리하고,
시간 내에 읽지 못하면 모구가 문장을 "먹어버리는" 몰입형 독서 도구입니다.
웹에서 읽기, 이제는 게임처럼 즐겨보세요.


📖 목차


💥 개발 배경

웹에서 글을 읽다 보면,
진짜 중요한 한 줄을 찾기 위해 수많은 부연 설명과 예시, 주석을 지나쳐야 하는 일이 많습니다.

React 공식 문서에서 예를 들자면

export default 접두사는 표준 JavaScript 구문입니다(React에만 해당되지 않습니다).

괄호 안의 문장이 지금 내게 정말 필요한 정보일까요?

export default 접두사는 표준 JavaScript 구문입니다.

이처럼 핵심이 아닌 문장, 몰입을 방해하는 부가 설명들을
직접 정리하고, 읽고 싶은 부분만 남겨둘 수 있다면
읽기는 더 깔끔하고, 집중력 있는 경험이 될 수 있을 거라고 생각했습니다.

MoguRead는 이런 상상에서 출발한 프로젝트입니다.
읽는 행위에 집중하고, 몰입을 방해하는 요소들을 "먹어 치우는" 경험을 제공합니다.
작지만 귀여운 마스코트 모구(Mogu)가 독서에 함께하며, 읽기를 놀이처럼 만들어줍니다.


🔍 기능 소개

1. 정리 모드

  • 집중을 방해하는 문장을 제거하여 핵심 내용에 몰입할 수 있도록 도와주는 기능입니다.
  • 정리하고 싶은 문장을 드래그하면 "선택된 문장"으로 등록됩니다.
  • 선택된 문장은 클릭 시 하이라이트 되어 위치를 확인할 수 있습니다.
  • “정리 시작” 버튼을 누르면, 선택된 문장들이 페이지에서 제거됩니다.
  • 정리된 문장을 클릭하면 해당 문장이 있었던 위치에 인디케이터와 안내 문구가 표시되어 위치를 확인할 수 있습니다.

2. 몰입 읽기 모드

  • 일정 시간 내에 읽지 않으면 문장이 점차 사라지는 몰입 독서 기능입니다.
  • 읽기 속도는 시작 전 미리 조절할 수 있으며, 사용자의 집중력에 맞게 설정 가능합니다.
  • “읽기 시작” 버튼을 누르면 선택된 속도에 따라 모드가 시작됩니다.
  • 마스코트 모구가 문장을 따라다니며 "먹어치우는" 연출을 통해 읽기에 몰입하도록 유도합니다.
  • “일시정지”, “되돌리기”, “재시작” 버튼으로 읽기 진행을 조절할 수 있습니다.

3. 대시보드

  • 정리한 문장과 몰입 읽기 기록을 날짜별로 시각적으로 확인할 수 있는 기능입니다.
  • 연도, 월을 기준으로 필터링하여 조회할 수 있습니다.
  • 기록은 필요에 따라 개별 삭제할 수 있습니다.


🛠️ 기술 스택


⚙️ 개발 과정

확장 프로그램 구조

MoguRead는 각 실행 환경의 제약과 권한을 고려하여, 구성 요소들이 명확히 역할을 나누고 메시지 기반으로 상호작용하는 구조로 설계되어 있습니다.
브라우저 탭의 변화를 감지하고, 사용자에게 직관적인 몰입형 인터페이스를 제공하는 과정은 다음과 같은 구성 요소들을 중심으로 이루어집니다.

확장 프로그램 구조 flow

이 다이어그램은 MoguRead 확장 프로그램의 핵심 구성 요소와 그들 간의 상호작용 흐름을 시각화한 것입니다.
각 구성 요소는 manifest.json을 통해 선언되고 연결되며, 브라우저 환경에서 유기적으로 동작합니다.

구성 요소 역할

1. Manifest(manifest.json)

모든 구성 요소를 선언하고 연결하는 확장 프로그램의 진입점입니다.
MoguRead의 동작 구조는 manifest 파일에 정의된 설정을 기반으로 유기적으로 작동합니다.

  • 구성요소 연결: Service Worker, Content Script, Side Panel, Options 페이지 등의 각 구성 요소를 유기적으로 연결합니다.
  • 리소스 정의: 어떤 스크립트와 HTML, 이미지 등을 사용할지 선언합니다.
  • 권한 설정: Content Script가 삽입될 웹사이트나 storage, sidePanel 등의 API 사용 권한을 명시합니다.
설정 항목 설명
background.service_worker 사이드 패널의 이벤트 처리나 페이지 간 이동을 감지하고, 각 영역의 제어 역할을 합니다.
content_scripts 사용자가 방문하는 웹페이지에 삽입되어, 마스코트 모구를 보여주고 텍스트를 정리하거나 하이라이팅 하는 등 DOM 조작을 수행합니다.
side_panel.default_path 사용자가 정리된 문장들을 확인하거나 몰입 읽기 모드를 시작할 수 있는 UI 패널의 진입점입니다.
web_accessible_resources Content Script에서 마스코트 모구 이미지 등의 리소스를 직접 접근하고 사용할 수 있도록 허용합니다.
host_permissions, permissions 사이트 접근(activeTab), 저장(storage), 사이드 패널 제어(sidePanel) 등 필요한 권한을 선언합니다.

2. Service Worker

Service Worker는 확장 프로그램의 백그라운드 중앙 제어 허브 역할을 수행합니다.
탭 상태를 감지하여 Content Script를 자동으로 주입하고, 사용자의 액션(예: 사이드 패널 열기)과 스크립트 실행 간의 연결을 관리합니다.

주요 기능 설명
Side Panel 설정 사용자가 확장 아이콘을 클릭했을 때 Side Panel이 자동으로 열리도록 설정합니다.
탭 활성화 감지 사용자가 탭을 전환할 때, 해당 탭에 Content Script가 삽입되었는지 확인하고, 없다면 삽입합니다.
탭 업데이트 감지 사용자가 페이지를 새로고침하거나 주소가 변경했을 때, DOM 로딩이 완료되면 Content Script를 자동으로 삽입합니다.
예외 처리 chrome:// 또는 chrome-extension://와 같은 내부 페이지에서는 Content Script를 삽입하지 않도록 필터링합니다.

3. Content Script

Content Script는 확장 프로그램에서 사용자가 현재 보고 있는 웹페이지 내부에 삽입되는 JavaScript 스크립트입니다.
실제 DOM을 제어하는 MoguRead의 핵심 실행 영역으로 마스코트 UI 삽입, 문장 하이라이팅, 제거, 애니메이션 등의 동작이 이 스크립트를 통해 수행됩니다.

주요 역할 설명
DOM 조작 사용자가 선택한 문장을 제거하거나, 몰입 읽기 모드에서 일정 시간이 지나면 단어를 투명하게 처리하는 등 페이지 내용을 직접 수정합니다.
마스코트 UI 삽입 마스코트 모구를 DOM에 삽입하고, 위치 제어 및 애니메이션 처리를 통해 시각적 피드백과 몰입감을 제공합니다.
메시지 수신 및 반응 Side Panel에서 전달된 메시지(예: “읽기 시작”, “정리 시작”)를 수신하여, 그에 맞는 동작을 수행합니다.

4. Side Panel

사용자와의 UI 상호작용을 담당하는 영역으로, 기능 실행의 출발점 역할을 합니다.
정리 모드, 몰입 읽기 모드 등 주요 기능을 실행하는 출발점 역할을 하며, 이때 발생한 명령은 Content Script에 메시지로 전달되어 웹페이지에서 실행됩니다.

주요 역할 설명
기능 실행의 출발점 “정리 시작”, “읽기 시작” 등 사용자의 액션을 트리거 합니다.
해당 메시지는 Content Script로 전송됩니다.
사용자 입력 수집 읽기 속도 설정, 정리 대상 문장 확인, 기록 선택 등 다양한 상호작용을 처리합니다.
뷰 전환 및 상태 반영 몰입 읽기 모드, 정리 모드의 전환이 가능하며, 현재 상태를 시각적으로 표시합니다.

몰입 읽기

몰입 읽기는 사용자가 집중하고 싶은 웹 페이지의 내용을 마스코트 모구가 따라가며 "먹어치우는" 연출을 통해 몰입감을 높여주는 기능입니다.
단어를 따라가는 시각적 흐름과 부드러운 스크롤 처리는 사용자의 집중을 방해하지 않고 자연스러운 흐름을 유도합니다.

작동 흐름

몰입 읽기 flow

핵심 흐름

흐름 설명
이미지 삽입 단어를 따라 움직이는 마스코트 모구 캐릭터 이미지를 DOM에 추가합니다.
문장 포맷팅 읽기 대상 단어는 CSS 클래스(.mogu-word)를 부여해 구분합니다.
애니메이션 제어 실제 페이지에서 DOM을 조작하고, 마스코트 모구 이미지 애니메이션을 수행합니다.
이때 단어의 길이, 줄바꿈 여부 등을 고려하여 속도와 움직임이 조절됩니다.

이미지 이동 처리 방식

마스코트 모구는 단어 하나하나를 좌에서 우로 이동하며 "따라 읽는” 방식으로 작동합니다.
위치 계산은 실제 웹페이지 글자의 DOM 좌표 정보를 기반으로 정밀하게 이루어집니다.

  • 이동 애니메이션
mogu.style.transition = `left ${animationDuration}ms ease`;
mogu.style.left = `${endX}px`;
  • 스크롤 보정 처리 모구가 따라가는 문장이 항상 화면 중앙에 위치하도록 자동 스크롤 처리합니다.
word.scrollIntoView({ behavior: "smooth", block: "center" });

세부 설계

읽기 속도 기준 (WPM 기반)

속도는 WPM(Words Per Minute), 즉 분당 읽는 단어 수 기준으로 설정되며,
사용자는 느림 / 보통 / 빠름 중에서 선택할 수 있습니다.

  • 속도 설정값
  • 느림(SLOW): 120 WPM → 약 500ms/단어
  • 보통(NORMAL): 200 WPM → 약 300ms/단어
  • 빠름(FAST): 300 WPM → 약 200ms/단어

참고 논문: 대한안과학회지 J Korean Ophthalmol Soc 2016;57(4):642-649 “한국어 읽기 속도 측정 애플리케이션의 유효성 및 정상인의 읽기 속도에 대한 사전 연구” 평균 읽기 속도: 202.3 ± 88.4 WPM (20~30대 성인 기준)

긴 단어 속도 보정

기본 속도 외에도, 단어 길이에 따라 읽기 시간을 추가로 보정합니다.
4글자 초과 시 글자 하나당 약 15ms를 추가하여 긴 단어는 더 천천히 읽히도록 설계했습니다.

이런 방식은 Spritz라는 속독 기술에서 먼저 활용되었습니다.
Spritz는 단어 길이에 따라 자동으로 속도를 조절해 몰입을 유지합니다.

“Words of 4-to-7 characters spritz through a display the fastest. Others have algorithmic slowing applied…” 4~7자 사이 단어가 가장 빠르게 읽히며, 그 외의 단어는 속도를 늦춥니다. — Spritz Inc.

시작 위치 보정

DOM 좌표를 그대로 적용하면 마스코트가 첫 글자 위에 겹쳐서 시작하게 됩니다.
이를 보정하기 위해 첫 글자의 시각적 너비를 측정하고, 해당 값을 기준 좌표에서 감산하여 왼쪽으로 보정합니다.
이로써 마스코트가 단어의 시작 지점에서 출발해, 차례로 먹어치우는 듯한 자연스러운 연출이 가능합니다.

const firstCharWidth = context.measureText(firstChar).width;

줄바꿈 감지 및 처리

단어의 세로 좌표(top) 값이 이전 단어와 달라지면, 줄바꿈이 발생한 것으로 간주합니다.
DOM 요소의 화면 내 위치와 크기를 반환하는 getBoundingClientRect()를 사용해 이 변화를 감지하고,
모구를 다음 줄의 시작 단어 위치로 이동시킨 후, 기존과 동일한 방식으로 수평 이동 애니메이션을 재개합니다.


웹 페이지 내 선택 문장 제거 기능 (정리 기능)

정리 기능은 사용자가 선택한 문장들을 페이지에서 제거함으로써, 핵심 내용에만 집중할 수 있도록 도와주는 기능입니다.
마스코트 모구가 선택된 문장을 "먹는" 애니메이션과 함께 제거하여 몰입감 있는 상호작용을 제공합니다.

작동 흐름

정리 기능 flow

핵심 흐름

흐름 설명
사용자 선택 감지 사용자가 웹페이지에서 드래그로 문장을 선택하면 자동으로 문장 정보가 추출됩니다.
정리 시작 버튼 클릭 사용자가 선택한 문장을 시각적으로 확인하고 정리 시작 버튼을 눌러 실행하는 출발점입니다.
문장 정리 실제 페이지에서 DOM을 조작하고, 마스코트 모구 이미지 애니메이션 및 문장 제거를 수행합니다.
메시지 전송 사이드 패널과 콘텐츠 스크립트 간 통신을 통해 메시지를 주고받는 채널 역할을 합니다.

제거하고 싶은 문장 선택 감지

사용자가 웹페이지 내에서 제거하고 싶은 문장을 마우스로 드래그해 선택하면, Content Script에서 해당 이벤트를 감지하여 다음과 같은 작업을 수행합니다.

  1. 드래그 선택 감지
  • mouseup 이벤트를 통해 사용자의 마우스 드래그 종료 시점을 감지합니다.
  • 선택된 텍스트가 없거나, 중복된 선택인 경우에는 무시됩니다.
  1. 선택된 문장 포장 및 식별 정보 생성
  • 선택된 문장은 고유하게 식별할 수 있도록 id가 부여된 span 태그로 감싸집니다.
  • 식별 정보가 함께 수집되며 이 과정을 통해 이후 정리 및 복원에 필요한 정밀한 DOM 위치 정보가 확보됩니다.
    • 선택된 실제 텍스트 (text)
    • 선택된 위치를 나타내는 CSS Selector (selector)
    • 시작/끝 offset (startOffset, endOffset)
    • 고유 식별자 (id)
    • 현재 페이지 URL
  1. 메시지 전송
  • 포장된 문장 데이터는 메시지를 통해 사이드 패널로 전송됩니다.
  • 사이드 패널은 해당 문장을 선택된 문장 UI에 표시하고, 사용자의 액션을 기다립니다.

"정리 시작" 버튼 클릭

사용자가 “정리 시작” 버튼을 누르면, 메시지를 통해 Content Script로 명령이 전송됩니다.
이때 전달되는 메시지에는 제거할 문장을 식별하는 고유 식별자(id) 목록이 포함됩니다.

이 구조는 사용자 인터페이스와 페이지 조작 로직을 분리하여 유지 보수성과 확장성을 확보합니다.

이미지 등장 및 제거 애니메이션 실행

Content Script는 제거 작업의 핵심 역할을 수행합니다.
정리 시작 메시지를 수신한 후, 다음과 같은 단계로 작업이 진행됩니다.

  1. 이미지 초기화 및 위치 설정
  • 기존에 삽입된 이미지가 있다면 제거하고 새로 배치하여 중복 삽입을 방지합니다.
  • 마스코트 모구 이미지는 제거 대상 문장으로 직접 이동하면서, "먹는" 동작을 시각적으로 표현합니다.
  1. 문장별 애니메이션 실행
  • 문장 위치 계산: data-word-id 속성으로 해당 문장을 식별하고, getBoundingClientRect()로 좌표를 계산합니다.
  • 마스코트 모구 이동 애니메이션: 좌측에서 우측으로 transition을 적용해 모구가 문장을 "먹는" 듯한 이동을 실행합니다.
  • 문장 제거 처리: 애니메이션 후, 해당 문장의 opacity를 0으로 만든 뒤, remove()로 DOM에서 제거합니다.

각 문장은 하나씩 천천히 순차적으로 제거되어 사용자가 시각적 효과를 명확히 인지할 수 있도록 설계되었습니다.

세부 설계

구현 방식

접근 방식 장점 단점
display: none 처리 DOM 유지 가능, 간단한 숨김 처리 가능 제거 효과가 시각적으로 약함
opacity 및 remove 조합 시각적 효과와 실제 제거를 모두 만족 구현 복잡도가 상대적으로 높음

MoguRead에서는 시각적 몰입감과 기능 안정성을 모두 확보하기 위해 opacity + remove 방식으로 설계되었습니다.

// 문장 요소의 투명도 조절
wordElement.style.transition = `opacity 600ms ease`;
wordElement.style.opacity = "0";

// 애니메이션 종료 후 제거
await delay(650);
wordElement.remove();

애니메이션으로 제거 과정을 시각적으로 전달한 뒤, 실제로 DOM에서 요소를 제거합니다.
이를 통해 시각적 몰입감과 UI 안정성을 동시에 확보할 수 있습니다.

뷰포트 밖 문장 처리

문장이 화면에 보이지 않는 위치에 있는 경우, 모구 이미지의 애니메이션 이동이 갑작스럽게 튀는 듯한 부자연스러운 시각 효과가 발생할 수 있습니다.
이를 방지하기 위해, 정리 대상 문장이 현재 시야 밖에 있을 경우 자동으로 해당 문장을 화면 중앙 근처로 스크롤하여 이동하도록 처리했습니다.

wordElement.scrollIntoView({
  behavior: "instant",  // 즉시 이동하여 깜빡임 최소화
  block: "center",      // 수직 중앙에 위치시켜 시각적 일관성 확보
});

이 처리는 모구의 이동 경로가 항상 화면 내에서 자연스럽게 유지되도록 보장하며, 사용자 입장에서 문장이 어떻게 제거되고 있는지를 명확히 인식할 수 있게 도와줍니다.

제거 완료 후의 상태 저장

문장의 제거가 모두 완료되면, Content Script는 마지막으로 정리 완료 메시지를 사이드 패널에 전송합니다.
이 메시지는 애니메이션과 문장 제거가 모두 끝났으며, 지금이 사용자 기록을 저장할 시점임을 의미합니다.

정리된 문장은 단순히 일시적으로 제거되는 것이 아니라,

  • 추후 같은 웹페이지에 재접속했을 때 복원 여부를 판단하거나,
  • 정리 위치를 시각적으로 다시 안내하거나,
  • 사용자 기록(히스토리)으로 남겨두기 위해 기록이 필요합니다.

이를 위해 다음과 같은 정보가 chrome.storage.local에 저장됩니다.

필드명 설명
text 실제 정리된 문장의 텍스트
id 문장마다 부여된 고유 식별자 (data-word-id 기반)
selector 문장이 속해 있던 상위 DOM 요소의 고유 CSS 선택자
startOffset / endOffset 해당 문장의 위치를 DOM 내에서 재현할 수 있는 상대 위치
url 해당 문장이 존재했던 페이지의 URL
savedAt 정리 작업이 수행된 시각 (timestamp)

이 저장 구조는 추후 문장 복원이나 히스토리 기능에 활용될 수 있어, 사용자 경험의 일관성을 높이는 데 기여합니다.


제거된 문장 위치 시각화

사용자는 이전에 제거했던 문장이 페이지 내에서 어디에 있었는지 궁금할 수 있습니다. MoguRead는 사이드 패널의 정리 기록을 클릭하면, 해당 문장이 원래 있었던 위치를 시각적으로 보여주는 기능을 제공합니다.

단순한 정보 조회를 넘어, 실제 위치에 인디케이터(표시자)를 삽입하고 해당 지점으로 부드럽게 스크롤 하여 정확한 위치를 안내합니다.

작동 흐름

제거 위치 표시 flow

핵심 흐름

흐름 설명
위치 복원 요청 사용자가 목록에서 문장을 클릭하면, 해당 문장의 원래 위치를 찾기 위한 요청을 보냅니다.
위치 계산 저장된 selector, 오프셋 정보를 기반으로 실제 DOM 내 위치를 계산하고 보정합니다.
인디케이터 삽입 및 스크롤 계산된 위치에 인디케이터를 표시하고, 해당 위치로 스크롤 합니다.
인디케이터 제거 일정 시간 후 인디케이터를 숨겨 UI를 깔끔하게 유지합니다.

위치 계산 방식

문장이 이미 DOM에서 삭제되었기 때문에, 단순한 텍스트 탐색으로는 정확한 위치를 찾을 수 없습니다. 이를 보완하기 위해 chrome storage에 저장했던 정보(selector, startOffset, text, savedAt)를 기반으로 오프셋 보정 알고리즘을 수행하며, 동일 요소 내 복수 문장 삭제까지 고려합니다.

  1. 대상 요소 탐색
  • 저장된 selector 값을 활용해, 삭제된 문장이 속해 있던 상위 DOM 요소를 찾습니다.
  1. 같은 요소 내 정리 기록
  • 동일한 selector를 갖는 정리 기록을 수집합니다.
  • 하나의 요소 내에 여러 문장이 삭제된 경우에도 정확한 상대 위치를 계산할 수 있도록 준비합니다.
  1. 삭제 여부 판별 (복원 vs 삭제)
  • 요소의 현재 텍스트를 확인하여, 문장이 남아 있다면 복원 상태, 존재하지 않으면 삭제 상태로 분류합니다.
  1. 삭제된 경우: 오프셋 보정
  • 앞서 삭제된 문장들의 길이를 누적하여 오프셋을 보정합니다.
const currentPosition = Math.max(0, targetItem.startOffset - offsetAdjustment);
  • offsetAdjustment는 동일 요소 내에서 앞선 삭제 항목들의 길이를 누적한 값입니다.
  1. 최종 위치 계산
  • 보정된 오프셋 기준으로 텍스트 노드를 순차적으로 탐색하여 정확한 노드와 위치를 계산합니다.
const walker = document.createTreeWalker(targetElement, NodeFilter.SHOW_TEXT);
  • 오프셋 지점에 도달하면, 그 위치에 인디케이터를 삽입합니다.

chrome.storage.local 사용 이유

MoguRead는 도메인 제약 없이, 브라우저 종료 후에도 데이터가 유지돼야 하기 때문에 Chrome 확장 전용 비동기 저장소인 chrome.storage.local을 선택했습니다.

상세 선택 이유

  1. 페이지와 무관하게 안전하게 데이터 보존 가능
  • localStorage와 달리 도메인 종속이 없고, 확장 프로그램 자체의 스코프에서 데이터가 저장됩니다.
  • 즉, 사용자가 어떤 웹사이트에서 선택을 했든, 전혀 상관없이 데이터를 안전하게 보존할 수 있습니다.
  • 이는 여러 도메인에서 일관된 방식으로 문장 기록을 관리해야 하는 MoguRead에 적합합니다.
  1. 브라우저 종료 후에도 데이터 유지
  • chrome.storage.local에 저장된 데이터는 브라우저를 종료하거나 재부팅해도 유지됩니다.
  • MoguRead는 사용자가 이전에 정리한 문장을 다시 기억하고 재활용하므로, 세션이 끝나도 지속적으로 접근 가능한 저장소가 필요합니다.
  1. 용량 여유가 충분함
  • chrome.storage.local은 기본적으로 5MB 용량 제한을 제공하며, 대부분의 정리 데이터에는 충분합니다.
  • 문장 단위의 텍스트와 선택자/offset 정보는 용량이 작기 때문에, 수백~수천 개의 문장도 무리 없이 저장할 수 있습니다.
  1. 비동기 API 제공으로 확장성과 안정성 확보
  • chrome.storage.local은 비동기 방식으로 작동하여, 성능 저하 없이 데이터 저장/조회가 가능합니다.
  • 특히 정리 기능이 애니메이션 등 비동기 흐름과 함께 작동하기 때문에, UI가 멈추지 않고 부드럽게 동작하는 데 유리합니다.
  1. 자동 백업/동기화 고려 시 유연성 확보
  • 향후 chrome.storage.sync로의 확장도 고려 가능하며,
  • local에 저장된 구조는 Firebase 등 외부 저장소와 연동할 때도 형식 호환성과 분리 설계에 유리합니다.

다른 저장 방식과의 비교

저장 방식 장점 단점
localStorage 사용하기 간단, 동기 방식 도메인 종속, 확장 프로그램 외부에 노출됨
sessionStorage 세션 기반 임시 저장 브라우저 닫으면 사라짐
IndexedDB 대용량, 정교한 구조화 가능 구현 복잡도 높음, 오버 스펙
chrome.storage.local 적절한 성능, 확장 프로그램 전용 스코프, 비동기 단일 사용자 기준, 오직 확장 전용

MoguRead는

  • 사이트와 무관하게 작동하고,
  • 브라우저가 꺼져도 기록을 유지해야 하며,
  • UI가 끊기지 않도록 부드럽게 동작해야 합니다.

이 조건을 충족하는 저장소인 chrome.storage.local를 데이터 저장소로 채택했습니다.


💭 프로젝트 소감

이번 프로젝트는 단순히 기능을 구현하는 것을 넘어서, 사용자 경험(UX)을 중심에 두고 설계하고 개선하는 과정에 집중한 경험이었습니다. 정리된 문장의 삭제 위치를 시각적으로 다시 안내하는 기능, 문장 길이에 따른 읽기 속도 보정, 시작 좌표의 위치 보정, 줄바꿈 감지 후 부드러운 스크롤 처리 등 세밀한 동작 하나하나가 사용자에게 어떤 감각으로 전달될지를 끊임없이 고민하며 구현했습니다.

처음엔 단순한 아이디어였지만, 실제로 구현해 보니 시각적 흐름, 위치 계산, 애니메이션 타이밍 등 고려해야 할 것이 많았고, 완성도를 높이기 위해 많은 시행착오와 고민을 반복했던 프로젝트였습니다.

이번 작업을 통해 기능 구현을 넘어서 사용자 관점에서 사고하고, 기술적 세부사항까지 주도적으로 설계하는 개발 경험을 쌓을 수 있었습니다. 앞으로도 한 걸음씩 실력을 확장해 나가며, 점점 더 의미 있는 제품을 만들 수 있는 개발자로 성장하고 싶습니다.


About

웹 콘텐츠를 깔끔하게 정리하고, 마스코트 모구와 함께 몰입해 읽는 크롬 확장 도구

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published