画像クリックでフルスクリーン表示するようにした
このブログでは画像を imgur に配置していて記事中ではサムネイルを表示するようにしている。
<figure>
<a href="https://i.imgur.com/WZajJkg.jpg" target="_blank" rel="noopener"
><picture>
<source
type="image/webp"
sizes="(max-width: 320px) 320px, (max-width: 640px) 640px, 640px"
srcset="
https://i.imgur.com/WZajJkgh.webp 1024w,
https://i.imgur.com/WZajJkgl.webp 640w,
https://i.imgur.com/WZajJkgm.webp 320w
"
/>
<img
src="https://i.imgur.com/WZajJkgl.jpg"
alt="image"
loading="lazy"
style=""
onload="this.style={minHeight:'auto'}"
/> </picture
></a>
</figure>
サムネイルは srcset で 幅 1024 までの webp 画像を出し分け、フォールバック用には幅 640 の画像を指定していて、a タグでクリックすると imgur に投稿したオリジナルサイズの 画像 URL を開くようにしている。
オリジナル画像表示できない問題
しかし imgur への画像直リンはうまくいかない。
これが imgur の仕様だし、無料で使ってるから文句も言えないわけだが、でもやっぱりフルサイズ画像を簡単に見たいのでちょっと手を加えることにした。
で、lightbox というかツイッターの画像表示みたいなのを実装した。特にローディング表示も閉じるボタンも無く、クリックすると開き、またクリックすると閉じるだけのシンプルなもの。
やってることはオリジナル画像を css で fixed にして画面いっぱいに表示してるだけだがどうしても JS は必要になる。ただ、あまり記事自体に JS 制御を盛り込みたくないのでこれも以前と同様に Web Component 化して勝手に処理するようにした。
クリックするとフル表示する Web Component
このサイトでの Web Components については以下の記事で書いている。現状は埋め込みツイートのロードと記事一覧でのサムネイル画像表示の 2 つで使っている。
tsx
import { Component, Host, h, Prop, State } from '@stencil/core'
@Component({
tag: 'miyaoka-lightbox',
styleUrl: 'miyaoka-lightbox.css',
shadow: true,
})
export class MiyaokaLightbox {
@Prop() src: string
@State() visible: boolean = false
render() {
return (
<Host>
<div onClick={() => (this.visible = true)} class="container">
{this.visible && (
<div
onClick={(e) => {
e.stopPropagation()
this.visible = false
}}
class="backdrop"
>
<img src={this.src} />
</div>
)}
<slot></slot>
</div>
</Host>
)
}
}
css
.container {
cursor: pointer;
display: inline;
}
.backdrop {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
z-index: 100;
background-color: rgba(64, 62, 62, 0.9);
}
.backdrop img {
width: 100%;
height: 100%;
object-fit: contain;
}
こんな感じのコンポーネントにして、オリジナル画像への a タグだったところをこのコンポーネントに置き換えるようにした。
作ってみてから思ったが、bool の state 一つなので、頑張れば checkbox や details の状態と css だけでもいけるのかもしれない