cometsight
v1.0.0
Published
A TypeScript scroll-tracking library that detects when elements are in user's focus zone with time-duration tracking
Downloads
100
Maintainers
Readme
Version 1.0.0 - Official Release 🚀
https://www.npmjs.com/package/cometsight
Table of Contents
About
CometSight is a lightweight TypeScript library that detects when elements are in the user's focus zone (not just visible on screen), with time-duration tracking capabilities. Perfect for manhwa/webtoon readers, smart analytics, and scrollytelling experiences. Most scroll-tracking libraries only check if an element is visible anywhere on screen. CometSight goes further by detecting when elements are in the user's focus zone - the area they're actually looking at.
Features
- Focus Zone Detection: Semantic thresholds like
'center','top','bottom'without complex calculations - Time-on-Element Tracking: Only trigger callbacks if elements stay in focus for a minimum duration
- Debounce Support: Wait for scroll to settle before triggering
- Zero Dependencies: Pure TypeScript with native IntersectionObserver API
- Chainable API: Fluent, intuitive interface
- Tab Visibility Aware: Automatically pauses tracking when user switches tabs
Installation
npm install cometsight
# or
yarn add cometsight
# or
pnpm add cometsight
# or
bun add cometsightQuick Start
Usage Examples
import { watchReadingProgress } from 'cometsight';
// Basic usage
const reader = watchReadingProgress('center', '.manhwa-panel', {
debounce: 500
});
reader.onSectionEnter((panel) => {
const panelId = panel.getAttribute('data-id');
console.log(`Reading panel: ${panelId}`);
});
// Chainable API
watchReadingProgress('center', '.story-paragraph', {
minTime: 3000
})
.onSectionEnter((el) => {
console.log('Entered:', el.id);
})
.onSectionLeave((el) => {
console.log('Left:', el.id);
});Interface include
import { watchReadingProgress, CometSightOptions } from 'cometsight';
interface PanelElement extends Element {
dataset: {
id: string;
};
}
const reader = watchReadingProgress('center', '.manhwa-panel', {
minTime: 1000,
debounce: 500
} as CometSightOptions);
reader.onSectionEnter((panel: PanelElement) => {
console.log('Panel ID:', panel.dataset.id);
});API Reference
Methods
| Method/Function | Description | Parameters | Returns |
|----------------|-------------|--------------|----------|
| watchReadingProgress(threshold, selector, options?) | Creates a new CometSight instance to watch elements matching the selector | - threshold (string) - Focus zone: 'top', 'center', 'bottom', or custom range (e.g., '0.3-0.6')- selector (string) - CSS selector for elements to watch- options (object, optional): - minTime (number) - Minimum time in focus zone before triggering (ms) - debounce (number) - Wait time after scroll settles before triggering (ms) - root (Element | null) - Root element for intersection checking | CometSight instance |
| .onSectionEnter(callback) | Register callback for when an element enters the focus zone | - callback (function) - Function called with element as argument | CometSight instance (chainable) |
| .onSectionLeave(callback) | Register callback for when an element leaves the focus zone | - callback (function) - Function called with element as argument | CometSight instance (chainable) |
| .destroy() | Cleanup and stop watching elements | None | void |
Focus Zones
| Zone | Description | Range |
|-------|-------------|--------|
| top | Top 30% of viewport | 0.0-0.3 |
| center | Center 30% of viewport (default) | 0.3-0.6 |
| bottom | Bottom 40% of viewport | 0.6-1.0 |
| 'min-max' | Custom range | Any valid range (e.g., '0.4-0.8') |
Use Cases
1. Manhwa/Webtoon Auto-Bookmark
Track exactly which panel the user is reading:
import { watchReadingProgress } from 'cometsight';
const reader = watchReadingProgress('center', '.manhwa-panel', {
debounce: 500
});
reader.onSectionEnter((panel) => {
const panelId = panel.getAttribute('data-id');
localStorage.setItem('lastPanel', panelId);
});2. Smart Analytics
Distinguish between skimmers and deep readers:
import { watchReadingProgress } from 'cometsight';
watchReadingProgress('center', '#pricing-plans', {
minTime: 3000
}).onSectionEnter(() => {
analytics.track('high_intent_user', { focus: 'pricing_table' });
});3. Scrollytelling
Trigger animations exactly when eyes hit specific paragraphs:
import { watchReadingProgress } from 'cometsight';
const story = watchReadingProgress('center', '.story-paragraph');
story.onSectionEnter((el) => {
if (el.id === 'jump-scare-text') {
audio.play('scream.mp3');
document.body.style.backgroundColor = 'red';
}
});
story.onSectionLeave((el) => {
if (el.id === 'jump-scare-text') {
document.body.style.backgroundColor = 'white';
}
});License
MIT License - Copyright (c) 2026 https://github.com/dotjumpdot
Support
- GitHub Issues: https://github.com/dotjumpdot/cometsight/issues
- Documentation: https://github.com/dotjumpdot/cometsight
- npm Package: https://www.npmjs.com/package/cometsight
Made with ❤️ by DotJumpDot
