{"_id":"@codewithahsan/quill-ink-core","_rev":"2-8a440f5fbc62fe7d524c3660cf94ccf8","name":"@codewithahsan/quill-ink-core","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@codewithahsan/quill-ink-core","version":"0.1.0","keywords":["handwriting","canvas","animation","streaming","llm","ink","angular","quill"],"license":"MIT","_id":"@codewithahsan/quill-ink-core@0.1.0","maintainers":[{"name":"ahsanayaz","email":"ahsan.ubitian@gmail.com"}],"homepage":"https://github.com/codewithahsan/ngx-quill-ink#readme","bugs":{"url":"https://github.com/codewithahsan/ngx-quill-ink/issues"},"dist":{"shasum":"ed055374b7dc5a95a8b0aebf249fb7d07fe06ddc","tarball":"https://registry.npmjs.org/@codewithahsan/quill-ink-core/-/quill-ink-core-0.1.0.tgz","fileCount":37,"integrity":"sha512-pJhySZGsOUg2Yone6EHhl3Zfk6k7MDWFrqmH7ehTAv+xsVuFPtnDQCbYWsR0bbamoqi0mETOwF5qkAPGoIYxtg==","signatures":[{"sig":"MEUCIHNcHNglRO/QFIa0zpbNCiLtJ32VtHVyQjhdCKqVHfdxAiEA/KLAuCdGKf0d6geKrxgmBCeU/V7pJTvLZhWaJc9fgYk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":194892},"main":"./index.cjs.js","types":"./index.d.ts","module":"./index.esm.js","gitHead":"77f67de900088b46a3caf29a37f0a2fc812d1bda","_npmUser":{"name":"ahsanayaz","email":"ahsan.ubitian@gmail.com"},"repository":{"url":"git+https://github.com/codewithahsan/ngx-quill-ink.git","type":"git"},"_npmVersion":"11.13.0","description":"Framework-agnostic canvas engine that renders streaming text as animated handwriting.","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/quill-ink-core_0.1.0_1784929517022_0.4388440594002305","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@codewithahsan/quill-ink-core","version":"0.1.1","main":"./index.cjs.js","module":"./index.esm.js","dependencies":{},"license":"MIT","sideEffects":false,"description":"Framework-agnostic canvas engine that renders streaming text as animated handwriting.","repository":{"type":"git","url":"git+https://github.com/AhsanAyaz/ngx-quill-ink.git"},"bugs":{"url":"https://github.com/AhsanAyaz/ngx-quill-ink/issues"},"homepage":"https://github.com/AhsanAyaz/ngx-quill-ink#readme","publishConfig":{"access":"public"},"keywords":["handwriting","canvas","animation","streaming","llm","ink","angular","quill"],"types":"./index.d.ts","gitHead":"aafaadc022234c77654812c4f411d942607d8ea6","_id":"@codewithahsan/quill-ink-core@0.1.1","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-sA2rSWUXQI+3e2I6MMyhTdAYjEOLd+AZqKCnXmpqkZEC2KyXHssmybjzenQL4kJcJ980gwCpVKATyZQsIWm5jA==","shasum":"591a9929ed33b68d7948dd05cc26199c050e6b90","tarball":"https://registry.npmjs.org/@codewithahsan/quill-ink-core/-/quill-ink-core-0.1.1.tgz","fileCount":37,"unpackedSize":194880,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID/rFGUKwrX3UsWkATsitom00xyVgSqGe018fEOJLuY8AiEAtSzAxudM94ZLAOAx45UEKiBTmeUS5G/vd2KGa15pH5Y="}]},"_npmUser":{"name":"ahsanayaz","email":"ahsan.ubitian@gmail.com"},"directories":{},"maintainers":[{"name":"ahsanayaz","email":"ahsan.ubitian@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/quill-ink-core_0.1.1_1784930638984_0.18671109902930327"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-24T21:45:16.883Z","modified":"2026-07-24T22:03:59.322Z","0.1.0":"2026-07-24T21:45:17.177Z","0.1.1":"2026-07-24T22:03:59.138Z"},"bugs":{"url":"https://github.com/AhsanAyaz/ngx-quill-ink/issues"},"license":"MIT","homepage":"https://github.com/AhsanAyaz/ngx-quill-ink#readme","keywords":["handwriting","canvas","animation","streaming","llm","ink","angular","quill"],"repository":{"type":"git","url":"git+https://github.com/AhsanAyaz/ngx-quill-ink.git"},"description":"Framework-agnostic canvas engine that renders streaming text as animated handwriting.","maintainers":[{"name":"ahsanayaz","email":"ahsan.ubitian@gmail.com"}],"readme":"# @codewithahsan/quill-ink-core\n\nFramework-agnostic TypeScript engine that renders **streaming text as animated handwriting** — ink flowing from an invisible quill onto paper — and captures **user pen strokes** (with a \"the page drinks your ink\" dissolve) for consumption by vision LLMs.\n\nZero dependencies. No framework imports. Canvas 2D only.\n\n## Install\n\n```bash\nnpm i @codewithahsan/quill-ink-core @codewithahsan/quill-ink-fonts\n```\n\n## Write path — machine → page\n\n```ts\nimport { InkSurface, registerFontPack } from '@codewithahsan/quill-ink-core';\nimport { caveat } from '@codewithahsan/quill-ink-fonts/caveat';\n\nregisterFontPack(caveat);\n\nconst surface = new InkSurface({\n  canvas: document.querySelector('canvas')!,\n  font: 'caveat',\n  fontSize: 28,\n  inkColor: '#1a2b4a',   // iron gall blue-black\n  penSpeed: 900,         // px of path per second\n  paper: 'ruled',\n});\n\n// strings…\nconst handle = surface.write('Dear reader, this page writes itself…');\nawait handle.done;\n\n// …or token streams (any AsyncIterable<string>)\nsurface.write(llmTokenStream);\n```\n\nThe pen writes stroke by stroke with pressure-modulated width, ink dots at\nstroke starts, tapered ends, per-glyph lightness jitter, baseline wobble and\npunctuation pauses (220ms after `.` `!` `?`, 120ms after `,`). When the token\nqueue grows the pen hurries (up to 2.5×); when it starves the pen simply\nrests — no spinner, ever.\n\n## Capture path — human → machine\n\n```ts\nsurface.enableCapture({ commitAfterMs: 2800 });\nsurface.onCapture(({ png, strokes, bounds }) => {\n  // png: Blob (white bg baked, 2× scale) — send to your vision model\n  // strokes: [x, y, tMs][][] raw polylines\n});\n```\n\nAfter the idle timeout (or an explicit `surface.commitCapture()`), the page\n*drinks the ink* — a directional dissolve absorbs the strokes — and the\ncommitted snapshot is emitted.\n\n## How it works\n\nHandwriting fonts are outline fonts; a pen needs **centerline strokes**. The\nengine ships precomputed skeleton packs (see `@codewithahsan/quill-ink-fonts`)\ngenerated via: rasterize → binarize → Zhang-Suen thinning → 8-neighbor graph\ntracing (min-turning-angle through junctions) → RDP simplification →\nCatmull-Rom smoothing. Glyphs not covered by a pack fall back to the same\npipeline at runtime, in a Web Worker spawned from an inline Blob URL — no\nbundler configuration needed. Results are cached in memory and IndexedDB.\n\nStrict CSP without `worker-src blob:`? The engine transparently falls back to\nsynchronous main-thread thinning (pack-covered glyphs never thin at runtime\nanyway).\n\n## SSR\n\nConstructing `InkSurface` outside a browser yields an inert no-op surface;\nall methods are safe to call.\n\n## Out of scope for v1\n\nRTL and CJK scripts, ligature-aware ductus, stylus pressure\n(`PointerEvent.pressure` lands in v2), React/Vue wrappers (the core is ready\nfor them — contributions welcome).\n\n## License\n\nMIT\n","readmeFilename":"README.md"}