Loading Posts...

Creating a Pinterest Layout with Ionic [v4]

Creating a Pinterest Layout with Ionic [v4]

If you want to create a Pinterest like layout with Ionic 4, you will encounter problems with the default implementation of the grid and a standard column based layout.

In this Quick Win we will implement a real Pinterest grid layout with Ionic using some custom CSS, media queries and even an official animation (borrowed from the Pinterest page).

We will also use a cool API called the Lorem Ipsum for photos so we got some real images for our Pinterest feed!

Getting Started

Because we’ll just build upon basic HTML and CSS stuff we simple need a blank app for testing:

ionic start academyLayout blank

Since we also want to make HTTP request to get some images we also need to add the according module as always to our app/app.module.ts like:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule,
    HttpClientModule],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

That’s all of the preparation!

Implementing the Basic Pinterest Grid

We start by loading images from the API, and we will use pagination which works great with an infinite scroll component.

The only tricking thing is that the information about the next page or result count and number of pages is not inside the body, but passed inside a field of the response header. Therefore, we have to observe the full response of our HTTP GET request and then extract the according field which is called “next”.

Besides that we only fill our array of images or append images if there are already elements in it, so here we go with our app/home/home.page.ts:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  imageList = [];
  nextPage = 'https://picsum.photos/v2/list';

  constructor(private http: HttpClient) {
    this.loadImages();
  }

  loadImages(event?) {
    this.http.get(this.nextPage, { observe: 'response' })
    .subscribe(res => {
      this.nextPage = this.parse_link_header(res.headers.get('Link'))['next'];
      this.imageList = this.imageList.length == 0 ? res.body : [...this.imageList, ...res.body];

      if (event) {
        event.target.complete();
      }
    });
  }

  // https://www.techiediaries.com/angular-httpclient-headers-full-response/
  private parse_link_header(header) {
    if (header.length == 0) {
      return ;
    }

    let parts = header.split(',');
    var links = {};
    parts.forEach( p => {
      let section = p.split(';');
      var url = section[0].replace(/<(.*)>/, '$1').trim();
      var name = section[1].replace(/rel="(.*)"/, '$1').trim();
      links[name] = url;

    });
    return links;
  }  

}

Now we come to the actual Pinterest styling. The problem is, the standard Ionic grid won’t deliver the result you want to see, therefore we have to use our own markup with additional CSS to make things work.

So we can create an iteration based on our imageList and simply use some div elements on which we add styling in the next step. We’ll also add a button in it – and we only want to show it once we hover over a pin!

Of course this is not really working on a mobile device, but chances are you also build for the web and then it’s a great animation and visual appealing behaviour.

At the bottom of the view we put our infinite loading component that will simply trigger our loadImages function now with an event that will be completed once we are done loading images.

Go ahead with the app/home/home.page.html and change it to:


  
    
      Academy Pinterest
    
  




  
Bookmark {{ img.author }}

This will now look like a bunch of garbage in your preview, because we haven’t added any CSS!

The most important part here is right at the beginning, perhaps add the rules one by one to see what’s going on and how they affect your app.

We use the column-count property do define that our view should be divided in different columns, just like you would do inside the standard Ionic grid row/column layout. But we take things a step further and also apply media queries to our rule in order to increase the column count on different screen sizes.

On a small screen we would have 2 columns, while at the biggest breakpoint we have even 5 columns!

Besides that we have some styling to make our collection-item pin more like a real Pinterest pin, and finally additional CSS for hovering over our Pins. Actually the animation is from the Pinterest page, I take no credit in that animation!

But what I added is additional styling for our button – by default it won’t be displayed, but in the hover state we will make it visible.

Now change your app/home/home.page.scss and add all the rules:

.collection {
    @media (max-width: 779px) and (min-width: 0px) {
        column-count: 2;
    }
    @media (max-width: 1039px) and (min-width: 780px) {
        column-count: 3;
    }
    @media (max-width: 1299px) and (min-width: 1040px) {
        column-count: 4;
    }
    @media (min-width: 1300px) {
        column-count: 5;
    }
}

.collection-item {
    display: inline-block;
    padding: 12px 12px 28px 12px;
    border-radius: 12px;
    cursor: zoom-in;
    img {
        border-radius: 12px;
    }
    ion-button {
        display: none;
        position: absolute;
        top: 20px;
    }
}

.collection-item:hover {
    animation: tapAnimation 0.25s cubic-bezier(0.31, 1, 0.34, 1) forwards;
    ion-button {
        display: block;
    }
}

@keyframes tapAnimation {
    0% {
      opacity: 1;
      transform: scale(0.96); }
    100% {
      opacity: 1;
      background: rgba(0, 0, 0, 0.05);
      transform: scale(1);
    } 
}

Now you can scroll through your Pinterest feed and hover all the elements. Note that the images returned from the API are pretty big so don’t worry if the loading takes some time!

One final tip: In order to debug things like the hover state more easily you can simply select the element in your debugging view and directly toggle the hover state to see how it looks then:

That’s actually a lot better then trying to hover and immediately afterwards select the element which is not really working. Not that I have tried of course…

Conclusion

The Pinterest layout in Ionic can be achieved with basic HTML and CSS, but it’s not working out of the box with the standard Grid.

However, the presented approach should give you a good starting point for your next image powered app!

You can also watch a video version of this Quick Win below.

The post Creating a Pinterest Layout with Ionic [v4] appeared first on Ionic Academy.

Get Free Email Updates!

Signup now and receive an email once I publish new content.

I agree to have my personal information transfered to MailChimp ( more information )

I will never give away, trade or sell your email address. You can unsubscribe at any time.

user

The author didnt add any Information to his profile yet

Loading Posts...