Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@pwabuilder/pwa-inking
Advanced tools
A [web component](https://meowni.ca/posts/web-components-with-otters/) from the [PWABuilder](https://pwabuilder.com) team that allows you to quickly add a 2D inking canvas (with an optional toolbar) to your Progressive Web App 🎨 ✨
A web component from the PWABuilder team that allows you to quickly add a 2D inking canvas (with an optional toolbar) to your Progressive Web App 🎨 ✨
Built with lit-element
There are two ways to use this component. For simple projects or just to get started fast, we recommend using the component by script tag. If your project is using npm then we recommend using the npm package.
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@pwabuilder/pwa-inking"
></script>
npm install @pwabuilder/pwa-inking
import @pwabuilder/pwa-inking
You can use the element <inking-canvas></inking-canvas>
anywhere in your template, JSX, html, etc. By itself, you will get a blank, bordered canvas which you can control through its APIs (see table for details). Every <inking-canvas></inking-canvas>
must have a distinct name so that its data can be properly cached, transmitted, etc.
<inking-canvas name="myInkingCanvas"></inking-canvas>
You can also add the <inking-toolbar></inking-toolbar>
element within the <inking-canvas></inking-canvas>
element so the user can control the canvas visually. To connect these elements, their respective canvas
and name
attribute values must match. The default toolbar contains all 6 tools in the following order: pen, pencil, highlighter, eraser, copy, and save.
<inking-canvas name="myInkingCanvas">
<inking-toolbar canvas="myInkingCanvas"></inking-toolbar>
</inking-canvas>
You can also specify the toolbar layout and select which subset of tools you want to include.
Toolbar layout options | Possible values |
---|---|
orientation | horizontal or vertical |
vertical | top, center, or bottom |
horizontal | left, center, or right |
Available tool components (which can be added in any order):
<inking-toolbar-pen></inking-toolbar-pen>
<inking-toolbar-pencil></inking-toolbar-pencil>
<inking-toolbar-highlighter></inking-toolbar-highlighter>
<inking-toolbar-eraser></inking-toolbar-eraser>
<inking-toolbar-copy></inking-toolbar-copy>
<inking-toolbar-save></inking-toolbar-save>
Example usage:
<inking-canvas name="myInkingCanvas">
<inking-toolbar canvas="myInkingCanvas" orientation="vertical" vertical="bottom" horizontal="right">
<inking-toolbar-highlighter></inking-toolbar-highlighter>
<inking-toolbar-pen></inking-toolbar-pen>
<inking-toolbar-eraser></inking-toolbar-eraser>
<inking-toolbar-save></inking-toolbar-save>
</inking-toolbar>
</inking-canvas>
By default <inking-canvas></inking-canvas>
will create ink strokes with a width depending on the active pointer event:
Pointer event | Property influencing ink stroke width | Ink stroke width details |
---|---|---|
mouse | none | Should match the default inking-toolbar tool slider value |
touch | width | Changes with surface area of inking screen pressed |
pen | pressure | Changes with downward force applied to inking screen |
If a browser does not provide a value for its pointer event's pressure/width, then the canvas should default to treating this input like a mouse event.
The stroke width regardless of pointer event type can be set and fixed through the <inking-toolbar></inking-toolbar>
.
The <inking-canvas></inking-canvas>
supports live sharing the drawing of its contents on different browsers and devices. A custom event is broadcasted for external influencers to collect. The following snippet detailing the stroke data is taken from the inking-canvas source code:
// broadcast stroke details for live sharing
let inkingCanvasPointerMoveEvent = new CustomEvent("inking-canvas-pointer-move", {
detail: {
pointer: pointer,
previous: previous,
event: event,
x0: previous.clientX,
y0: previous.clientY,
x1: (event as PointerEvent).clientX,
y1: (event as PointerEvent).clientY,
color: this.strokeColor,
pointerType: (event as PointerEvent).pointerType,
pressure: (event as PointerEvent).pressure,
width: (event as PointerEvent).width,
strokeSize: this.strokeSize,
toolStyle: this.toolStyle,
inkingCanvasName: this.name
}
});
this.dispatchEvent(inkingCanvasPointerMoveEvent);
External strokes (ones originally drawn on a different browser or device) can also be drawn on the local <inking-canvas></inking-canvas>
instance by accepting a data package like the one defined above using the drawRemoteStrokes(strokeData: any)
function.
You can use any websocket-based sharing solution to broadcast and deliver stroke data. It is recommended to prevent stroke duplication by ensuring the recipient client is not the stroke's origin and that the destination <inking-canvas></inking-canvas>
matches the origin <inking-canvas></inking-canvas>
by name (in case the app hosts multiple instances of the component).
The following code is a snippet from a Socket.IO example client (found in src/script/pages/app-home.ts):
socket.on('drawing', (data: any) => {
if (data.originID !== this.socket.id) {
if (data.contents.inkingCanvasName === this.firstInkingCanvas.name) {
this.firstInkingCanvas.drawRemoteStroke(data.contents);
} else if (data.contents.inkingCanvasName === this.secondInkingCanvas.name) {
this.secondInkingCanvas.drawRemoteStroke(data.contents);
}
}
});
Property | Attribute | Description | Type | Default |
---|---|---|---|---|
name | name | Used to connect an inking toolbar | string | "" |
canvasHeight | height | Fills parent height default | number | -1 |
canvasWidth | width | Fills parent width by default | number | -1 |
Name | Description |
---|---|
getStrokeColor() | Returns ink color |
setStrokeColor(color: string) | Changes ink color |
getStrokeSize() | Returns ink stroke width |
setStrokeSize(strokeSize: number) | Changes ink stroke width |
getStrokeStyle() | Returns name of active tool defining ink style |
setStrokeStyle(toolName: string) | Changes ink style to reflect provided tool name (pen, pencil, highlighter, or eraser) |
copyCanvasContents() | Copies canvas state to clipboard via Clipboard API (if supported by browser) |
saveCanvasContents() | Opens native file system to allow user to save canvas state as png image |
drawRemoteStroke(strokeData: any) | Draws remote stroke to local canvas based on passed pointer event and remote canvas state |
eraseAll() | Deletes all visible and cached canvas ink |
getCanvas() | Returns inner html canvas object for advanced use cases |
getScale() | Returns canvas size relative to its content's aspect ratio |
requestDrawCanvas() | Triggers an additional canvas redraw if one is not already queued up |
setMinWidth(newMinWidth: number) | Changes minimum canvas width and overrides default 300px value |
Property | Attribute | Description | Type | Default |
---|---|---|---|---|
orientation | orientation | Toolbar layout direction | string | horizontal |
verticalAlignment | vertical | Toolbar layout vertical alignment | string | top |
horizontalAlignment | horizontal | Toolbar layout horizontal alignment | string | left |
targetInkingCanvas | canvas | Connects toolbar to canvas whose name matches this value | string | "" |
Name | Description |
---|---|
getCurrentToolName() | Returns the active tool name |
getCurrentStrokeColor() | Returns the current toolbar ink color of the active tool |
getCurrentStrokeColorName() | Returns the current stroke color name of the active tool |
getCurrentStrokeSize() | Returns the current stroke width of the active tool |
requestDrawSineCanvas() | Triggers an additional example stroke redraw if one is not already queued up |
You can style the different parts of pwa-inking using CSS ::part selectors. Below are the list of parts available for styling:
Component | Part Name | Description |
---|---|---|
inking-canvas | canvas | The html canvas object |
inking-toolbar-pen | button | The toolbar pen button |
inking-toolbar-pencil | button | The toolbar pencil button |
inking-toolbar-highlighter | button | The toolbar highlighter button |
inking-toolbar-eraser | button | The toolbar eraser button |
inking-toolbar-copy | button | The toolbar copy button |
inking-toolbar-save | button | The toolbar save button |
Remove the canvas border:
inking-canvas::part(canvas) {
border: none;
}
Change the save button color:
inking-toolbar-save::part(button) {
background-color: blue;
}
FAQs
A [web component](https://meowni.ca/posts/web-components-with-otters/) from the [PWABuilder](https://pwabuilder.com) team that allows you to quickly add a 2D inking canvas (with an optional toolbar) to your Progressive Web App 🎨 ✨
We found that @pwabuilder/pwa-inking demonstrated a not healthy version release cadence and project activity because the last version was released 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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.