Angular Integration
First, make sure you installed Interacto and its Angular library.
Interacto Module
In your app.module.ts
file add the InteractoModule
into the imports
array of NgModule
.
Example:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
InteractoModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
This will enable dependency injection and import all the interacto features.
Using Interacto in Angular components
You can inject as constructor parameters Interacto objects into your Angular components: the undo/redo history; and the Bindings
object (the factory that permits the creation of Interacto bindings or access various Interacto data). For example:
public constructor(private undoHistory: UndoHistory, private bindings: Bindings) {
}
These injections are optional. We will see in this section that you can develop your Angular app with it.
Setting a specific undo/redo algorithm for an Angular component
By default, your app shares the same undo/redo linear history to all the Angular components a single. In some cases, you may want to a specific undo/redo history for one Angular component, or you may use another undo algorithm.
Currently we provide two algorithms: the linear one (the standard we use by default); the tree algorithm (that keeps traces of undo/redo branches).
The following example uses the function interactoTreeUndoProviders
we provide for injecting Interacto in this component to use the tree algorithm.
@Component({
selector: 'app-tab-shapes',
templateUrl: './tab-shapes.component.html',
styleUrls: ['./tab-shapes.component.css'],
// This provider is optional. It permits to have a specific Bindings and thus a specific UndoHistory for this
// component. Useful when you want to have different undo histories.
providers: [interactoTreeUndoProviders()]
})
export class TabShapesComponent { ... }
Similarly, to use a specific yet linear history for one component, you can use the method interactoProviders
:
@Component({
selector: 'app-tab-text',
templateUrl: './tab-text.component.html',
styleUrls: ['./tab-text.component.css'],
providers: [interactoProviders()]
})
export class TabTextComponent { ... }
Defining Interacto bindings
You have two ways of defining Interacto bindings in Angular components: using dedicated Interacto directives in the HTML, or by defining bindings in ngAfterViewInit
.
Using Interacto Angular directives
The first way to use Interacto in Angular is to use dedicated Interacto directives. This follows the way developers usually program Angular apps. Using this technique, you do not have to inject any Interacto objects in your component's constructor.
Let us start with a small example:
<button [ioButton]="binderClickEndGame">End game</button>
In the HTML file of a component, we define a button that has the ioButton
directive. This directive points to the method binderClickEndGame
defined in the component class.
// In your component
public binderClickEndGame(binder: PartialButtonBinder): void {
binder
.toProduceAnon(() => this.showEndGame())
.bind();
}
This method binderClickEndGame
takes as argument a partly-configured Interacto binding that you can complete in the method. The user interaction is already selected: ioButton
corresponds to a button interaction. The widget on which the binding will operate is also selected: it is the HTML tag. So there is no need to use the routines usingInteraction
and on
in binderClickEndGame
.
Interacto also provides the HTML element that produced the user interaction as second parameter of the method that creates the Interacto binder, for example:
// in your component
public binderClickEndGame(binder: PartialButtonBinder, button: HTMLButtonElement): void {
binder
.toProduce(() => new AnonCmd(() => this.showEndGame()))
.bind();
}
The parameter's type of the directive method depends on the selected Interacto directive. For example with ioButton
on a button, it is the type returned by buttonBinder()
, so PartialButtonBinder
. Please, refer to the return type of the methods of Bindings
methods.
Here is an exhaustive list of the directives. All Interacto directives start with the io
prefix.
Mouse interactions:
ioClick
for click.PartialPointBinder
as parameter typeioClicks
for clicks.PartialPointsBinder
as parameter typeioDoubleClick
for double click.PartialUpdatePointBinder
as parameter typeioDnd
for DnD.PartialPointSrcTgtBinder
as parameter typeioDragLock
for drag lock.PartialPointSrcTgtBinder
as parameter typeioMousemove
for mouse move.PartialPointBinder
as parameter typeioLongMousedown
for long pressure.PartialUpdatePointBinder
as parameter typeioMousedown
for mouse pressure.PartialPointBinder
as parameter typeioMouseup
for mouse release.PartialPointBinder
as parameter typeioMouseenter
for mouse entering.PartialPointBinder
as parameter typeioMouseleave
for mouse leaving.PartialPointBinder
as parameter type
Touch interactions:
ioLongTouch
for long touch.PartialTouchBinder
as parameter typeioMultiTouch
for multi-touches.PartialMultiTouchBinder
as parameter typeioPan
for panning.PartialMultiTouchBinder
as parameter typeioSwipe
for swiping.PartialMultiTouchBinder
as parameter typeioTap
for tapping.PartialTapBinder
as parameter type
Keyboard interactions:
ioKeydown
for key pressure.PartialKeyBinder
as parameter typeioKeyup
for key release.PartialKeyBinder
as parameter typeioKeysdown
for keys pressures.PartialKeysBinder
as parameter typeioKeyType
for key typing.PartialKeyBinder
as parameter typeioKeysType
for keys typing.PartialKeysBinder
as parameter type
Widget interactions:
ioButton
for buttons (usesbuttonBinder()
,PartialButtonBinder
)ioAnchor
fora
tags (useshyperlinkBinder()
,PartialAnchorBinder
)ioSelect
forselect
tags (usescomboBoxBinder()
,PartialSelectBinder
)ioTextarea
fortextarea
tags (usestextInputBinder()
,PartialTextInputBinder
)ioTextinput
for textinput
tags (usestextInputBinder()
,PartialTextInputBinder
)ioInput
for the following input types:- input radio and checkbox (uses
checkboxBinder()
,PartialInputBinder
) - input color (uses
colorPickerBinder()
,PartialInputBinder
) - input date (uses
dateBinder()
,PartialInputBinder
); - input number (uses
spinnerBinder()
,PartialSpinnerBinder
);
- input radio and checkbox (uses
Undo/redo
For undo and redo, you can add ioUndo
and ioRedo
on specific buttons. These two buttons will then work with the undo history of Interacto. For example:
<button ioUndo>Undo</button>
<button ioRedo>Redo</button>
Dynamic registration on elements
By default, putting an Interacto directive on an HTML element uses the on
routine for registering the element. In some cases on want to use onDynamic
. To do so, you can add the Interacto routine ioOnDynamic
on the same element. For example:
<div ioOnDynamic [ioClick]="eltSelect" />
Passing extra parameters
If you want to pass extra parameters, you have to do as follows:
<div [ioClick] (clickBinder)="binderClickLoad($event, m)" *ngFor="let m of myList">
Play with '{{m}}'
</div>
In this code the directive ioClick
has no value, so that it creates a partial binder and triggers an Angular event with it. This event corresponds to the clickBinder
directive that calls the method binderClickLoad
with as parameters the created partial binder (the event $event
) and additional parameters (here m
). binderClickLoad
now looks like:
// in your component
public binderClickLoad(binder: PartialPointBinder, name: string): void {
...
}
The xxxBinder
directive is proper to the user interaction you use. Here are all these directives. For:
ioClick
:clickBinder
ioClicks
:clicksBinder
ioDoubleClick
:dbleclickBinder
ioDnd
:dndBinder
ioDragLock
:dragLockBinder
ioMousemove
:mousemoveBinder
ioLongMousedown
:longMousedownBinder
ioMousedown
:longTouchBinder
ioMouseup
:ioMouseup
ioMouseenter
:mouseenterBinder
ioMouseleave
:ioMouseleave
ioLongTouch
:longTouchBinder
ioMultiTouch
:multiTouchBinder
ioPan
:panBinder
ioSwipe
:swipeBinder
ioTap
:tapBinder
ioKeydown
:keydownBinder
ioKeyup
:keyupBinder
ioKeysdown
:keysdownBinder
ioKeyType
:keyTypeBinder
ioKeysType
:keysTypeBinder
ioButton
:buttonBinder
ioAnchor
:aBinder
ioSelect
:selectBinder
ioTextarea
:textareaBinder
ioTextinput
:textinputBinder
ioInput
:inputBinder
Using ngAfterViewInit
You can define Interacto bindings without using Interacto directives. To do so your component needs to implements AfterViewInit
to implement the Angular life-cycle method ngAfterViewInit
: after the HTML view being initialized, you can handle its widgets to define Interacto bindings.
Second, you have to inject a Bindings
instance in your component constructor.
Then, you can define Interacto bindings in the ngAfterViewInit
method like this:
ngAfterViewInit(): void {
this.bindings.reciprocalDndBinder(this.appComponent.handle, this.appComponent.spring)
.onDynamic(this.canvas)
.toProduce(i => new MoveRect(i.src.target as SVGRectElement))
...
.bind();
}
Note that this way you need to have your widgets (here this.canvas
) as attributes of your component class. This is the drawback of this may of defining bindings (quite verbose):
@ViewChild('canvas')
private canvas: ElementRef<SVGSVGElement>;
Showing the undo/redo history
In the documentation we illustrate the undo/redo features using two buttons undo
and redo
.
For Angular, we also provide Angular components for displaying in a more sophisticated way the undo/redo history.
This component is called io-linear-history
, and you can use it like in the following example:
<as-split direction="horizontal">
<as-split-area #h [size]="20">
<io-linear-history></io-linear-history>
</as-split-area>
<as-split-area [size]="80">
<textarea [ioTextarea]="writeTextBinder" rows="16" cols="100" value="{{dataService.txt}}"></textarea>
<br/>
<button [ioButton]="clearClicksBinder" class="clearTextButton">Clear text</button>
</as-split-area>
</as-split>