Angular でswiper を使う

はじめに

Angular でswiper を利用する方法をまとめます。
この記事はこちらのQiitaの内容を大いに参考にさせていただいております。
こちらの作者様のwebページもどうやらAngular で書かれており大いに勉強させていただきました。ありがとうございます。

angular swiper
angular swiper

swiper

swiper はMITライセンスで公開されているカルーセルやスライダーを簡単に作成できるライブラリーです。
2019年9月現在約20,000のGithub starを獲得しています。

Angular でswiper を使う

こちらのQiitaの内容をを解説しています。

stackblitz に移植したものを載せておきます。

stackblitz.com

swiper のインストール

swiper をインストールします。

$ npm install --save swiper
$ npm install --save @types/swiper

angular.json でstylesheet を読み込みます。

 〜省略〜
"styles": [
  "src/styles.css",
  "../node_modules/swiper/dist/css/swiper.css"
],
 〜省略〜

swiper を wrapする Component

swiper/swiper.component.ts を以下のように書きます。 hugo とswiper でcarousel を作成する で書来ましたが swiper-container class 内の swiper-slide class がスライドとして振舞うようなcss が当たります。

import { Injectable, Inject, Component, ElementRef, Host, Input } from '@angular/core';
import Swiper from 'swiper';

@Injectable()
@Component({
  selector: 'swiper-container',
  template:
  `<div class="swiper-container">
    <div class="swiper-wrapper">
      <ng-content></ng-content>
    </div>
    <!-- Add Pagination -->
    <div class="swiper-pagination"></div>
    <!-- Add Arrows -->
    <div class="swiper-button-next" *ngIf="pager"></div>
    <div class="swiper-button-prev" *ngIf="pager"></div>

  </div>`
})
export class SwiperContainer {
  @Input() public pager: any;
  @Input() public options: any;

  public swiper: any;
  public showPager: boolean = true;

  constructor(
    @Inject(ElementRef) private elementRef: ElementRef
  ) { }

  public ngOnInit() {
    let options = this.setDefaultOptions({}, this.options);

    const nativeElement = this.elementRef.nativeElement;
    this.swiper = new Swiper(nativeElement.children[0], this.options);
  }

  public update() {
    setTimeout(() => {
      this.swiper.update()
    });
  }

  private setDefaultOptions(dest: any, ...args: any[]) {
    for (let i = arguments.length - 1; i >= 1; i--) {
      let source = arguments[i] || {};
      for (let key in source) {
        if (source.hasOwnProperty(key) && !dest.hasOwnProperty(key)) {
          dest[key] = source[key];
        }
      }
    }
    return dest;
  }
}

@Injectable()
@Component({
  selector: 'swiper-slide',
  template: '<div><ng-content></ng-content></div>'
})
export class SwiperSlide {
  private ele: HTMLElement;

  constructor(
    @Inject(ElementRef) elementRef: ElementRef,
    @Host() @Inject(SwiperContainer) swiper: SwiperContainer
  ) {
    this.ele = elementRef.nativeElement;
    this.ele.classList.add('swiper-slide');
    swiper.update();
  }
}

Component から利用する

app.component.ts から以下のように利用します。
swipeOptions として先ほど作ったswiper/swiper.component.ts に外からオプションの指定が可能です。

import { Component, ViewChild } from '@angular/core';
import { SwiperContainer } from './swiper/swiper.component';

declare var Swiper: any;

@Component({
  selector: 'my-app',
    template: `
    <swiper-container [options]="swipeOptions" [pager]="true" #homeSlide>
      <swiper-slide>
        <img src="https://source.unsplash.com/random/512x512">
      </swiper-slide>
      <swiper-slide>
        <img src="https://source.unsplash.com/random/512x512?nature">
      </swiper-slide>
      <swiper-slide>
        <img src="https://source.unsplash.com/random/512x512?portrait">
      </swiper-slide>
    </swiper-container>
  `,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {
  name = 'Angular with Swiper';
  @ViewChild('homeSlide', {static: true}) public homeSlide: SwiperContainer;

  public swipeOptions = {
    spaceBetween: 0,
    loop: true,
    speed: 1000,
    centeredSlides: true,
    autoplay: {
      delay: 2500,
      disableOnInteraction: false,
    },
    pagination: {
      el: '.swiper-pagination',
      clickable: true,
      type: 'bullets'
    },
    navigation: {
      nextEl: '.swiper-button-next',
      prevEl: '.swiper-button-prev',
    },
  };

  constructor() {
  }

  goToNextPage() {
    this.homeSlide.swiper.slideNext();
  }
}

css は以下のように書きました。
ここはお好みでどうぞ。

.swiper-container {
  width: 100%;
  height: 100%;
}
.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: -webkit-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}

まとめ

Angular でswiper を利用する方法をまとめました。
個人的にあまり Moduleの分割であったり Shared libなどの構成を使ってこなかったのですが、元記事様のサイトはとても効率よく構成されていて勉強になりました。

参考記事