This library provides you simple Angular bindings for KonvaJS. This is still a work in progress and not an official release of Konva framework. PRs and contributions are more than welcome.
This project is inspired by the more official library n2-konva that, as for now, seems not to be maintaned.
Supported Angular version: 16
.
- Installation
- Konva API implementation status
- Example usage
- Stage autoscale
- Basic shapes
- Images
- Labels
- Transitions (Konva.Tween)
- Events handling
- Inner events
- How to contribute
- Full API Documentation
npm install ngx-konva konva
Simply import NgxKonvaModule
inside any module you need to use it in:
import { NgxKonvaModule } from 'ngx-konva';
@NgModule({
// ... your stuff
imports: [
// ... other modules import
NgxKonvaModule,
],
// ... other module stuff
})
export class MyModule { }
API | Status | Component |
---|---|---|
Stage |
âś… | ko-stage |
Layer |
âś… | ko-layer |
Rect |
âś… | ko-rect |
Circle |
âś… | ko-circle |
Line |
âś… | ko-line |
RegularPolygon |
âś… | ko-regular-polygon |
Text |
âś… | ko-text |
TextPath |
âś… | ko-text-path |
Ellipse |
âś… | ko-ellipse |
Wedge |
âś… | ko-wedge |
Group |
âś… | ko-group |
Ring |
âś… | ko-ring |
Image |
âś… | ko-image |
Label |
âś… | ko-label |
Path |
âś… | ko-path |
Sprite |
❌ | |
Star |
âś… | ko-star |
Arrow |
âś… | ko-arrow |
Shape |
âś… | ko-shape (for custom shapes) |
Arc |
âś… | ko-arc |
Tween |
âś… | transitionWith @Input |
Filters |
❌ | |
Animations |
❌ |
Each element respect the hierarchy described here: https://konvajs.org/docs/overview.html.
<ko-stage [config]="{width: 100, height: 100}">
<ko-layer>
<ko-circle [config]="{
radius: 120,
fill: 'blue',
stroke: 'black',
strokeWidth: 4,
x: 0,
y: 0
}"></ko-circle>
<ko-image [config]="{x: 100, y: 100}"
src="https://upload.wikimedia.org/wikipedia/it/0/08/Dartfener.jpg">
</ko-image>
</ko-layer>
</ko-stage>
Each item has an @Input config
you can use dynamically to change the configuration of the Node.
All properties allowed are handled by config
, but if you need to change the id
of a Node use the related id
@Input.
Note: Each Node is identified by an automatically generated
id
to avoid adding the same node multiple times, use theid
@Input accordingly.
In order to listen to events refer to Events handling.
If you do not want to handle width/height
directly on ko-stage
you can use the component ko-stage-autoscale
and modifying the parent container size: the ko-stage-autoscale
will size and scale automatically the container in order to fit it perfectly, even when the container resizes.
The first container size different from 0, 0 will be considered the initial 1 scale.
<div id="container" [style.width.px]="width" [style.height.px]="height">
<ko-stage-autoscale>
<ko-layer>
<ko-circle [config]="{
radius: 120,
fill: 'blue',
stroke: 'black',
strokeWidth: 4,
x: 0,
y: 0
}"></ko-circle>
</ko-layer>
</ko-stage-autoscale>
</div>
If you want to capture the initial canvas resolution you can listen to the EventEmitter (initDimensions)
that will return { width: number, height: number }
of the scale: 1
canvas.
Since the stage is already scaled to fit the container if you need to add an additional scale to your stage you can use the handy @Input additionalScale
from the component.
Apart for nodes that are described in the next paragraphs, for each of the basic shapes provided by Konva there is a component that can be used. Take a look to the Konva API implementation status to see which component you should use.
Each of these components receives a @Input config
compatible with the shape configuration and a centerOrigin
@Input to offset the origin at the center of the figure.
<ko-ring [config]="{
x: 500,
y: 500,
innerRadius: 40,
outerRadius: 70,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4,
}"></ko-ring>
<ko-shape [config]="{
x: 10,
y: 20,
fill: '#00D2FF',
width: 100,
height: 50,
sceneFunc: this.sceneFunc
}"></ko-shape>
In order to simplify the Konva Image API the [config]
provided for ko-image
does not include config.image
. You can use the @input [src]
to specify the image to load and all the loading work will be done internally for you.
<ko-stage [config]="{width: 100, height: 100}">
<ko-layer>
<ko-image [config]="{x: 100, y: 100}"
src="https://upload.wikimedia.org/wikipedia/it/0/08/Dartfener.jpg">
</ko-image>
</ko-layer>
</ko-stage>
You can use ko-label
to render a Label provided with a text and a tag. You can disable both of them by using the @Inputs textDisabled
and tagDisabled
, and you can change the configuration of each component by updating the @Input config
for the Label, textConfig
for the Text and tagConfig
for the Tag.
<ko-label [config]="{
x: 500,
y: 500,
opacity: 0.75,
zIndex: 10
}"
[tagConfig]="{
fill: 'black',
pointerDirection: 'down',
pointerWidth: 10,
pointerHeight: 10,
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffsetX: 10,
shadowOffsetY: 10,
shadowOpacity: 0.5,
}"
[textConfig]="{
text: 'Tooltip pointing down',
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'red',
}">
</ko-label>
In order to use Tween and transition between states in a component you can use the transitionWith
@Input available for every kind of shape. Consider that the passed [config]
is considered the initial state of the component and it will not apply an initial animation. Each modification on [config]
@Input will cancel (if not already finished) the previous transition and bring the component to the next state with the configuration passed inside transitionWith
, that accepts the TweenConfig.duration
and TweenConfig.easing
parameters.
If you want to skip a transition in one of the [config]
updates you can alway pass the _skipTransition: true
parameter and for that change no animation will be triggered.
<ko-image [transitionWith]="{duration: 2}" [config]="imageConfig"
src="https://upload.wikimedia.org/wikipedia/it/0/08/Dartfener.jpg"></ko-image>
Try changing imageConfig
over time to see the animation happening.
You can subscribe to the Tween events by using the (transitionOnFinish)
and (transitionOnUpdate)
@Output.
Tip: if you need it,
KoNestable.Easing
exports the default Tween easing functions.
In order to avoid consuming memory setting up unused listeners, the Node events are handled through directives.
These are the directives you can use:
<ko-circle koHover (onHoverStart)="handleStart($event)" (onHoverEnd)="handleEnd($event)" [config]="{
radius: 120,
fill: 'blue',
stroke: 'black',
strokeWidth: 4,
x: 0,
y: 0
}"></ko-circle>
It allows to capture when the user hover on a Node. Each onHoverStart
and onHoverEnd
emits the underlying Shape
of KonvaJS.
<ko-circle koPointer (koPointerDblClick)="onDblClick($event)" [config]="{
radius: 120,
fill: 'blue',
stroke: 'black',
strokeWidth: 4,
x: 0,
y: 0
}"></ko-circle>
It allows to capture all pointer events. Full API.
<ko-circle koDrag (koDragMove)="onDragMove($event)" (koDragStart)="onDragStart($event)"
(koDragEnd)="onDragEnd($event)" [config]="{
radius: 120,
fill: 'blue',
stroke: 'black',
strokeWidth: 4,
x: 0,
y: 0
}"></ko-circle>
It allows to capture all drag events. Reference.
<ko-circle koTransform (koTranform)="onTranform($event)" (koTranformStart)="onTranformStart($event)"
(koTransformEnd)="onTranformEnd($event)" [config]="{
radius: 120,
fill: 'blue',
stroke: 'black',
strokeWidth: 4,
x: 0,
y: 0
}"></ko-circle>
It allows to capture all transform events. Reference.
ko-layers
provides you these output:
(onNewItem)
: when a newShape
orLayer
is added to the current layer. Argument: theShape | Layer
added.(beforeUpdate)
(afterUpdate)
: called before/after the layers gets updated. Argument:Stage
. Useful to use the underlying KonvaJS API on the passed argument.
ko-layers
provides you these output:
(onNewLayer)
: when a newLayer
is added to the current layer. Argument: theLayer
added.(beforeUpdate)
(afterUpdate)
: called before/after the layers gets updated. Argument:Layer
. Useful to use the underlying KonvaJS API on the passed argument.
ko-nestable
(all basic shapes) provides you these output:
(beforeUpdate)
(afterUpdate)
: called before/after the layers gets updated. Argument:KoNestableNode
. Useful to use the underlying KonvaJS API on the passed argument and modifying directly the Konva Node.
Contributing is quite simple: in order to complete coverage of the KonvaJS API we have to add more shapes.
To add more "simple" shapes take a look to the ./projects/ngx-konva/src/lib/ko-shape.component.ts
component:
- Add the new selector
- Update the
ko-nestable.ts
types - Check if the default configuration handling is fine
If you need to handle children inside the new component or create more complex shapes please create a specific component for that. Extend the KoNestable
class for each component that should be nestable inside a Layer and provide the getKoItem
to return the underlying shape. By doing that KoNestable
will take care of adding and destroying the Shape instances your component will use. Again, take a look to KoShapeComponent
to see an example.
In order to add new event listeners to the shapes see ko-hover.directive.ts
as an example of an event listener directive.
See /docs for full API Documentation.