Skip to content
here-is-leoPublic

Latest commit

 

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


Negar

A canvas with nothing in the way. Open it and draw. Negar is a minimal, RTL-first sketching surface built on the HTML5 Canvas — with a handwriting engine that responds to speed, precise shape tools, text and highlighter, and a full editing history. No frameworks. No build step. No dependencies.

Features  ·  Tools  ·  Stack  ·  Architecture  ·  Quick start  ·  Shortcuts  ·  Meet Leo


Draw freehand, place shapes, add text, highlight — all in one canvas.


01 / Everything a sketch needs, and nothing it doesn't

↗ A pen that behaves like a pen

A velocity-driven freehand engine adjusts stroke width to hand speed, smooths jitter, and tapers stroke ends — so writing and sketching feel natural, not mechanical.

◉ Shapes that stay clean

Rectangle, ellipse, line, arrow — with dashed and dotted styles, custom stroke widths, and Shift to constrain proportions. Fillable, layered, and reorderable.

◇ Text and highlighting

Place RTL-aware text anywhere on the canvas. Highlight with a multiply-blended marker that keeps the content beneath readable. Double-click any text to edit it in place.

⌘ An editor beneath the surface

Full undo and redo. Multi-select with a marquee. Copy, paste, duplicate, lock, and reorder. Drag to move, grab a corner to resize, nudge with the arrow keys.

◐ A viewport you control

Pan with Space or the middle mouse. Zoom with Ctrl + scroll, or zoom to fit your content. Toggle the dot grid. Reset to 100% at any time.

☾ Persistent and portable

Everything autosaves to local storage and restores on reload. Export the full canvas as a PNG at your display's pixel density. Light and dark themes, one click apart.

Highlights at a glance

Velocity-based pen · 3 pen styles · Highlighter · Shapes + arrows · RTL text · Marquee select · Resize handles · Undo / redo · Copy / paste · Lock & layer order · Autosave · PNG export · Dark mode · Keyboard-first

02 / The toolbar, in detail

Tool What it does Key
Select Click to select, drag to move, marquee to multi-select, handles to resize V
Hand Pan the canvas freely — also middle mouse, or hold Space H
Pen Freehand with speed-reactive width and smoothed strokes P
Highlighter Wide, translucent, multiply-blended marks M
Eraser Removes whole strokes and shapes on contact E
Text Editable RTL text anywhere on the canvas T
Line Straight line, constrained with Shift L
Arrow Line with an arrowhead that scales with stroke width A
Rectangle Rounded rectangle, optionally filled R
Ellipse Perfect ellipse, optionally filled O
Diamond Rhombus aligned to the drag box D
Triangle Isosceles triangle aligned to the drag box G
Star Five-point star, aspect-aware S

Every stroke and shape carries its own color, width, opacity, dash style, and fill — chosen from the style panel before or after drawing.

03 / Built on a focused stack

Layer Foundation Notes
Runtime Vanilla JavaScript (ES2020+) No bundler, no framework, no runtime dependency
Rendering HTML5 Canvas 2D Separate grid and draw layers, DPR-aware
Input Pointer Events + coalesced events Mouse, trackpad, pen, and touch through one path
Persistence localStorage Element graph serialized as JSON, restored on load
Typography Vazirmatn RTL-first interface and canvas text
Styling Hand-written CSS with custom properties Theme tokens, color-mix(), backdrop blur

04 / Clear responsibilities at every layer

flowchart LR
    P[Pointer input] --> I[Interaction layer]
    K[Keyboard] --> I
    I --> S[(State)]
    S --> R[Renderer]
    R --> G[Grid canvas]
    R --> D[Draw canvas]
    S --> H[History stack]
    S --> L[localStorage]
    H --> R
    L --> S
    classDef input fill:#E5F4D8,stroke:#548369,color:#17382B;
    classDef core fill:#E5F1EC,stroke:#548369,color:#17382B;
    class P,K input;
    class I,S,R,H,L core;
Loading

Interaction translates raw pointer and keyboard events into intent: drawing, selecting, panning, resizing, erasing. State holds the element graph, the viewport, the selection, and the history index. Renderer redraws the scene from state on every change, so what you see is always a pure function of what is stored. History snapshots the element graph, which makes undo and redo exact rather than approximate.

Nothing couples rendering to input. Nothing couples persistence to the interface. Adding a new tool means teaching the interaction layer one new shape.

05 / From source to running locally

Prerequisites: a modern browser. That is all. There is no build step.

Get the source

git clone https://github.com/here-is-leo/negar.git
cd negar

Open it

# Option 1 — open the file directly
open index.html          # macOS
xdg-open index.html      # Linux
start index.html         # Windows

# Option 2 — serve it locally (recommended for testing on other devices)
python3 -m http.server 8080
# then visit http://localhost:8080

Host it anywhere

Negar is fully static, so any host works: GitHub Pages, Netlify, Cloudflare Pages, or a folder on your own server. Push the files, point the host at index.html, done.

06 / Keyboard, without lifting your hands

Tools
Action Keys
Select / Hand / Pen / Highlighter / Eraser / Text V H P M E T
Line / Arrow / Rectangle / Ellipse L A R O
Diamond / Triangle / Star D G S
Editing
Action Keys
Undo / Redo Ctrl + Z / Ctrl + Shift + Z
Copy / Cut / Paste Ctrl + C / X / V
Duplicate Ctrl + D
Select all / Delete Ctrl + A / Delete
Nudge selection ↑ ↓ ← → — hold Shift for ×10
Bring forward / Send backward Ctrl + ] / Ctrl + [
Navigation & view
Action Keys
Pan canvas Hold Space and drag, or middle mouse
Zoom Ctrl + scroll
Zoom in / out Ctrl + + / Ctrl + -
Reset zoom to 100% Ctrl + 0
Toggle help ?
Cancel current action Esc
Smart clicks
Gesture Result
Right-click on canvas Full context menu
Double-click on text Edit in place
Alt + click on an element Instant duplicate and drag
Ctrl + click on an element Add to current selection
Drag marquee right Intersection select
Drag marquee left Enclosed select

07 / The developer behind the project

Ilia Farahani (Leo) — Senior Developer — @here-is-leo

Ilia Farahani (Leo) · ایلیا فاراهانی (لئو)
Senior Developer · برنامه‌نویس ارشد پروژه

GitHub / @here-is-leo ↗



نگار

بومی که هیچ‌چیز سر راهت نیست. بازش کن و بکش. نگار یک سطح طراحی مینیمال و راست‌به‌چپ روی Canvas مرورگر است؛ با موتور دست‌نویسی که به سرعت دست واکنش می‌دهد، ابزارهای دقیق اشکال، متن و هایلایت، و یک تاریخچهٔ کامل ویرایش. بدون فریم‌ورک، بدون مرحلهٔ بیلد، بدون هیچ وابستگی.

قابلیت‌ها · ابزارها · فناوری‌ها · معماری · راه‌اندازی · میان‌برها · برنامه‌نویس


کشیدن دست‌نویس، گذاشتن اشکال، افزودن متن و هایلایت — همه روی یک بوم.


۰۱ / هر آنچه یک اسکچ لازم دارد، و هیچ‌چیز اضافه

↗ قلمی که مثل قلم رفتار می‌کند

موتور دست‌نویسی حساس به سرعت، ضخامت خط را با تندی حرکت دست تنظیم می‌کند، لرزش را نرم می‌کند و انتهای خط را باریک می‌کند — تا نوشتن و کشیدن طبیعی باشد، نه مکانیکی.

◉ اشکالی که تمیز می‌مانند

مستطیل، بیضی، خط و فلش — با سبک‌های خط‌چین و نقطه‌چین، ضخامت دلخواه و Shift برای حفظ نسبت‌ها. قابل پر کردن، لایه‌بندی و تغییر ترتیب.

◇ متن و هایلایت

متن را هر جای بوم بگذار — با پشتیبانی کامل از راست‌به‌چپ. با ماژیکِ multiply هایلایت کن تا محتوای زیرش خوانا بماند. با دابل‌کلیک روی هر متن، همان‌جا ویرایشش کن.

⌘ ویرایشگری زیر پوسته

واگرد و ازنوی کامل. انتخاب چندگانه با کادر. کپی، چسباندن، تکثیر، قفل و تغییر ترتیب. جابجایی با کشیدن، تغییر اندازه با گوشه‌ها، جابجایی دقیق با کلیدهای جهت.

◐ نمایی که در کنترل توست

با Space یا دکمهٔ وسط ماوس بوم را جابجا کن. با Ctrl + اسکرول زوم کن، یا به اندازهٔ محتوا زوم کن. شبکهٔ نقطه‌ای را خاموش و روشن کن و هر وقت خواستی به ۱۰۰٪ برگرد.

☾ ماندگار و قابل حمل

همه‌چیز خودکار در حافظهٔ محلی ذخیره و در بارگذاری بعدی بازیابی می‌شود. کل بوم را با تراکم پیکسلی نمایشگرت به‌صورت PNG خروجی بگیر. تم روشن و تاریک، یک کلیک فاصله دارند.

نگاه یک‌خطی: قلم حساس به سرعت · سه سبک قلم · هایلایت · اشکال و فلش · متن راست‌به‌چپ · انتخاب کادری · دستگیره‌های تغییر اندازه · واگرد و ازنو · کپی و چسباندن · قفل و ترتیب لایه · ذخیرهٔ خودکار · خروجی PNG · حالت تاریک · کاملاً مبتنی بر کیبورد

۰۲ / نوار ابزار، با جزئیات

ابزارکارکردکلید
انتخابکلیک برای انتخاب، کشیدن برای جابجایی، کادر برای انتخاب چندگانه، گوشه‌ها برای تغییر اندازهV
جابجاییجابجایی آزاد بوم — با دکمهٔ وسط ماوس یا نگه‌داشتن Space هم می‌شودH
قلمدست‌نویس با ضخامت واکنشی به سرعت و خطوط نرم‌شدهP
هایلایتعلامت‌گذاری پهن، نیمه‌شفاف و با ترکیب multiplyM
پاک‌کنحذف کامل خط‌ها و اشکال با برخوردE
متنمتن قابل ویرایش با پشتیبانی راست‌به‌چپ، هر جای بومT
خطخط مستقیم؛ با Shift در جهت‌های محدودL
فلشخط با سرپیکانی که با ضخامت مقیاس می‌گیردA
مستطیلمستطیل گوشه‌گرد، با امکان پر کردنR
بیضیبیضی دقیق، با امکان پر کردنO
لوزیلوزی هم‌راستا با کادر کشیدنD
مثلثمثلث متساوی‌الساقین، هم‌راستا با کادرG
ستارهستارهٔ پنج‌پر، سازگار با نسبت ابعادS

هر خط و شکل، رنگ، ضخامت، شفافیت، سبک خط و رنگ پرِ خودش را دارد — که پیش یا پس از کشیدن از پنل سبک انتخاب می‌شود.

۰۳ / فناوری‌ها

لایهفناوریتوضیح
اجراJavaScript خالص (ES2020+)بدون باندلر، بدون فریم‌ورک، بدون وابستگی زمان اجرا
رندرCanvas 2D در HTML5دو لایهٔ جدا برای شبکه و رسم، هماهنگ با DPR
ورودیPointer Events و coalesced eventsماوس، ترک‌پد، قلم و لمس از یک مسیر واحد
ذخیره‌سازیlocalStorageگراف عناصر به‌صورت JSON، بازیابی در بارگذاری
تایپوگرافیVazirmatnرابط و متن بوم، راست‌به‌چپ از پایه
استایلCSS دست‌نویس با متغیرهای سراسریتوکن‌های تم، color-mix() و backdrop blur

۰۴ / مسئولیت‌های روشن در هر لایه

flowchart LR
    P[Pointer input] --> I[Interaction layer]
    K[Keyboard] --> I
    I --> S[(State)]
    S --> R[Renderer]
    R --> G[Grid canvas]
    R --> D[Draw canvas]
    S --> H[History stack]
    S --> L[localStorage]
    H --> R
    L --> S
    classDef input fill:#E5F4D8,stroke:#548369,color:#17382B;
    classDef core fill:#E5F1EC,stroke:#548369,color:#17382B;
    class P,K input;
    class I,S,R,H,L core;
Loading

لایهٔ تعامل رویدادهای خام اشاره‌گر و کیبورد را به قصد تبدیل می‌کند: کشیدن، انتخاب، جابجایی، تغییر اندازه، پاک کردن. State گراف عناصر، نما، انتخاب و اندیس تاریخچه را نگه می‌دارد. رندرر در هر تغییر، صحنه را از روی state بازمی‌سازد؛ یعنی آنچه می‌بینی همیشه تابعی خالص از آنچه ذخیره شده است. تاریخچه از گراف عناصر عکس می‌گیرد، پس واگرد و ازنو دقیق‌اند، نه تقریبی.

هیچ‌چیز رندر را به ورودی گره نزده. هیچ‌چیز ذخیره‌سازی را به رابط کاربری وابسته نکرده. افزودن یک ابزار تازه، یعنی آموزش یک شکل جدید به لایهٔ تعامل — و بس.

۰۵ / از سورس تا اجرا روی سیستم خودت

پیش‌نیاز: فقط یک مرورگر مدرن. مرحلهٔ بیلدی وجود ندارد.

دریافت سورس

git clone https://github.com/here-is-leo/negar.git
cd negar

اجرا

# گزینهٔ ۱ — مستقیم بازش کن
open index.html          # macOS
xdg-open index.html      # Linux
start index.html         # Windows

# گزینهٔ ۲ — سرو محلی (برای تست روی دستگاه‌های دیگر)
python3 -m http.server 8080
# سپس http://localhost:8080 را باز کن

میزبانی، هر جایی که بخواهی

چون نگار کاملاً استاتیک است، هر هاستی جواب می‌دهد: GitHub Pages، Netlify، Cloudflare Pages، یا یک پوشه روی سرور خودت. فایل‌ها را آپلود کن، هاست را به index.html اشاره بده، تمام.

۰۶ / کیبورد، بدون برداشتن دست‌ها

ابزارها
کار کلیدها
انتخاب / جابجایی / قلم / هایلایت / پاک‌کن / متن V H P M E T
خط / فلش / مستطیل / بیضی L A R O
لوزی / مثلث / ستاره D G S
ویرایش
کار کلیدها
واگرد / ازنو Ctrl + Z / Ctrl + Shift + Z
کپی / برش / چسباندن Ctrl + C / X / V
تکثیر Ctrl + D
انتخاب همه / حذف Ctrl + A / Delete
جابجایی انتخاب ↑ ↓ ← → — با Shift ده برابر
آوردن به جلو / فرستادن به عقب Ctrl + ] / Ctrl + [
پیمایش و نما
کار کلیدها
جابجایی بوم نگه‌داشتن Space و کشیدن، یا دکمهٔ وسط ماوس
زوم Ctrl + اسکرول
بزرگ‌نمایی / کوچک‌نمایی Ctrl + + / Ctrl + -
بازگشت به ۱۰۰٪ Ctrl + 0
نمایش راهنما ?
لغو کار جاری Esc
کلیک‌های هوشمند
حرکت نتیجه
راست‌کلیک روی بوم منوی گزینه‌های کامل
دابل‌کلیک روی متن ویرایش همان‌جا
Alt + کلیک روی یک عنصر تکثیر فوری و کشیدن
Ctrl + کلیک روی یک عنصر افزودن به انتخاب فعلی
کشیدن کادر به راست انتخاب بر اساس اشتراک
کشیدن کادر به چپ انتخاب بر اساس احاطه کامل

۰۷ / برنامه‌نویس این پروژه

ایلیا فاراهانی (لئو)
برنامه‌نویس ارشد پروژه

Ilia Farahani · @here-is-leo


NEGAR · نگار
Sketch freely. Stay minimal.

↑ Back to top / بازگشت به بالا

Releases

Packages

Contributors

Languages