LoginSignup
0

More than 1 year has passed since last update.

NCMBとFramework7を使ったギャラリーコンポーネントの紹介と使い方

Last updated at Posted at 2022-02-18

NCMBはモバイルアプリ開発におけるバックエンド機能(認証、データストア、ファイルストア、プッシュ通知など)を提供しています。バックエンドなのでAPIベースで利用するのが基本で、UI(アプリ側)は各自で開発する仕組みになっています。

現在、数多くのアプリが存在し、その中には定番とも言える機能があります。そうした定番機能を各フレームワークごとに実装しておくことで、再利用性高くNCMBが利用できるかと思います。

今回はFramework7で作った写真ギャラリーコンポーネントを紹介します。Monacaアプリでも利用可能です。

実際に動いているところはこちらです。

小さくて解像度が悪いですがGIFだとこんな感じ。

gallery Resized.gif

UIについて

コンポーネントは1つのHTMLだけで実装されているのが特徴です。そのため、基本的には以下の方法で導入・利用ができます。

  1. NCMB SDKの読み込み
  2. NCMBのキーの取得
  3. NCMBの初期化
  4. ルーティングの設定
  5. ギャラリーUI(HTML)を配置

用意されている画面(機能)は次の通りです。

写真一覧の表示

FireShot Capture 068 - Gallery - localhost.jpg

NCMBのファイルストアに保存されている写真を一覧表示します。

写真ブラウザー

FireShot Capture 069 - 20220217205910 Gallery - localhost.jpg

タップした写真を拡大表示します。別な写真への切り替えもできます。

必要なライブラリ・SDKの読み込み

今回利用しているライブラリ・SDKは次の通りです。

  • NCMB JavaScript SDK

これらを www/index.html で読み込みます。

<script src="js/ncmb.min.js"></script>

必要なキー・トークンの取得

NCMBのアプリケーションキーとクライアントキーを取得します。

NCMBの初期化

www/js/app.js にてNCMBを初期化します。今回は www/js/config.json というファイルにキーを記述しているので、以下のように読み込みを行っています。

const $ = Dom7;
(async () => {
  const device = Framework7.getDevice();
    // 設定ファイルの読み込み
  const config = await (await fetch('./js/config.json')).json();
    // NCMBの初期化
  window.ncmb = new NCMB(config.applicationKey, config.clientKey);

  // Framework7の初期化
  window.app = new Framework7({
    name: 'NCMB Notice',
    theme: 'auto',
    el: '#app',
    id: 'com.nifcloud.mbaas.map',
    store: store,
    routes: routes,
    input: {
      scrollIntoViewOnFocus: device.cordova && !device.electron,
      scrollIntoViewCentered: device.cordova && !device.electron,
    },
    statusbar: {
      iosOverlaysWebView: true,
      androidOverlaysWebView: false,
    },
    on: {
      init: function () {
        if (this.device.cordova) {
          cordovaApp.init(this);
        }
      },
    },
  });
})();

ファイルストアの公開設定

NCMBの管理画面にて、ファイルストアのHTTPS公開設定を有効にします。これでファイルストアにアップロードした写真に対してHTTPS経由でアクセスできるようになります(キーが不要になります)。

FireShot Capture 066 - Gallery - localhost.jpg

ルーティングの設定

今回は最低限のルーティングを設定しています( www/js/routes.js )。 /gallery/:name (nameはファイル名のプリフィックス) でギャラリーコンポーネントを表示します。


var routes = [
  {
    path: '/',
    url: './index.html',
  },
  {
    path: '/gallery/:name',
    componentUrl: './pages/gallery.html',
  },
  {
    path: '(.*)',
    url: './pages/404.html',
  },
];

www/index.html/gallery/cat を最初に表示します。この場合、ファイル名が cat で始まっている写真を表示します。

<div id="app">
    <!-- Your main view, should have "view-main" class -->
    <div class="view view-init safe-areas" data-url="/gallery/cat">
    </div>
</div>

ギャラリーUI(HTML)を配置

後は gallery.html をダウンロードして、www/pages/gallery.html に配置するだけです。

写真のアップロード

image.png

任意の写真をアップロードします。今回はキャットボックスから警戒する猫の写真素材 - ぱくたそより猫の画像をお借りしています。写真の名前は cat-〜.jpg といった形に統一しています。

アプリIDの取得

NCMBではHTTPSアクセスする際に次のようなURLでアクセスします。

https://mbaas.api.nifcloud.com/2013-09-01/applications/MKpbJPxaTIU5m1nW/publicFiles/cat-13.jpg

この時の MKpbJPxaTIU5m1nW はNCMBのアプリによって異なります(これをアプリIDと呼びます)。このアプリIDは管理画面のURLでわかります。

https://console.mbaas.nifcloud.com/#/applications/MKpbJPxaTIU5m1nW/file

この時の MKpbJPxaTIU5m1nW がアプリIDです。

ギャラリーUIについて

ギャラリーUIの内容は次のようになります。実装はコメントを参照してください。 YOUR_APP_ID は自分のアプリIDに書き換えてください。 /assets/images/blank.pngこちらよりダウンロードできます。

<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner sliding">
        <div class="title">フォトギャラリー</div>
      </div>
    </div>
    <div class="page-content">
      <div class="block gallery">
        <div class="row no-gap">
          ${ photos.map(photo => $h`
            <div class="col-25">
              <img src="${photo}" class="photo" @load=${load} @click=${show} />
            </div>
          `)}
        </div>
      </div>
    </div>
  </div>
</template>
<style>
  .gallery {
    display: none;
  }
  .photo {
    width: 100%;
    object-fit: cover;
  }
</style>
<script>
  export default function (props, {$f7, $onMounted, $update }) {
    const prefix = `${props.name}`; // 表示対象のファイル名(前方一致)
    const appId = 'YOUR_APP_ID'; // アプリID
    const blankPhoto = '/assets/images/blank.png'; // グリッドで余った部分の埋め合わせよう画像のパス
    const photos = []; // 取得した画像のURLを入れる変数
    let browser; // フォトブラウザオブジェクト
    let loadCount = 0; // 読み込み完了した画像の数
    $onMounted(async () => {
      reset();
      // ローディングアイコンを表示
      app.preloader.show();
      // 写真を取得します
      const files = await getPhotos();
      // ファイルを写真に変換します
      fileToPhoto(files);
      // フォトブラウザオブジェクトを作成します
      browser = $f7.photoBrowser.create({
        photos: photos.filter(photo => photo !== blankPhoto)
      });
      // 表示を更新
      $update();
      // ローディングを消します
      app.preloader.hide();
    });

    const reset = () => {
      // ギャラリーを一度非表示にします
      $('.gallery').hide();
      // 読み込み完了画像カウントのリセット
      loadCount = 0;
    }

    // ファイルを写真に変換します
    const fileToPhoto = (files) => {
      // 写真のファイル名から公開アクセス用URLに変換します
      files.forEach(file => {
        photos.push(`https://mbaas.api.nifcloud.com/2013-09-01/applications/${appId}/publicFiles/${file.fileName}`)
      });
      // グリッドの足りない分を空白の写真で埋め合わせます
      for (let i = 0; i < files.length % 4; i++) {
        photos.push(blankPhoto);
      }
    }

    // 画像が読み込まれると呼ばれる関数です
    const load = (e) => {
      // 読み込み完了画像のカウンターを1上げます
      loadCount += 1;
      // 全画像が読み込み終わるまで待ちます
      if (loadCount < photos.length) return;
      // 画像の幅を取得
      const width = $('.photo').width();
      // 全画像の高さを幅と同じ(正方形)にします
      $('.photo').css('height', `${width}px`);
      // ギャラリーを表示します
      $('.gallery').show();
    };

        // フォトブラウザで写真を表示します
    const show = (e) => {
      const photo = $(e.target).attr('src');
      const index = photos.indexOf(photo);
      if (photo === blankPhoto) return;
      browser.open(index);
    }

        // NCMBから写真を取得します
    const getPhotos = () => {
      return ncmb.File
        .regularExpressionTo('fileName', `${prefix}.*`)
        .limit(100)
        .fetchAll();
    }
    return $render;
  }
</script>

工夫したポイント

画像を正方形のグリッドで表示する機能がFramework7標準では用意されていないので、実装しています。画像のローディングをカウントして、全画像が読み込み終わったタイミングで幅を決定しています。

また、高さを決めるまではギャラリーを非表示にしています。もし表示すると、次のようになってHTMLっぽさが出てしまいます。

before.gif

高さを決定してから表示するとこんな感じです。

after.gif

カスタマイズ

たとえばギャラリーが複数あるならば dog-〜.jpg と名前をつけてアップロードして、HTML側でも /gallery/god にアクセスすれば良いでしょう。

まとめ

ギャラリーコンポーネントを使えばアプリの中で写真一覧を実装するのがとても簡単に実現できます。ぜひお試しください!

mBaaSでサーバー開発不要! | ニフクラ mobile backend

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0