JavaScript Library – PhotoSwipe

效果

 

前言

以前用過 lightbox2 和 fancyapps.

lightbox2 已經沒有維護了.

fancyapps 改版好多次了. v2, v3 現在 v4 已經開始收費了.

PhotoSwipe 目前最火, 下載量最大. 今年三月才推出新版. 雖然還沒有用 TypeScript 重寫, 但至少是 ES Module 也有 .d.ts 了. 算有跟着時代走.

還有一個叫 lightGallery.js 也是要付費的.

 

參考

官網 Docs – photoswipe.com

 

Get Started

我這裏用 esbuild + Yarn classic 做 demo.

安裝

yarn add photoswipe

它自帶 .d.ts 所以不需要另外安裝 @types 了.

HTML 引入 CSS

因爲沒有用 bundle tools 所以直接從 node_module 拉出來就好.

<link
  rel="stylesheet"
  href="./node_modules/photoswipe/dist/photoswipe.css"
/>

HTML Data Elements

    <div
      class="pswp-gallery pswp-gallery--single-column"
      id="gallery--getting-started"
    >
      <a
        href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/2/img-2500.jpg"
        data-pswp-width="1669"
        data-pswp-height="2500"
        target="_blank"
      >
        <img
          src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/2/img-200.jpg"
          alt=""
        />
      </a>
      <!-- cropped thumbnail: -->
      <a
        href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/7/img-2500.jpg"
        data-pswp-width="1875"
        data-pswp-height="2500"
        data-cropped="true"
        target="_blank"
      >
        <img
          src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/7/img-200.jpg"
          alt=""
        />
        Cropped
      </a>
      <!-- data-pswp-src with custom URL in href -->
      <a
        href="https://unsplash.com"
        data-pswp-src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/3/img-2500.jpg"
        data-pswp-width="2500"
        data-pswp-height="1666"
        target="_blank"
      >
        <img
          src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/3/img-200.jpg"
          alt=""
        />
      </a>
      <!-- Without thumbnail: -->
      <a
        href="http://example.com"
        data-pswp-src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/5/img-2500.jpg"
        data-pswp-width="2500"
        data-pswp-height="1668"
        target="_blank"
      >
        No thumbnail
      </a>
      <!-- wrapped with any element: -->
      <div>
        <a
          href="https://cdn.photoswipe.com/photoswipe-demo-images/photos/6/img-2500.jpg"
          data-pswp-width="2500"
          data-pswp-height="1667"
          target="_blank"
        >
          <img
            src="https://cdn.photoswipe.com/photoswipe-demo-images/photos/6/img-200.jpg"
            alt=""
          />
        </a>
      </div>
    </div>
View Code

結構

首先是一個 container 裏面包含了所有要展現在 modal 裏的圖片. 接着就是每一個圖片 data 了.

最基本的 data 需要有 width, height, src 三個屬性值. 

這個是一種用 HTML provide data 的手法, 它還有一種是直接用 JS without HTML 的手法. 下面會講到.

JavaScript

import PhotoSwipeLightbox from 'photoswipe/lightbox';

const lightbox = new PhotoSwipeLightbox({
  gallery: '#gallery--getting-started',
  children: 'a',
  pswpModule: () => import('photoswipe'),
});
lightbox.init();

photoswipe/lightbox 和 photoswipe 是分開的 src, 目的是減少第一次加載的重量, photoswipe/lightbox 是立刻加載, photoswipe 則是在點擊後纔去加載.

PhotoSwipeLightbox 初始化後會去 select HTML 然後獲取到 data sources, 這個 data sources 也可以直接通過 JS provide 哦. 下面會講到.

TypeScript Issue

目前有一個 TypeScript Issue, 雖然例子是 Angular 但其實只要你用 TypeScript 都會遇到的. 沒辦法對這類 library 來說最少還需要 2 年纔會完全擁抱 TypeScript 的.

解決方法是定義一個 ptotoswipe.d.ts 就可以了. 

declare module 'photoswipe';
declare module 'photoswipe/lightbox';

 

How PhotoSwipe Work?

作爲一個 Library, 我覺得 PhotoSwipe 設計的很好. 它沒有封裝許多上層的功能, 反而是給出了許多例子去實現這些功能. 

比如 download,  fullscreen, caption, WebP

這樣可以確保 Library 足夠輕. 維護升級就相對輕鬆. 相對的, 對普羅大衆來說可能就需要二次開發了. 但這個 trade-off 還是很值得學習的.

下面我們來看看它的幾個重要接口.

 

1. Data Sources

參考: Docs – Data Sources

上面有提到, data sources 就是 without HTML. 直接通過 JS provide data.

因爲 PhotoSwipe 的主要功能就是做 Modal 開啓後的 gallery 遊覽. 其實只要有 data 就可以了. 開啓 Modal 之前的圖片並不在它的範圍內.

首先是設定 options, 裏面包含 dataSources

然後 import module, 最後通過 loadAndOpen 打開 Modal Gallery

 

2. addFilter

參考: Custom Content in Slides

PhotoSwipe 拿到 data sources 以後就要去 build modal gallery 了. 這時它提供了一些攔截接口.

你可以理解爲 pipe 或者 middleware.

這 2 招就非常 customize. 

1. numItems 直接修改了 data sources 的 length. 那麼 loop 就多了

2. itemData, 可以改寫輸出的內容. 它直接給了一個 raw HTML.

整個就是無中生有, 動態的創建了 data sources. 非常靈活.

在一個例子 WebP

把 HTML dataset 的屬性傳入 itemData 中

在 contentLoadImage 的時候偷龍轉風換成 <picture>

最後輸出做好的 picture image

它的概念就是攔截然後替換輸出.

 

其它 Customize

1. 增加操作按鈕 e.g. download, autoplay : 

參考: Adding UI elements, Methods 

 

2. 換 Theme

Styling PhotoSwipe

 

3. video

direct support issue

實現 example

雖然沒有直接支持, 但是可以通過類似 WebP 的方法做到

 

4. thumbnails and video

The Best Pop-up Galleries for Photography

這篇文章有提到, PhotoSwipe 和 lightGallery.js (要錢的) 的主要區別. 雖然是 2017 年的文章.

PhotoSwipe 缺失的主要功能是支持 video 和 thumbnials (開啓 modal gallery 之後有一個 thumbnials list 讓用戶切換)

但就如上面提到的可以通過 Customize 的方式去實現. thumbnials list 的實現類似 Adding Navigation Indicator (bullets)

 

總結

整體使用體驗還是很不錯的, 如果沒有特別要求基本上算是開箱即用了. 個人覺得如果有支持 video 那就更好了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章