スマレジエンジニアyushiのブログ

スマレジエンジニアのブログ

【プロフィールページ改修 第11回】写真表示の左右移動

久しぶりに、プロフィールページを作成していきます。

プロフィールページ カテゴリーの記事一覧 - スマレジエンジニアyushiのブログ

技術スタックは下記の通りです。

  • nuxt.js
  • SCSS
  • Tailwind CSS

今回は、画像表示時に左右移動できるようにします。

方針

前回、写真ビューを作成しました。

現在の仕様だと、複数画像を開くためにいちいち写真ビューを閉じる必要があります。

そこで、左右移動ボタンを設置し、写真ビュー上で表示する写真を切り替えられるようにしたいです。

スクリーンショット

完成品のスクショです。

作成方法はこの後紹介します。

ボタンの設置

ボタンを設置します。左端・右端の写真表示時には、左・右のボタンを表示しないようにしています。
クリックイベントを上位コンポーネントにemitします。

<template>
    ...
      <button
        class="arrow-button left-arrow"
        :class="{ hasNext: hasLeft }"
        @click.stop="$emit('go-left')"
      />
      <img class="image" :src="filePath" @click.stop />
      <button
        class="arrow-button right-arrow"
        :class="{ hasNext: hasRight }"
        @click.stop="$emit('go-right')"
      />
    ...
</template>

CSSも更新します。

矢印表示は、擬似要素(after)で表示します。 スマホサイズの場合は矢印を表示せず、写真の左の方をタップすれば左の写真に移動、という様にします。

.image {
  width: 90%;
  height: 90%;
  max-width: calc(100% - 150px);
  max-height: 90%;
  object-fit: contain;
  @media (max-width: $mobile-max-width) {
    max-width: 100%;
  }
}
$arrow-color: #aaa;
$arrow-size: 15px;
$arrow-btn-size: 50px;
.arrow-button {
  position: relative;
  background-color: #333;
  width: $arrow-btn-size;
  height: $arrow-btn-size;
  border-radius: 50%;
  opacity: 0;
  &::after {
    content: '';
    position: absolute;
    top: calc($arrow-btn-size / 2 - $arrow-size);
    border-top: $arrow-size solid transparent;
    border-bottom: $arrow-size solid transparent;
  }
  &.left-arrow::after {
    border-right: $arrow-size solid $arrow-color;
    left: calc($arrow-btn-size / 2 - $arrow-size * 2 / 3);
  }
  &.right-arrow::after {
    border-left: $arrow-size solid $arrow-color;
    right: calc($arrow-btn-size / 2 - $arrow-size * 2 / 3);
  }
  &.hasNext {
    opacity: 0.5;
  }
  @media (max-width: $mobile-max-width) {
    position: fixed;
    top: 0;
    width: 100px;
    height: 100%;
    border-radius: 0;
    &::after {
      display: none;
    }
    &.left-arrow {
      left: 0;
    }
    &.right-arrow {
      right: 0;
    }
    &.hasNext {
      opacity: 0;
    }
  }
}

コンポーネントでの状態管理

前回は写真の選択状態をファイルパスで行っていましたが、index(配列内の行番号)で管理するように変更します。

  data() {
    return {
-      selected: null,
+      selectedIndex: null,
    }

左右移動用のメソッドを用意します。

methods: {
    go(val) {
      if (!this.hasPhoto(this.selectedIndex + val)) {
        return
      }
      this.selectedIndex += val
    },
    hasPhoto(val) {
      return val >= 0 && val < this.photos.length
    },
}

写真ビューコンポーネントのprops・event管理を更新します。

    <LightBox
      :file-path="selectedPath"
      :has-left="hasPhoto(selectedIndex !== null && selectedIndex - 1)"
      :has-right="hasPhoto(selectedIndex !== null && selectedIndex + 1)"
      @close="clearSelection"
      @go-left="go(-1)"
      @go-right="go(1)"
    />

Pull Request

画像表示時に左右移動できるようにする by nek0meshi · Pull Request #22 · nek0meshi/profile · GitHub

あとがき

最近はdominionにハマっています。
開発チームでもオンラインで遊びました。