Laravel11 & Vue.js3でAmazonS3の画像をLightbox風に表示

コード

Laravel11とVue.js3を組み合わせてAmazon S3の画像をLightbox風に表示します。

とてもシンプルなLightbox実装方法で、外部ライブラリは不要です。

※ users->profile_imageに保存された画像を取得する設定です。

1.「署名付きURL」を取得する設定

Models/User.php

use Illuminate\Support\Facades\Storage;

class User extends Authenticatable
{
    // s3 署名付きURLを取得するメソッド
    public function getFileUrl($filePath)
    {
        if ($filePath) {
            return Storage::disk('s3')->temporaryUrl(
                $filePath, now()->addMinutes(15)
            );
        }
        return null;
    }
}

LaravelのUserモデルにgetProfileImageUrlAttributeというメソッドを追加し、Amazon S3上に保存されたユーザーのプロフィール画像の「署名付きURL」を取得する方法を提供しています。

事前の設定、画像のアップロードなどはこちら

2.画像を表示

xxx.blade.php

<style>
.lightbox-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.9);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
}
.lightbox-image {
    max-width: 90%;
    max-height: 90vh;
    object-fit: contain;
}
.close-button {
    position: absolute;
    top: 20px;
    right: 20px;
    color: white;
    font-size: 30px;
    cursor: pointer;
}

.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}
</style>

<!-- 画像表示(クリック前) -->
<div style="max-width:150px;">
    <img 
        :src="profileImageUrl"
        alt="Profile Image"
        @click="showLightbox = true"
        style="cursor: pointer; width: 100%;"
        class=""
    >
</div>

<!-- Lightbox(クリック後) -->
<Transition name="fade">
    <div v-if="showLightbox" class="lightbox-overlay" @click="showLightbox = false">
        <span class="close-button">×</span>
        <img :src="profileImageUrl" class="lightbox-image" @click.stop>
    </div>
</Transition>

<!-- S3のセキュリティ設定上、事前に読み込みが必要(Vue.jsで使えるように) -->
<script>
    window.profileImageUrl = @json( $user->getFileUrl($user->profile_image) );

    const { createApp } = Vue;
    createApp({
        data() {
            return {
                showLightbox: false,
                profileImageUrl: window.profileImageUrl || ''
            }
        }
    }).mount('#app');
</script>

シンプルなLightbox構造
Lightbox表示のためのシンプルなCSSスタイルとVueのv-ifディレクティブを活用し、クリックでオーバーレイが表示される仕組みを簡潔に実装しています。これにより、ユーザーは画像をクリックすると大きな表示がされ、さらにクリックで閉じることができるため、使いやすいインターフェースです。

トランジションでのアニメーション効果
Vue.jsの<Transition>タグを利用し、フェードイン・フェードアウトのエフェクトを追加しています。これにより、画像の表示や非表示時に滑らかなアニメーションが加わり、ユーザー体験が向上します。

Amazon S3の画像URLの取得
window.profileImageUrl = @json($user->profile_image_url);を用いて、Laravel側で取得したS3の画像URLをVue.jsコンポーネントで使用できるようにしています。これにより、LaravelからS3のセキュアな画像URLをVue.jsに簡単に渡すことが可能になり、直接Vue.jsに組み込んで表示することができます。

クリックイベントの制御
Lightboxが開いたときに背景のクリックで閉じることができるように@click="showLightbox = false"が設定され、さらに画像自体のクリックを無視するために@click.stopが利用されています。この設定により、ユーザーは操作に混乱することなく、直感的にLightboxを閉じることができます。

レスポンシブデザイン
.lightbox-imagemax-width: 90%max-height: 90vhが設定されており、画面サイズに合わせて画像が自動的に縮小表示されるため、どのデバイスでも適切なサイズで表示されます。