Ngxa 🚀
So excited to announce another one open source contribution of me. With purpose of helping me and anyone else on using Angular Animations.
Animations are one of the essential UI trends of any modern website/application, they create the effect of real “live” communication between users and the system.
So to build animations easy and reusing single style code I created Ngxa.
Ngxa library helps to build animations easy in angular apps based on Angular Animations
Easy builder, Dynamically, Reusable
Utility functions based on Animate.css styles with the power of ngxa library
Reusing single style code functions with different configurations
Quick Links
Demo ~ Documentation ~ Npm Package
Getting Started
Installation
npm i ngxa --save
Usage
import { roll } from 'ngxa';
@Component({
animations: [
roll({direction:'In'}), // rollIn
roll({direction:'Out'}) // rollOut
]
})
Example Of Building Trigger
Building animation trigger by using buildTrigger function from ngxa
import {animate, animation, AnimationTriggerMetadata, keyframes, style} from "@angular/animations";
import {AnimationConfig} from "ngxa/common";
import {buildTrigger} from "ngxa/base";
const FadeKeyFrames: AnimationKeyframesSequenceMetadata = keyframes([
style({opacity: 0, offset: 0}),
style({opacity: 1, offset: 1}),
]);
const FadeAnimation: AnimationReferenceMetadata = animation( animate('{{timings}}', FadeKeyFrames));
export const fade = (animationConfig?: Partial<AnimationConfig>): AnimationTriggerMetadata => {
return buildTrigger({
triggerName: (animationConfig && animationConfig.triggerName) || 'fade',
transitions: {
animationReferenceMetadata: FadeAnimation,
animationConfig,
animationOptions: {params: {timings: '500ms'}}
},
states: []
});
};
Now the trigger can be reused anywhere we want just by importing it and Including into animations property in component decorator.
The trigger function accept an optional configuration parameter to overwrite default AnimationConfig.
import {fade} from "./path";
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
animations: [
// use fadeAnimation and overwrite optional configs
fade({timings:'0.3s', stateChangeExpressions: [':enter', '0 => 1'], triggerName: 'fadeAnimation'} )
]
})
Using Animation in component's Template
<span [@fadeAnimation]="state">Fade Me</span>
Or with dynamic params
<span [@fadeAnimation]="{value:state,params:{timings:'0.3s'}}">Fade Me</span>
Common Configuration Interfaces
export interface AnimationConfig{
triggerName: string;
stateChangeExpressions: string | string[];
delay: string;
timings: string | number;
nestedAnimations: NestedAnimationsType;
}
export interface TransitionConfig{
animationReferenceMetadata: AnimationReferenceMetadata;
animationConfig?: Partial<AnimationConfig>;
animationOptions?: AnimationOptions | null;
}
export interface BuildTriggerConfig{
triggerName: string;
transitions: TransitionConfig | TransitionConfig[];
states?: AnimationStateMetadata | AnimationStateMetadata[],
}
If needed to add specific configaration properties based on each style, we should create a new interface and extend AnimationConfig to include all necessary properties
import {AnimationConfig} from "./ngxa/common";
interface RotateInConfig extends AnimationConfig{
degrees: number;
direction: RotateInAnimationDirection;
}
Utility functions Based On Animate.css Styles
Each style offers two functions, building trigger and building transition
Triggers
Can be reused for single style with different configurations
import {
bounce, flash, pulse, rubberBand, shake, headShake, swing, tada, wobble, jello, heartBeat,
backIn, backOut, bounceIn, bounceOut, fadeIn, fadeOut, flip, flipIn, flipOut,
lightspeedIn, lightspeedOut, rotateIn, rotateOut, hinge, jackInTheBox, roll, zoomIn, zoomOut, slideIn, slideOut
} from "./ngxa";
Let's take on consideration reusing zoomIn function on multiple directions such as: zoomInUp, zoomInDown, zoomInLeft, zoomInRight
import {zoomIn} from "./ngxa";
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
animations:[
zoomIn(),
zoomIn({direction: 'Up', stateChangeExpressions: ':enter, 0 => 1', translate: '200px'}),
zoomIn({direction: 'Down', stateChangeExpressions: [':enter','out => in'], translate: '500px'}),
zoomIn({direction: 'Left', translate: '300px', nestedAnimations:'parallel'}),
zoomIn({direction: 'Right', timings:'1s', triggerName:'customZoomInRight'}),
]
})
<div [@zoomIn]>
<span>ZoomIn Me</span>
</div>
<div [@zoomInUp]>
<span>ZoomInUp Me</span>
</div>
<div [@zoomInDown]>
<span>ZoomInDown Me</span>
</div>
<div [@zoomInLeft]>
<span>ZoomInLeft Me</span>
</div>
<div [@customZoomInRight]>
<span>ZoomInRight Me</span>
</div>
Using it with dynamic params and state
<div [@zoomInDown]="{value:state,params:{timings:'1s', delay:'0ms', translate:'2000px'}}">
<span>ZoomInDown Me</span>
</div>
<button mat-raised-button (click)="onAnimateIt()">Animate It</button>
onAnimateIt event handler
state: string = 'out';
onAnimateIt(): void{
this.state = 'out';
setTimeout(()=> {
this.state = 'in';
},1)
}
Transitions
can be included into other triggers with different configurations
import {
bounceTransition, flashTransition, pulseTransition, rubberBandTransition, shakeTransition, headShakeTransition,
swingTransition, tadaTransition, wobbleTransition, jelloTransition, heartBeatTransition,
backInTransition, backOutTransition, bounceInTransition, bounceOutTransition,
fadeInTransition, fadeOutTransition, flipInTransition, flipOutTransition, flipTransition,
lightspeedInTransition, lightspeedOutTransition, rotateInTransition, rotateOutTransition,
hingeTransition, jackInTheBoxTransition, rollTransition, zoomInTransition, zoomOutTransition,
slideInTransition, slideOutTransition,
} from "./ngxa";
Creating a trigger with multiple styles by using transition functions
export function attentionsAndBounceInStyles(config?: Partial<AnimationConfig>): AnimationTriggerMetadata {
return buildTrigger(
{
triggerName: (config && config.triggerName) || 'animations',
transitions: [
swingTransition({stateChangeExpressions: '* => swing'}),
bounceTransition({stateChangeExpressions: '* => bounce'}),
flashTransition({stateChangeExpressions: '* => flash'}),
headShakeTransition({stateChangeExpressions: '* => headShake'}),
heartBeatTransition({stateChangeExpressions: '* => heartBeat'}),
jelloTransition({stateChangeExpressions: '* => jello'}),
pulseTransition({stateChangeExpressions: '* => pulse'}),
rubberBandTransition({stateChangeExpressions: '* => rubberBand'}),
shakeTransition({stateChangeExpressions: '* => shake'}),
tadaTransition({stateChangeExpressions: '* => tada'}),
wobbleTransition({stateChangeExpressions: '* => wobble'}),
// bounce in transition on different directions
bounceInTransition({stateChangeExpressions: '* => bounceIn'}),
bounceInTransition({stateChangeExpressions: '* => bounceInUp', direction: 'Up'}),
bounceInTransition({stateChangeExpressions: '* => bounceInDown', direction: 'Down'}),
bounceInTransition({stateChangeExpressions: '* => bounceInLeft', direction: 'Left'}),
bounceInTransition({stateChangeExpressions: '* => bounceInRight', direction: 'Right'}),
]
}
)
}
Stagger Nested Animations
To fire animations into a list can be used staggerNestedAnimations function as a parent animation
import {swing, zoomIn, staggerNestedAnimations} from "./ngxa";
@Component({
selector: 'app-description',
templateUrl: './description.component.html',
styleUrls: ['./description.component.scss'],
animations: [
zoomIn({stateChangeExpressions:':enter, 0 => 1', timings:'1s', direction: 'Down'}),
swing({stateChangeExpressions:':enter, 0 => 1'}),
staggerNestedAnimations({timings:'300ms', stateChangeExpressions:':enter, 0 => 1'})
]
})
export class DescriptionComponent{
status: boolean = true;
onAnimateIt() {
this.status = false;
setTimeout(() => {
this.status = true;
}, 1);
}
}
<div [@staggerNestedAnimations]="status">
<div [@zoomInDown]="status">
<span>Angular Animations Wrapper</span>
</div>
<div [@zoomInDown]="status">
<div [@swing]="{value:status, params:{timings:'1500ms'}}">
<span>Easy Builder, Dynamically, Reusable And Different Direction On Single Base Code</span>
</div>
<span>This wrapper helps you to implement animations easy in your angular application</span>
</div>
<button [@zoomInDown]="status" (click)="onAnimateIt()" >
Animate It
</button>
</div>
That's all for now 👋🏼
Please file issues and pull requests against that Repo, let's improve it and add more futures together.
I hope this package will be helpful for your current and future projects to implement Animations.
If it looks helpful for you, please like and share to help others get knowing about it.
Thanks for reading, let me know your opinion, it's worth a lot!
Top comments (2)
this looks amazing, has a lot of potential
many thanks Oliver, happy to hear that.