Angular 6+ masonry grid component with CSS animations on scroll.
Demo: https://ng-masonry-grid.stackblitz.io/
Note: If you want angular 5 ng-masonry-grid, use (ng-masonry-angular5) branch for the same.
First install Peer dependencies
$ npm install masonry-layout imagesloaded --save
To install ng-masonry-grid library, run:
$ npm install ng-masonry-grid --save
You can import NgMasonryGridModule
Module in any Angular application AppModule
as shown below:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
// Import NgMasonryGridModule
import { NgMasonryGridModule } from 'ng-masonry-grid';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
// Specify NgMasonryGrid library as an import
NgMasonryGridModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Once NgMasonryGridModule Module is imported, you can use its components and directives in your Angular application:
// In your Angular Component
@Component({
selector: 'app-root',
template: `
<!-- You can now use ng-masonry-grid component in app.component.html -->
<!-- Masonry grid Container -->
<ng-masonry-grid
[masonryOptions]="{ transitionDuration: '0.8s', gutter: 5 }"
[useAnimation]="true"
[useImagesLoaded]="true"
[scrollAnimationOptions]="{ animationEffect: 'effect-4', minDuration : 0.4, maxDuration : 0.7 }">
<!-- Masonry Grid Item -->
<ng-masonry-grid-item id="{{'masonry-item-'+i}}" *ngFor="let item of masonryItems; let i = index;" (click)="removeItem($event)">
<!-- Grid Content -->
<img src="some_image.jpg" alt="No image" />
</ng-masonry-grid-item>
</ng-masonry-grid>
`,
styleUrls: ['Path_to/node_modules/ng-masonry-grid/ng-masonry-grid.css'] // point to ng-masonry-grid CSS file (required)
})
Note: 'id' on ng-masonry-grid-item is required for removeItem, removeAllItems functionality
scrollAnimationOptions = {
/* animation effect class will added on ng-masonry-grid-item on scroll, you can choose animation effect class from the predefined list:
["effect-1","effect-2","effect-3","effect-4","effect-5","effect-6","effect-7","effect-8"] or else you can add your own custom class as you wish */
animationEffect: 'effect-1', // String: (default: 'effect-1')
// Integer: Minimum and a maximum duration of the animation
minDuration : 0,
maxDuration : 0,
// The viewportFactor defines how much of the appearing item has to be visible in order to trigger the animation
// if we'd use a value of 0, this would mean that it would add the animation class as soon as the item is in the viewport.
// If we were to use the value of 1, the animation would only be triggered when we see all of the item in the viewport (100% of it)
viewportFactor : 0
}
// or
useAnimation = true; // true/false default: true, default animation options will be applied if you do not provide scrollAnimationOptions
masonryOptions = {
addStatus: 'append', // default: 'append', values from: ['append', 'prepend', 'add'], set status of adding grid items to Masonry
transitionDuration: '0.4s', // Duration of the transition when items change position or appearance, set in a CSS time format. Default: transitionDuration: '0.4s'
...
// More masonry options available in (http://masonry.desandro.com/options.html)
}
// Unloaded images can throw off Masonry layouts and cause item elements to overlap. imagesLoaded plugin resolves this issue.
useImagesLoaded = "true"; // default: false, use true incase if of any images to be loaded in grid items
More masonry options available in Masonry options by David DeSandro
Triggered after a layout and all positioning transitions have completed.
Triggered after an ng-masonry-grid-item element has been removed.
Get an instance of Masonry after intialization, so that you can use all Masonry Methods such as layout(), reloadItems() etc.
<ng-masonry-grid
(onNgMasonryInit)="onNgMasonryInit($event)"
(layoutComplete)="layoutComplete($event)"
(removeComplete)="removeGridItem($event)">
<ng-masonry-grid-item
id="{{'masonry-item-'+i}}"
*ngFor="let item of masonryItems; let i = index;"
(click)="removeItem($event)">
</ng-masonry-grid-item>
</ng-masonry-grid>
import { Masonry, MasonryGridItem } from 'ng-masonry-grid'; // import necessary datatypes
_masonry: Masonry;
masonryItems: any[]; // NgMasonryGrid Grid item list
// Get ng masonry grid instance first
onNgMasonryInit($event: Masonry) {
this._masonry = $event;
}
// Append items to NgMasonryGrid
appendItems() {
if (this._masonry) { // Check if Masonry instance exists
this._masonry.setAddStatus('append'); // set status to 'append'
this.masonryItems.push(...items); // some grid items: items
}
}
// Prepend grid items to NgMasonryGrid
prependItems() {
if (this._masonry) {
// set status to 'prepend' before adding items to NgMasonryGrid otherwise default: 'append' will applied
this._masonry.setAddStatus('prepend');
this.masonryItems.splice(0, 0, ...items);
}
}
// Add items to NgMasonryGrid
addItems() {
if (this._masonry) {
this._masonry.setAddStatus('add'); // set status to 'add'
this.masonryItems.push(...items);
}
}
// Remove selected item from NgMasonryGrid, For example, (click)="removeItem($event)" event binding on grid item
// Note: 'id' on ng-masonry-grid is required to remove actual item from the list
removeItem($event: any) {
if (this._masonry) {
this._masonry.removeItem($event.currentTarget) // removeItem() expects actual DOM (ng-masonry-grid-item element)
.subscribe((item: MasonryGridItem) => { // item: removed grid item DOM from NgMasonryGrid
if (item) {
let id = item.element.getAttribute('id'); // Get id attribute and then find index
let index = id.split('-')[2];
// remove grid item from Masonry binding using index (because actual Masonry items order is different from this.masonryItems items)
this.masonryItems.splice(index, 1);
}
});
}
}
// Remove first item from NgMasonryGrid
removeFirstItem() {
if (this._masonry) {
this._masonry.removeFirstItem()
.subscribe( (item: MasonryGridItem) => {
if (item) {
let id = item.element.getAttribute('id');
let index = id.split('-')[2];
this.masonryItems.splice(index, 1);
}
});
}
}
// Remove all items from NgMasonryGrid
removeAllItems() {
if (this._masonry) {
this._masonry.removeAllItems()
.subscribe( (items: MasonryGridItem) => {
// remove all items from the list
this.masonryItems = [];
});
}
}
// reorder items to original position
// Note: Add masonry option:- horizontalOrder: true
reorderItems() {
if (this._masonry) {
this._masonry.reOrderItems();
}
}
To generate all *.js
, *.d.ts
and *.metadata.json
files:
$ npm run build
To run demo...
- From the ng-masonry-grid/dist directory, create a symlink in the global node_modules directory to the dist directory of ng-masonry-grid:
$ cd dist
$ npm link
- Navigate to ng-masonry-grid/playground directory:
$ cd playground
$ npm link ng-masonry-grid
- Now run the demo (from ng-masonry-grid) directory:
$ npm run demo
This ng-masonry-grid component is created based on Masonry Layout by David DeSandro
MIT © Shailendra Kumar