{"id":13406074,"url":"https://github.com/vinothpandian/react-sketch-canvas","last_synced_at":"2026-05-27T04:05:26.199Z","repository":{"id":32497272,"uuid":"133679825","full_name":"vinothpandian/react-sketch-canvas","owner":"vinothpandian","description":"Freehand vector drawing component for React using SVG as canvas 🖌️","archived":false,"fork":false,"pushed_at":"2024-11-16T21:26:49.000Z","size":6768,"stargazers_count":495,"open_issues_count":36,"forks_count":89,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-09T03:04:54.200Z","etag":null,"topics":["canvas","component","freehand-drawing","react","react-library","sketch","sketching"],"latest_commit_sha":null,"homepage":"https://vinoth.info/react-sketch-canvas","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vinothpandian.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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}},"created_at":"2018-05-16T14:40:17.000Z","updated_at":"2025-05-07T12:56:10.000Z","dependencies_parsed_at":"2024-02-20T02:44:22.160Z","dependency_job_id":"dbfd9f21-1ff5-43d5-9100-3e1a7a3fcf14","html_url":"https://github.com/vinothpandian/react-sketch-canvas","commit_stats":{"total_commits":160,"total_committers":11,"mean_commits":"14.545454545454545","dds":"0.23750000000000004","last_synced_commit":"80f85cefe8a568915e7519e749f22b1ba1575fe8"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinothpandian%2Freact-sketch-canvas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinothpandian%2Freact-sketch-canvas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinothpandian%2Freact-sketch-canvas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinothpandian%2Freact-sketch-canvas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vinothpandian","download_url":"https://codeload.github.com/vinothpandian/react-sketch-canvas/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254459088,"owners_count":22074605,"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","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":["canvas","component","freehand-drawing","react","react-library","sketch","sketching"],"created_at":"2024-07-30T19:02:20.193Z","updated_at":"2026-05-27T04:05:26.169Z","avatar_url":"https://github.com/vinothpandian.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","UI Components"],"sub_categories":["Canvas"],"readme":"\u003cp style=\"text-align: center;\"\u003e\n  \u003cimg src=\"https://i.imgur.com/ajs39FC.png\" height=\"150\" alt=\"React Sketch Canvas\" /\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\u003ch3 style=\"text-align: center;\"\u003e\n  Freehand vector drawing component for React using SVG as canvas 🖌\n\u003c/h3\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cdiv style=\"text-align: center;\"\u003e\n\n![npm](https://img.shields.io/npm/v/react-sketch-canvas?style=flat-square) \u0026nbsp;\u0026nbsp; ![NPM](https://img.shields.io/npm/l/react-sketch-canvas?style=flat-square) \u0026nbsp;\u0026nbsp; ![npm](https://img.shields.io/npm/dm/react-sketch-canvas?style=flat-square) \u003cbr/\u003e\n![npm bundle size](https://img.shields.io/bundlephobia/min/react-sketch-canvas?style=flat-square) \u0026nbsp;\u0026nbsp; ![npm bundle size](https://img.shields.io/bundlephobia/minzip/react-sketch-canvas?style=flat-square) \u003cbr/\u003e\n[![codecov](https://codecov.io/gh/vinothpandian/react-sketch-canvas/branch/master/graph/badge.svg?token=NJcqGRgbSa)](https://codecov.io/gh/vinothpandian/react-sketch-canvas)\n\n\u003c/div\u003e\n\n## Overview\n\n### Features\n\n- **Supports Desktop and Mobile.**\n- **Accepts input from Mouse, touch, and graphic tablets.**\n\n### Requirements\n\n- **\u003cspan style=\"color:red\"\u003e**Requires React \u003e= 18.0.0**\u003c/span\u003e**\n\n### Wanna test React Sketch Canvas before using it?\n\n- **Try [here](https://vinoth.info/react-sketch-canvas)**\n\n## Installation\n\nIf you use npm\n\n```sh\nnpm i react-sketch-canvas\n```\n\nor with pnpm\n\n```sh\npnpm add react-sketch-canvas\n```\n\n## Example\n\nCommon usage example\n\n```javascript\nimport * as React from \"react\";\nimport { ReactSketchCanvas } from \"react-sketch-canvas\";\n\nconst styles = {\n  border: \"0.0625rem solid #9c9c9c\",\n  borderRadius: \"0.25rem\",\n};\n\nconst Canvas = () =\u003e {\n  return \u003cReactSketchCanvas style={styles} width=\"600\" height=\"400\" strokeWidth={4} strokeColor=\"red\" /\u003e;\n};\n```\n\nTo export Data URL of your sketch use ref\n\n```javascript\nimport * as React from \"react\";\nimport { ReactSketchCanvas } from \"react-sketch-canvas\";\n\nconst styles = {\n  border: \"0.0625rem solid #9c9c9c\",\n  borderRadius: \"0.25rem\",\n};\n\nconst Canvas = class extends React.Component {\n  constructor(props) {\n    super(props);\n\n    this.canvas = React.createRef();\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cReactSketchCanvas ref={this.canvas} strokeWidth={5} strokeColor=\"black\" /\u003e\n        \u003cbutton\n          onClick={() =\u003e {\n            this.canvas.current\n              .exportImage(\"png\")\n              .then((data) =\u003e {\n                console.log(data);\n              })\n              .catch((e) =\u003e {\n                console.log(e);\n              });\n          }}\n        \u003e\n          Get Image\n        \u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n};\n```\n\n## List of Props\n\n| Props                              | Expected datatype | Default value         | Description                                                                                         |\n| ---------------------------------- | ----------------- | --------------------- | --------------------------------------------------------------------------------------------------- |\n| width                              | PropTypes.string  | 100%                  | canvas width (em/rem/px)                                                                            |\n| height                             | PropTypes.string  | 100%                  | canvas width (em/rem/px)                                                                            |\n| id                                 | PropTypes.string  | \"react-sketch-canvas\" | ID field to uniquely identify a SVG canvas (Supports multiple canvases in a single page)            |\n| className                          | PropTypes.string  | \"\"                    | Class for using with CSS selectors                                                                  |\n| strokeColor                        | PropTypes.string  | black                 | Pen color                                                                                           |\n| canvasColor                        | PropTypes.string  | white                 | canvas color (HTML colors)                                                                          |\n| backgroundImage                    | PropTypes.string  | ''                    | Set SVG background with image URL                                                                   |\n| exportWithBackgroundImage          | PropTypes.bool    | false                 | Keep background image on image/SVG export (on false, canvasColor will be set as background)         |\n| preserveBackgroundImageAspectRatio | PropTypes.string  | none                  | Set aspect ratio of the background image. For possible values check [MDN docs][preserveaspectratio] |\n| strokeWidth                        | PropTypes.number  | 4                     | Pen stroke size                                                                                     |\n| eraserWidth                        | PropTypes.number  | 8                     | Erase size                                                                                          |\n| allowOnlyPointerType               | PropTypes.string  | all                   | allow pointer type (\"all\"/\"mouse\"/\"pen\"/\"touch\")                                                    |\n| onChange                           | PropTypes.func    |                       | Returns the current sketch path in `CanvasPath` type on every path change                           |\n| onStroke                           | PropTypes.func    |                       | Returns the the last stroke path and whether it is an eraser stroke on every pointer up event       |\n| style                              | PropTypes.object  | false                 | Add CSS styling as CSS-in-JS object                                                                 |\n| svgStyle                           | PropTypes.object  | {}                    | Add CSS styling as CSS-in-JS object for the SVG                                                     |\n| withTimestamp                      | PropTypes.bool    | false                 | Add timestamp to individual strokes for measuring sketching time                                    |\n| readOnly                           | PropTypes.bool    | false                 | Disable drawing on the canvas (undo/redo, clear \u0026 reset will still work.)                           |\n\nSet SVG background using CSS [background][css-bg] value\n\nYou can specify width and height values in em or rem. It fills the parent element space if width and height are not set\n\n\u003cbr /\u003e\n\n## Methods\n\nYou can export the sketch as an image or as a svg\n\n_Use ref to access the element and call the following functions to export image_\n\n| Props                        | Expected datatype                                                                                                                                |\n| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |\n| eraseMode(boolean)           | Switch to eraser mode by passing true. You can switch back to pen mode by passing false                                                          |\n| clearCanvas()                | Clears the canvas.                                                                                                                               |\n| resetCanvas()                | Resets the canvas and clears the undo/redo stack along with it.                                                                                  |\n| undo()                       | Undo the last action.                                                                                                                            |\n| redo()                       | Redo the previous action.                                                                                                                        |\n| exportImage(imageTypeString) | Accepts an image type as argument (`ExportImageType`) and returns a Promise which resolves to base64 data url of the sketch.                     |\n| exportSvg()                  | returns a Promise which resolves to an inline SVG element.                                                                                       |\n| exportPaths()                | returns a Promise which resolves to an instance of `CanvasPath`.                                                                                 |\n| loadPaths(CanvasPath)        | Accepts an `CanvasPath` exported from exportPaths() and loads it on the canvas.                                                                  |\n| getSketchingTime()           | returns a Promise which resolves the time that user sketched in the canvas (considers only when the user made the strokes or erased the strokes) |\n\n## Types\n\n```ts\ntype ExportImageType = \"jpeg\" | \"png\";\n\ninterface Point {\n  x: number;\n  y: number;\n}\n\ninterface CanvasPath {\n  paths: Point[];\n  strokeWidth: number;\n  strokeColor: string;\n  drawMode: boolean;\n  startTimestamp?: number;\n  endTimestamp?: number;\n}\n```\n\n---\n\n## Thanks to\n\n- Philipp Spiess' [tutorial][based-on]\n- Draws smooth curves, thanks to François Romain's [tutorial][smooth-curve-tutorial]\n\n---\n\n## Disclaimer on Agentic Engineering\n\nVersion 8 was built with the help of AI coding assistants. I made the plans, decisions, and reviews, then manually tested as much as I could. Most of the implementation was done by Claude Code (Opus 4.7) and Codex (GPT-5.5), so I want to be upfront that the bulk of the code was authored by the models rather than typed by hand.\n\nIf you are curious about the workflow, Simon Willison has a great write-up on the patterns I followed: [Agentic Engineering Patterns](https://simonwillison.net/guides/agentic-engineering-patterns/).\n\n---\n\n[based-on]: https://pspdfkit.com/blog/2017/how-to-build-free-hand-drawing-using-react/\n[smooth-curve-tutorial]: https://medium.com/@francoisromain/smooth-a-svg-path-with-cubic-bezier-curves-e37b49d46c74\n[css-bg]: https://developer.mozilla.org/en-US/docs/Web/CSS/background\n[preserveaspectratio]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvinothpandian%2Freact-sketch-canvas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvinothpandian%2Freact-sketch-canvas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvinothpandian%2Freact-sketch-canvas/lists"}