Create graphics with a hand-drawn, sketchy, appearance

Overview

Rough.js

Rough.js is a small (<9 kB) graphics library that lets you draw in a sketchy, hand-drawn-like, style. The library defines primitives to draw lines, curves, arcs, polygons, circles, and ellipses. It also supports drawing SVG paths.

Rough.js works with both Canvas and SVG.

Rough.js sample

@RoughLib on Twitter.

Install

from npm:

npm install --save roughjs

Or get the latest using unpkg: https://unpkg.com/roughjs@latest/bundled/rough.js

If you are looking for bundled version in different formats, the npm package will have these in the following locations:

CommonJS: roughjs/bundled/rough.cjs.js

ESM: roughjs/bundled/rough.esm.js

Browser IIFE: roughjs/bundled/rough.js

Usage

Rough.js rectangle

const rc = rough.canvas(document.getElementById('canvas'));
rc.rectangle(10, 10, 200, 200); // x, y, width, height

or SVG

const rc = rough.svg(svg);
let node = rc.rectangle(10, 10, 200, 200); // x, y, width, height
svg.appendChild(node);

Lines and Ellipses

Rough.js rectangle

rc.circle(80, 120, 50); // centerX, centerY, diameter
rc.ellipse(300, 100, 150, 80); // centerX, centerY, width, height
rc.line(80, 120, 300, 100); // x1, y1, x2, y2

Filling

Rough.js rectangle

rc.circle(50, 50, 80, { fill: 'red' }); // fill with red hachure
rc.rectangle(120, 15, 80, 80, { fill: 'red' });
rc.circle(50, 150, 80, {
  fill: "rgb(10,150,10)",
  fillWeight: 3 // thicker lines for hachure
});
rc.rectangle(220, 15, 80, 80, {
  fill: 'red',
  hachureAngle: 60, // angle of hachure,
  hachureGap: 8
});
rc.rectangle(120, 105, 80, 80, {
  fill: 'rgba(255,0,200,0.2)',
  fillStyle: 'solid' // solid fill
});

Fill styles can be: hachure(default), solid, zigzag, cross-hatch, dots, dashed, or zigzag-line

Rough.js fill examples

Sketching style

Rough.js rectangle

rc.rectangle(15, 15, 80, 80, { roughness: 0.5, fill: 'red' });
rc.rectangle(120, 15, 80, 80, { roughness: 2.8, fill: 'blue' });
rc.rectangle(220, 15, 80, 80, { bowing: 6, stroke: 'green', strokeWidth: 3 });

SVG Paths

Rough.js paths

rc.path('M80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 Z', { fill: 'green' });
rc.path('M230 80 A 45 45, 0, 1, 0, 275 125 L 275 80 Z', { fill: 'purple' });
rc.path('M80 230 A 45 45, 0, 0, 1, 125 275 L 125 230 Z', { fill: 'red' });
rc.path('M230 230 A 45 45, 0, 1, 1, 275 275 L 275 230 Z', { fill: 'blue' });

SVG Path with simplification:

Rough.js texas map Rough.js texas map

Examples

Rough.js US map

View examples here

API & Documentation

Full Rough.js API

Credits

Some of the core algorithms were adapted from handy processing lib.

Algorithm to convert SVG arcs to Canvas described here was adapted from Mozilla codebase

Contributors

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

License

MIT License (c) Preet Shihn

Comments
  • Option to eliminate randomness

    Option to eliminate randomness

    It would be great if there was an option to eliminate randomness when drawing shapes. So basically that the first time it would be random, and then the same shape would be drawn again.

    For example drawing lines on canvas and then redrawing the entire canvas causes the lines to flicker due to randomness. roughjs

    I would be willing to work on this as a PR, if you think it's a good idea.

    enhancement 
    opened by novoselrok 18
  • Crashes when appending defs for a polygon or path

    Crashes when appending defs for a polygon or path

    When using this library in node, rendering a polygon with a transparent fill fails with Cannot read property 'appendChild' of null. It originates on this line which was built from this line in svg.ts.

    When it tries to run this.defs!.appendChild(pattern);, this.defs is null, so it fails. I'm not familiar with typescript, so I'm not sure what the exclamation mark is for , but skipping this assignment when this.defs === null fixes the error.

    For reproduction, I'm attempting to rendering the following polygon:

    // Coordinates
    [ [ 50, 160 ],
      [ 55, 180 ],
      [ 70, 180 ],
      [ 60, 190 ],
      [ 65, 205 ],
      [ 50, 195 ],
      [ 35, 205 ],
      [ 40, 190 ],
      [ 30, 180 ],
      [ 45, 180 ] ]
    
    // Options
    { stroke: 'green', fill: 'transparent', strokeWidth: 5 }
    

    Circle, ellipse and rectangle do not have this issue, but path crashes with the same error. Let me know if you need more information.

    opened by ismay 14
  • Webpack?

    Webpack?

    Versions [email protected] [email protected]

    I am trying to use roughjs with webpack. (Actually using webpacker, as main app is a Rails application)

    I have tried using rough.svg and rough.canvas, and I end up getting this error (or the same for canvas) every time:

    TypeError: roughjs_dist_rough__WEBPACK_IMPORTED_MODULE_0___default.a.svg is not a function

    from this:

    import rough from "roughjs/dist/rough";
      return {
        bgFrame: (element) => {
    
          let svgBg = document.createElementNS("http://www.w3.org/2000/svg", "svg")
          **const rs = rough.svg(svgBg);**
          let frameWidth = element.width;
          let frameHeight = element.height;
          let node = rs.rectangle(0, 0, frameWidth, frameHeight, {fill: "red"}); 
          svgBg.appendChild(node);
        }
      }
    }) ();
    export default frame
    

    called here:

     [...document.querySelectorAll('img.frame')].forEach(
        (image) => {
          frame.bgFrame(image)
        }
      )
    

    I have tried several variations on this without luck. I can create an svg without roughjs, and add it to the document.

    Thanks for any thoughts on where I am going wrong.

    opened by anitagraham 11
  • rough.js and Typescript

    rough.js and Typescript

    Hi!

    First of all, thanks for creating this package 😄

    I had some trouble getting rough.js to work on a create-react-app / Typescript setup.

    When importing rough.js using import rough from "roughjs/bundled/rough.esm.js", I got this error:

    Could not find a declaration file for module 'roughjs/bundled/rough.esm.js'. '/Users/francisco/dev/puzzle-game/node_modules/roughjs/bundled/rough.esm.js' implicitly has an 'any' type. Try npm install @types/roughjs if it exists or add a new declaration (.d.ts) file containing declare module 'roughjs/bundled/rough.esm.js'; TS7016

    I'm a beginner with TypeScript, so I'm not sure what would be the best solution to fix that, but it seems that adding the following file solves the issue.

    roughjs/bundled/rough.esm.d.ts

    declare module "roughjs/bundled/rough.esm.js" {
      import rough from "roughjs/bin/rough";
      export default rough;
    }
    

    I'm assuming similar files could be created for the other bundles as well.

    Would you be open to a PR for this change ? or do you think there is a better way of solving the issue?

    opened by puigfp 9
  • TS compilation since Async feature

    TS compilation since Async feature

    Hello @pshihn, thank you for this great contribution 👯 👏

    Since version 2.2.0, which introduce async methods, I'm not being able to build the library inside angular 6 app. I do not provide OS and versions information because the issue reside on types of RoughCanvasAsync (promise of...) not matching the implemented class RoughCanvas.

    Here you could see an evidence Build Status

    opened by Ricard 9
  • Add text rendering

    Add text rendering

    Perhaps use https://github.com/ipython/xkcd-font or https://fonts.google.com/specimen/Amatic+SC

    Ideally should be able to configure the font, but using one of these two as a default. Will work with Canvas and SVG.

    Also, see: https://bl.ocks.org/aaizemberg/76b00a3aa08d7161b980d915db6a85a2

    enhancement 
    opened by pshihn 7
  • "Dots" fill looks weird when units are scaled up

    Hiya!

    I'm trying to use rough.js with canvas-sketch; the only part of this that matters is that canvas-sketch lets me use inches as the canvas unit, rather than pixels (and it does the inches-> pixels conversion behind the scenes). For most options this is fine; for ex this is a hashed rectangle of 5x5 inches,

    const rect = rc.rectangle(1, 1, 5, 5, {
          fill: 'black',
          fillWeight: 0.05, 
          hachureGap: 0.5,
          roughness:0.1,
        });
    

    And it looks about what you'd expect (if maybe with slightly wider lines than expected): Screen Shot 2021-11-04 at 12 50 42 PM

    When I switch the fill to "dots" however, the dots go really wild: Screen Shot 2021-11-04 at 12 51 47 PM

    I assume this is happening because there's some internal math that assumes pixels, but before I go digging where to fix that locally, I was wondering if you had any advice of where to look? Or any hacks to just scale the dots down more (that isn't "stop using inches :sob:")? The fillWeight seems to be getting ignored in my case, or somehow scaled in the library maybe? (0.05 inches should be a very small radius, but if i crank up the hachure gap to 3 inches soIid just get fewer dots, it still looks wrong and not like a teensy circle: Screen Shot 2021-11-04 at 12 53 37 PM

    I'm sorry for the edge case! Thanks in advance! 🙏

    opened by notwaldorf 6
  • Disable floating points

    Disable floating points

    There's a recent regression in Skia (Chromium 94.x+) in how it renders stuff when the SVG uses floating points and linecap is set to round, resulting in really annoying bugs https://github.com/excalidraw/excalidraw/issues/4046.

    Reported to crbug https://bugs.chromium.org/p/chromium/issues/detail?id=1266390, but the fix may take a while.

    Can rough support rounding floating point numbers to get around this in the meantime?

    opened by dwelle 6
  • FillStyle Dots bugs on Rectangles bigger than 200x200 (4.1.4)

    FillStyle Dots bugs on Rectangles bigger than 200x200 (4.1.4)

    dotshi

    it looks like the pattern scales with the rectangle until it's 200x200 then it gets capped. See gif above. Also, the render time increases dramatically after 200x200. See gif. I'm just rendering a simple rectangle with fillStyle = 'dots'

    opened by bynormous 6
  • Default Property Values Incorrect in Documentation

    Default Property Values Incorrect in Documentation

    In the documentation, the default values for fillWeight, hachureGap, and simplification are incorrect.

    fillWeight is listed as strokeWidth, but the default is -1 hachureGap is listed as strokeWidth, but the default is -1 simplification is listed as 1, but the default is 0

    opened by MilesManners 6
  • Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The canvas width is 0

    Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The canvas width is 0

    Hi, I modify the demo with D3 version 4 success. https://died.github.io/us-map.html

    But when I change topojson to other country, it give out a error

    Uncaught (in promise) DOMException: Failed to execute 'createPattern' on 'CanvasRenderingContext2D': The canvas width is 0. at t.path (https://cdn.jsdelivr.net/gh/pshihn/rough/dist/rough.min.js:1:24757)

    I think it should be topojson content issue but it's my first time using topojson, so I have no idea to fix it, any tips ? Thank.

    topojson source https://github.com/jason2506/Taiwan.TopoJSON/blob/master/topojson/counties.json

    code different with Taiwan topojson, other same as us-map.html

          d3.json("counties.json", async (error, tw) => {
            if (error) throw error;
            let topo = topojson.feature(tw, tw.objects.map).features;
            for (let feature of topo) {
              await rc.path(path(feature), {
                fill: randomColor(),
                fillStyle: randomStyle(),
                hachureAngle: randomAngle()
              });
            }
          });
    
    opened by died 6
  • Dot filling is not constant with fixed seed

    Dot filling is not constant with fixed seed

    Hello, I want to use dots fillStyle but I have an issue with it. Everytime I use it, it changes dots positions even if the seed is fixed.

    In my app, I have a loop to draw and dots are moving on each draw call which is quite disturbing. Note that I have tested with others fillStyle and it works for others filling. Here is my conf if it can helps :

    {
        fillStyle: "dots",
        fill: "rgb(119, 217, 93)",
        seed: 1,
        stroke: "black",
        roughness: 3,
        strokeWidth: 5
    }
    
    opened by tneullas 0
  • Ability to pass fill rule through options

    Ability to pass fill rule through options

    Hi! We're using rough.js for our application. We're facing issues with rendering path-based shapes due to the fill rule update. Would be very helpful to pass a certain fill rule via options.

    In our case, there's no way to set non-zero to a cylinder path and filling is inconsistent Screenshot 2022-07-27 at 17 33 57 Screenshot 2022-07-27 at 17 24 33

    opened by interstates21 2
  • Bump terser from 5.7.0 to 5.14.2

    Bump terser from 5.7.0 to 5.14.2

    Bumps terser from 5.7.0 to 5.14.2.

    Changelog

    Sourced from terser's changelog.

    v5.14.2

    • Security fix for RegExps that should not be evaluated (regexp DDOS)
    • Source maps improvements (#1211)
    • Performance improvements in long property access evaluation (#1213)

    v5.14.1

    • keep_numbers option added to TypeScript defs (#1208)
    • Fixed parsing of nested template strings (#1204)

    v5.14.0

    • Switched to @​jridgewell/source-map for sourcemap generation (#1190, #1181)
    • Fixed source maps with non-terminated segments (#1106)
    • Enabled typescript types to be imported from the package (#1194)
    • Extra DOM props have been added (#1191)
    • Delete the AST while generating code, as a means to save RAM

    v5.13.1

    • Removed self-assignments (varname=varname) (closes #1081)
    • Separated inlining code (for inlining things into references, or removing IIFEs)
    • Allow multiple identifiers with the same name in var destructuring (eg var { a, a } = x) (#1176)

    v5.13.0

    • All calls to eval() were removed (#1171, #1184)
    • source-map was updated to 0.8.0-beta.0 (#1164)
    • NavigatorUAData was added to domprops to avoid property mangling (#1166)

    v5.12.1

    • Fixed an issue with function definitions inside blocks (#1155)
    • Fixed parens of new in some situations (closes #1159)

    v5.12.0

    • TERSER_DEBUG_DIR environment variable
    • @​copyright comments are now preserved with the comments="some" option (#1153)

    v5.11.0

    • Unicode code point escapes (\u{abcde}) are not emitted inside RegExp literals anymore (#1147)
    • acorn is now a regular dependency

    v5.10.0

    • Massive optimization to max_line_len (#1109)
    • Basic support for import assertions
    • Marked ES2022 Object.hasOwn as a pure function
    • Fix delete optional?.property
    • New CI/CD pipeline with github actions (#1057)

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Interoperability with Pencil

    Interoperability with Pencil

    I'm trying to add a Sketchy Rough collection to Pencil. This is a box example:

    example

    You can see Pencil is able to drag only over SVG paths. Do you think there is a way we could overcome this issue?

    opened by lppedd 2
  • Compatibility roughs.js  - gsap for animation

    Compatibility roughs.js - gsap for animation

    Hello,

    I'm working on a project for science communication about Antarctica. I found rough.js really perfect for the different drawings (https://observablehq.com/@jbaba/antarctica-elevation). These drawings will be part of a scrollytelling where animations are importants to support the story. I plan to use gsap for that purpose. Unfortunately , I discovered that rough.js and gsap are not compatible. Is there an other way to deal with animation and rough.js ? Could compatibility be on the whish list?

    opened by jbbarre 1
Releases(v3.1.0)
Owner
Rough
Hand drawn graphics for the web ⇢ 🎨 RoughJs ✏️ RoughNotation ☑️ Wired-Elements
Rough
Reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser.

roughViz.js is a reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser, based on D3v5, roughjs, and handy. Why? Use

Jared Wilber 6.4k Jan 4, 2023
The JavaScript library for modern SVG graphics.

Snap.svg · A JavaScript SVG library for the modern web. Learn more at snapsvg.io. Follow us on Twitter. Install Bower - bower install snap.svg npm - n

Adobe Web Platform 13.6k Dec 30, 2022
The Swiss Army Knife of Vector Graphics Scripting – Scriptographer ported to JavaScript and the browser, using HTML5 Canvas. Created by @lehni & @puckey

Paper.js - The Swiss Army Knife of Vector Graphics Scripting If you want to work with Paper.js, simply download the latest "stable" version from http:

Paper.js 13.5k Dec 30, 2022
A library optimized for concise and principled data graphics and layouts.

MetricsGraphics is a library built for visualizing and laying out time-series data. At around 15kB (gzipped), it provides a simple way to produce comm

Metrics Graphics 7.5k Dec 22, 2022
A lightweight JavaScript graphics library with the intuitive API, based on SVG/VML technology.

GraphicsJS GraphicsJS is a lightweight JavaScript graphics library with the intuitive API, based on SVG/VML technology. Overview Quick Start Articles

AnyChart 973 Jan 3, 2023
A cross platform high-performance graphics system.

spritejs.org Spritejs is a cross platform high-performance graphics system, which can render graphics on web, node, desktop applications and mini-prog

null 5.1k Dec 24, 2022
React + Canvas = Love. JavaScript library for drawing complex canvas graphics using React.

React Konva React Konva is a JavaScript library for drawing complex canvas graphics using React. It provides declarative and reactive bindings to the

konva 4.9k Jan 9, 2023
A library optimized for concise and principled data graphics and layouts.

MetricsGraphics is a library built for visualizing and laying out time-series data. At around 15kB (gzipped), it provides a simple way to produce comm

Metrics Graphics 7.5k Dec 22, 2022
A lightweight JavaScript graphics library with the intuitive API, based on SVG/VML technology.

GraphicsJS GraphicsJS is a lightweight JavaScript graphics library with the intuitive API, based on SVG/VML technology. Overview Quick Start Articles

AnyChart 937 Feb 5, 2021
Create word clouds in JavaScript.

Word Cloud Layout This is a Wordle-inspired word cloud layout written in JavaScript. It uses HTML5 canvas and sprite masks to achieve near-interactive

Jason Davies 3.6k Jan 2, 2023
Create beautiful charts with one line of JavaScript

Chartkick.js Create beautiful charts with one line of JavaScript See it in action Supports Chart.js, Google Charts, and Highcharts Also available for

Andrew Kane 1.2k Jan 2, 2023
Create beautiful JavaScript charts with one line of React

React Chartkick Create beautiful JavaScript charts with one line of React See it in action Supports Chart.js, Google Charts, and Highcharts Quick Star

Andrew Kane 1.2k Dec 28, 2022
Matteo Bruni 4.7k Jan 4, 2023
Create beautiful JavaScript charts with one line of Ruby

Chartkick Create beautiful JavaScript charts with one line of Ruby. No more fighting with charting libraries! See it in action Chartkick 4.0 was recen

Andrew Kane 6.1k Jan 8, 2023
Create PowerPoint presentations with a powerful, concise JavaScript API.

This library creates Open Office XML (OOXML) Presentations which are compatible with Microsoft PowerPoint, Apple Keynote, and other applications.

Brent Ely 1.8k Dec 30, 2022
svgMap is a JavaScript library that lets you easily create an interactable world map comparing customizable data for each country.

svgMap svgMap is a JavaScript library that lets you easily create an interactable world map comparing customizable data for each country. Live demo: h

Stephan Wagner 155 Dec 25, 2022
Using ASP.NET Core, SignalR, and ChartJs to create real-time updating charts

Real-time Charts with ASP.NET Core, SignalR, and Chart.js This project shows how to update a real-time chart in your web browser using technologies li

Khalid Abuhakmeh 11 Nov 25, 2022
Chart.js plugin to create charts with a hand-drawn, sketchy, appearance

chartjs-plugin-rough Chart.js plugin to create charts with a hand-drawn, sketchy, appearance Version 0.2 requires Chart.js 2.7.0 or later, and Rough.j

Akihiko Kusanagi 73 Dec 1, 2022
Reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser.

roughViz.js is a reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser, based on D3v5, roughjs, and handy. Why? Use

Jared Wilber 6.4k Jan 4, 2023