Animations
Hosanna UI offers three complementary animation layers. Start simple, then move up as you need more power.
Aggregate View Transitions
- Screen-level transitions for
NavController/TabController(e.g., Fade, Simple). - Configured via
app.config.jsonkeys; optionally override per call. - Best for navigating between screens; keeps focus and lifecycle correct.
See: Aggregate View Transitions
ViewJsonAnimator (low-level)
- Fast renderer-field tweening using JSON maps (many nodes at once).
- Ideal for simple property animations where you control precise fields.
- Pair with
ViewAnimatorfor a single renderer.
See: ViewJsonAnimator
HosannaViewAnimator (high-level)
- State-driven animations across a view subtree using logical state keys.
- Automatically maps logical fields to renderer updates and persists final state.
- Best for orchestrated UI effects spanning multiple views.
See: HosannaViewAnimator
Ui And Interaction Animations
@view('UiAndInteractionAnimations')
export class UiAndInteractionAnimationsView extends BaseExampleScreenView<UiAndInteractionAnimationsState> {
protected getViews(): ViewStruct<ViewState>[] {
// --- edit below ---
return [
VGroup([
// Example 1: Move and color change animation
VGroup([
Button({
id: 'moveButton',
text: 'Click to move',
width: 400,
height: 50,
})
.onClick(this.onMoveButtonClick.bind(this))
.isInitialFocus(),
AnimatedRectangle({
id: 'moveRect',
width: 100,
height: 100,
color: '#00FF00',
})
]).itemSpacing(30),
Spacer({ height: 30 }),
// Example 2: Size animation
VGroup([
Button({
id: 'sizeButton',
text: 'Click to animate size',
width: 400,
height: 50,
})
.onClick(this.onSizeButtonClick.bind(this)),
AnimatedRectangle({
id: 'sizeRect',
width: 100,
height: 100,
color: '#0000FF',
})
]).itemSpacing(30)
,
])
.translation([50, 50])
.itemSpacing(20)
];
// --- edit above ---
}
private onMoveButtonClick() {
const rect = this.getSubView<AnimatedRectangleView>('moveRect');
if (rect) {
rect.animateTo({
translation: [400, 0],
color: '#FF00FF'
}, 1500, { reverse: true });
}
}
private onSizeButtonClick() {
const rect = this.getSubView<AnimatedRectangleView>('sizeRect');
if (rect) {
rect.animateTo({
width: 200,
height: 200
}, 1000, { reverse: true });
}
}
}