Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
@bicycle-codes/atrament
Advanced tools
Tiny JS library for beautiful drawing and handwriting on the HTML Canvas
A small JS library for beautiful drawing and handwriting on the HTML Canvas
Atrament is a library for drawing and handwriting on the HTML canvas. Its goal is for drawing to feel natural and comfortable, and the result to be smooth and pleasing. Atrament does not store the stroke paths itself - instead, it draws directly onto the canvas bitmap, just like an ink pen onto a piece of paper ("atrament" means ink in Slovak and Polish). This makes it suitable for certain applications, and not quite ideal for others.
⚠️ Note: From version 4, Atrament supports evergeen browsers (Firefox, Chrome and Chromium-based browsers) and Safari 15 or above. If your application must support older browsers, please use version 3. You can view the v3 documentation here.
Features:
Enjoy!
If you're using a tool like rollup
or webpack
to bundle your code, you can install it using npm.
npm install --save atrament
.import { Atrament } from 'atrament';
<canvas>
tag, e.g.:<canvas id="sketchpad" width="500" height="500"></canvas>
Atrament
instance passing it your canvas object:import Atrament from 'atrament';
const canvas = document.querySelector('#sketchpad');
const sketchpad = new Atrament(canvas);
const sketchpad = new Atrament(canvas, {
width: 500,
height: 500,
color: 'orange',
});
sketchpad.clear();
sketchpad.weight = 20; //in pixels
sketchpad.color = '#ff485e'; //just like CSS
import { MODE_DRAW, MODE_ERASE, MODE_FILL, MODE_DISABLED } from 'atrament';
sketchpad.mode = MODE_DRAW; // default
sketchpad.mode = MODE_ERASE; // eraser tool
sketchpad.mode = MODE_FILL; // click to fill area
sketchpad.mode = MODE_DISABLED; // no modification to the canvas (will still fire stroke events)
0.85
by default.sketchpad.smoothing = 1.3;
true
by default.sketchpad.adaptiveStroke = false;
strokerecorded
event). false
by default.sketchpad.recordStrokes = true;
x
and y
coordinates, and a time
which is the number of milliseconds since the stroke began, until the segment was drawn.To make drawings look sharp on high DPI screens, Atrament scales its drawing context by window.devicePixelRatio
since v4.0.0. This means when you set a custom width
or height
, you should
also multiply the CSS pixel values by devicePixelRatio
. The values accepted by draw()
and included in stroke events are always in CSS pixels.
These events fire when the canvas is first drawn on, and when it's cleared.
The state is stored in the dirty
property.
sketchpad.addEventListener('dirty', () => console.info(sketchpad.dirty));
sketchpad.addEventListener('clean', () => console.info(sketchpad.dirty));
These events don't provide any data - they just inform that a stroke has started/finished.
sketchpad.addEventListener('strokestart', () => console.info('strokestart'));
sketchpad.addEventListener('strokeend', () => console.info('strokeend'));
These only fire in fill mode. The fillstart
event also contains x
and y
properties
denoting the starting point of the fill operation (where the user has clicked).
sketchpad.addEventListener('fillstart', ({ x, y }) =>
console.info(`fillstart ${x} ${y}`),
);
sketchpad.addEventListener('fillend', () => console.info('fillend'));
The following events only fire if the recordStrokes
property is set to true.
strokerecorded
fires at the same time as strokeend
and contains data necessary for reconstructing the stroke.
segmentdrawn
fires during stroke recording every time the draw
method is called. It contains the same data as strokerecorded
.
sketchpad.addEventListener('strokerecorded', ({ stroke }) =>
console.info(stroke),
);
/*
{
segments: [
{
point: { x, y },
time,
}
],
color,
weight,
smoothing,
adaptiveStroke,
}
*/
sketchpad.addEventListener('segmentdrawn', ({ stroke }) =>
console.info(stroke),
);
To enable functionality such as undo/redo, stroke post-processing, and SVG export in apps using Atrament, the library can be configured to record and programmatically draw the strokes.
The first step is to enable recordStrokes
, and add a listener for the strokerecorded
event:
atrament.recordStrokes = true;
atrament.addEventListener('strokerecorded', ({ stroke }) => {
// store `stroke` somewhere
});
The stroke can then be reconstructed using methods of the Atrament
class:
// set drawing options
atrament.mode = stroke.mode;
atrament.weight = stroke.weight;
atrament.smoothing = stroke.smoothing;
atrament.color = stroke.color;
atrament.adaptiveStroke = stroke.adaptiveStroke;
// don't want to modify original data
const segments = stroke.segments.slice();
const firstPoint = segments.shift().point;
// beginStroke moves the "pen" to the given position and starts the path
atrament.beginStroke(firstPoint.x, firstPoint.y);
let prevPoint = firstPoint;
while (segments.length > 0) {
const point = segments.shift().point;
// the `draw` method accepts the current real coordinates
// (i. e. actual cursor position), and the previous processed (filtered)
// position. It returns an object with the current processed position.
const { x, y } = atrament.draw(point.x, point.y, prevPoint.x, prevPoint.y);
// the processed position is the one where the line is actually drawn to
// so we have to store it and pass it to `draw` in the next step
prevPoint = { x, y };
}
// endStroke closes the path
atrament.endStroke(prevPoint.x, prevPoint.y);
Atrament does not provide its own undo/redo functionality to keep the scope as small as possible. However, using stroke recording and programmatic drawing, it is possible to implement undo/redo with a relatively small amount of code. See @nidoro and @feored's example here.
To obtain the dependencies, cd
into the atrament directory and run npm install
.
You should be able to then build atrament by simply running npm run build
and rebuild continuously with npm run watch
.
The demo app is useful for development, and it's set up to use the compiled files in /dist
. It's a plain HTML website which can be served with any local server.
A good way to develop using the demo is to run python -m http.server
(with Python 3) in the /demo
directory. The demo will be served on localhost:8000
.
FAQs
Tiny JS library for beautiful drawing and handwriting on the HTML Canvas
The npm package @bicycle-codes/atrament receives a total of 13 weekly downloads. As such, @bicycle-codes/atrament popularity was classified as not popular.
We found that @bicycle-codes/atrament demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.