{"id":23494457,"url":"https://github.com/Amer-Jabar/khoshnus","last_synced_at":"2025-08-27T19:31:10.054Z","repository":{"id":258311259,"uuid":"872304436","full_name":"Amer-Jabar/khoshnus","owner":"Amer-Jabar","description":"A library to bring life to your web writings!","archived":false,"fork":false,"pushed_at":"2024-12-02T17:32:52.000Z","size":327,"stargazers_count":244,"open_issues_count":0,"forks_count":10,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-09T09:35:12.004Z","etag":null,"topics":["calligraphy","font","frontend","javascript","ui","writing"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/khoshnus","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Amer-Jabar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-14T07:55:50.000Z","updated_at":"2025-06-10T14:12:14.000Z","dependencies_parsed_at":"2024-11-08T12:23:29.106Z","dependency_job_id":"cf14b5f5-929c-4242-a877-1951c25227a7","html_url":"https://github.com/Amer-Jabar/khoshnus","commit_stats":null,"previous_names":["amer-jabar/khoshnus"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Amer-Jabar/khoshnus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amer-Jabar%2Fkhoshnus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amer-Jabar%2Fkhoshnus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amer-Jabar%2Fkhoshnus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amer-Jabar%2Fkhoshnus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Amer-Jabar","download_url":"https://codeload.github.com/Amer-Jabar/khoshnus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amer-Jabar%2Fkhoshnus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272367687,"owners_count":24922229,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-27T02:00:09.397Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calligraphy","font","frontend","javascript","ui","writing"],"created_at":"2024-12-25T03:03:04.788Z","updated_at":"2025-08-27T19:31:10.042Z","avatar_url":"https://github.com/Amer-Jabar.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"![khoshnus-demo-gif](https://imgur.com/0MkNbTJ.gif)\n\n# ✨ Khoshnus - Craft Beautiful Handwritten SVG Text Animations\n\nKhoshnus is just a library, but it's also your tool for bringing life to static text in an artistic way. With its\nelegant SVG animations, your text can now be revealed as if written by hand!\n\n## 🖋️ What Does Khoshnus Do?\n\nKhoshnus lets you:\n\n- Animate SVG text with a beautiful, handwritten effect.\n- Choose from unique fonts with customizable animations.\n- Control each letter's timing, stroke, and fill for a more personalized touch.\n- Transform plain text into an elegant visual experience.\n\n## 🎨 Features\n\n- **Multiple Font Styles**: Choose from an array of fonts.\n- **Smooth SVG Animation**: Stroke and fill effects are animated for a lifelike handwriting experience.\n- **Fine-Grained Control**: Adjust timing and style for each letter—make them reveal at your own pace.\n- **Fully Configurable**: Every visual aspect of the text can be customized.\n\n## 🚀 Quick Start\n\n### 📦 Installation\n\nTo get started with Khoshnus, add the npm package to your project by running either of the following commands:\n\n```bash\nnpm install khoshnus\n--------------------\nyarn add khoshnus\n```\n\n### TL;DR\n\nDo this if you are using React.\n```javascript\nimport { FONT_MATRIX, initialize, write } from \"khoshnus\"\nimport 'khoshnus/style.css'\n\nconst App = () =\u003e {\n    useEffect(() =\u003e {\n        const manuscript = new Manuscript();\n        manuscript.setup({\n            font: FONT_MATRIX[\"Pinyon Script\"].name,\n            fontSize: \"10px\",\n        });\n        const textId = manuscript.write(\"Hello Universe, My Name Is Optimus Prime!\")\n        manuscript.erase(textId, { delayOperation: 15000 })\n    }, []);\n\n    return (\n        \u003cdiv\u003e\n            \u003csvg id=\"khoshnus\" width=\"100%\" height=\"500\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003c/svg\u003e\n        \u003c/div\u003e\n    )\n}\n```\n\n---\n\n---\n\n### 1. Include the SVG in Your HTML\n\nAdd an empty SVG element with the id of `khoshnus` that Khoshnus will use to animate your text. Feel free to adjust the size of the SVG\nbased on your needs.\n\n```html\n\n\u003csvg id=\"khoshnus\" width=\"100%\" height=\"100%\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003c/svg\u003e\n```\n\n### 2. Initialize and Write Your Text\n\nOnce you have your bare HTML file, import the basic stuff needed from the library:\n\n```javascript\nimport { initialize, write, FONT_MATRIX } from \"khoshnus\";\n\nimport \"khoshnus/style.css\";\n```\n\nThen start using the library:\n\n```javascript\n// Create the Manuscript instance and setup global configuration.\nconst manuscript = new Manuscript();\nmanuscript.setup({\n    font: FONT_MATRIX[\"Pinyon Script\"].name,\n    fontSize: \"10px\",\n});\n// Write the letters into the SVG element.\nconst textId = manuscript.write(\"Hello Universe, My Name Is Optimus Prime!\")\n\n// Erase the text after the desired waiting period - optional, you can leave it forever ;)\nmanuscript.erase(textId, { delayOperation: 15000 })\n```\n\n### 3. Customize Your Animation\n\nKhoshnus offers full control over your animation. Want the text to feel like it’s written slowly or quickly? You decide!\nHere’s a glimpse of how you can tweak it:\n\n```javascript\ninitialize({\n    font: FONT_MATRIX[\"Pinyon Script\"].name, // Only fonts from FONT_MATRIX are available.\n    fontSize: \"16px\",\n    start: {\n        startStrokeDashoffset: FONT_MATRIX[\"Pinyon Script\"].strokeDashoffset,\n        startStroke: \"black\",\n        startStrokeWidth: 0.0000000001,\n        startFill: \"transparent\",\n    },\n    end: {\n        endStrokeDashoffset: 0,\n        endStroke: \"transparent\",\n        endStrokeWidth: 0.3,\n        endFill: \"black\",\n    },\n    durations: {\n        strokeDashoffsetDuration: 3500,\n        strokeWidthDuration: 2500,\n        strokeDuration: 2500,\n        fillDuration: 4000,\n    },\n});\n```\n\n### ✍️ Positioning \u0026 Delays\n\nThe magic of Khoshnus lies in its ability to provide positioning and delay control. Here’s an example:\n\n```javascript\nwrite(\"Your Text Here\", {\n    writeConfiguration: {\n        eachLetterDelay: 250, // Delay of each letter after the previous one.\n        delayOperation: 0 // Delay of the write operation - useful when you want wait time between written snippets.\n    },\n    textConfiguration: {\n        x: \"50%\", // X position of the text.\n        y: \"50%\", // Y position of the text.\n        textAnchor: \"middle\", // Anchor of the text.\n        dominantBaseline: \"middle\", // Baseline of the text - where it should align.\n        fontSize: \"12px\" // Font size - appearance could possibly depend on the parent element.\n    }\n});\n```\n\n## 💡 Advanced Example\n\nCheck out the following snippet:\n```javascript\nconst manuscript = new Manuscript();\nmanuscript.setup({\n    font: FONT_MATRIX[\"Pinyon Script\"].name,\n    fontSize: \"10px\",\n});\nconst textId0 = manuscript.write(\"Do not lament my absence,\", {\n    textElementAttributes: { y: \"10%\", },\n    writeConfiguration: { eachLetterDelay: 100 }\n})\nconst textId1 = manuscript.write(\"for in my spark,\", {\n    textElementAttributes: { y: \"25%\" },\n    writeConfiguration: {\n        delayOperation: 3000,\n        eachLetterDelay: 100\n    }\n})\nconst textId2 = manuscript.write(\"I know that this is not the end,\", {\n    textElementAttributes: { y: \"37.5%\" },\n    writeConfiguration: {\n        delayOperation: 5500,\n        eachLetterDelay: 100,\n    }\n})\nconst textId3 = manuscript.write(\"but merely,\", {\n    textElementAttributes: { y: \"55%\" },\n    writeConfiguration: {\n        delayOperation: 9500,\n        eachLetterDelay: 100,\n    }\n})\nconst textId4 = manuscript.write(\"a new beginning.\", {\n    textElementAttributes: { y: \"67.5%\", },\n    writeConfiguration: {\n        delayOperation: 11500,\n        eachLetterDelay: 100,\n    }\n})\nconst textId5 = manuscript.write(\"- Optimus Prime\", {\n    textElementAttributes: {\n        x: \"80%\",\n        y: \"90%\",\n    }, writeConfiguration: {\n        delayOperation: 14000,\n        eachLetterDelay: 100,\n    }\n})\nmanuscript.erase(textId0, { delayOperation: 20000 });\nmanuscript.erase(textId1, { delayOperation: 20000 });\nmanuscript.erase(textId2, { delayOperation: 20000 });\nmanuscript.erase(textId3, { delayOperation: 20000 });\nmanuscript.erase(textId4, { delayOperation: 20000 });\nmanuscript.erase(textId5, { delayOperation: 20000 });\n```\n\nIt generates the following piece of art:\n\nhttps://github.com/user-attachments/assets/ac1641df-facf-40db-91ea-e7565340cba7\n\n## Multiple SVGs\n\nIt is possible to define multiple SVGs in your component/view as long as they have different ids and you define which Manuscript object references which SVG element. The following React.js snippet shows two SVG elements being referenced, each by its corresponding Manuscript object:\n\n```javascript\nconst App = () =\u003e {\n  useEffect(() =\u003e {\n    const manuscript1 = new Manuscript({\n      svgId: \"khoshnus-1\",\n      font: FONT_MATRIX[\"Pinyon Script\"].name,\n      fontSize: \"10px\",\n    });\n    const text1 = manuscript1.write(\"Do not lament my absence,\", {\n      textElementAttributes: {\n        y: \"10%\",\n      }, writeConfiguration: { eachLetterDelay: 100 }\n    })\n    manuscript1.erase(text1)\n    \n    const manuscript2 = new Manuscript({\n      svgId: \"khoshnus-2\",\n      font: FONT_MATRIX[\"Pinyon Script\"].name,\n      fontSize: \"10px\",\n    });\n    const text2 = manuscript2.write(\"For in my spark,\", {\n      textElementAttributes: {\n        y: \"10%\",\n      }, writeConfiguration: { eachLetterDelay: 100 }\n    })\n    manuscript2.erase(text2)\n  }, []);\n\n  return (\n    \u003cdiv\u003e\n      \u003csvg id=\"khoshnus-1\" width=\"100%\" height=\"300\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003c/svg\u003e\n      \u003csvg id=\"khoshnus-2\" width=\"100%\" height=\"300\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003c/svg\u003e\n      \u003c/div\u003e\n  )\n}\n```\n\n### 🖼️ Font Options\n\nHere are some of the unique fonts you can play with:\n\n- **BlackCherry**: Bold strokes with an offset of 80\n- **Celtic**: Celtic-inspired, with a stroke offset of 50\n- **Eutemia**: Classic, elegant font with a 60 offset\n- **Kingthings**: Royal and medieval vibes, stroke offset of 40\n- **Ruritania**: Majestic, with an exaggerated offset of 280\n- **VTKS**: Artistic flair, with an offset of 150\n- **Parisienne**: Soft and feminine, offset of 100\n- **Sevillana**: Spanish-inspired curves, with an offset of 120\n- **Pinyon Script**: Formal and sophisticated, offset of 100\n\n### 🌟 Creative Use Cases\n\nHere are just a few ways you can use Khoshnus:\n\n- Display personalized signature animations for your website.\n- Add a dynamic handwritten greeting to your home page.\n- Animate text for art projects, digital invitations, or logos.\n- Create a storybook-like experience with flowing, hand-drawn text.\n\n### ⚖️ License\n\nThis project is licensed under the MIT License, meaning you're free to use, modify, and distribute it in both personal\nand commercial projects.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAmer-Jabar%2Fkhoshnus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAmer-Jabar%2Fkhoshnus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAmer-Jabar%2Fkhoshnus/lists"}