smartphoto 2.1.11 → 2.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/css/smartphoto.css +24 -0
- package/css/smartphoto.min.css +1 -1
- package/js/jquery-smartphoto.js +179 -31
- package/js/jquery-smartphoto.min.js +2 -2
- package/js/smartphoto.js +179 -31
- package/js/smartphoto.min.js +2 -2
- package/lib/smartphoto.js +178 -30
- package/lib/smartphoto.mjs +178 -30
- package/lib/types/core/index.d.ts +5 -0
- package/lib/types/core/types.d.ts +2 -1
- package/lib/types/core/view.d.ts +1 -0
- package/lib/types/lib/util.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -181,6 +181,11 @@ Slide fields:
|
|
|
181
181
|
<td>update the URL hash (<code>#group=…&photo=…</code>) via the History API</td>
|
|
182
182
|
<td>true</td>
|
|
183
183
|
</tr>
|
|
184
|
+
<tr>
|
|
185
|
+
<td>useViewTransitionApi</td>
|
|
186
|
+
<td>use the View Transition API for the open animation when the browser supports it (falls back to the clone-based animation when disabled or unsupported)</td>
|
|
187
|
+
<td>true</td>
|
|
188
|
+
</tr>
|
|
184
189
|
<tr>
|
|
185
190
|
<td>swipeTopToClose</td>
|
|
186
191
|
<td>close the viewer on an upward swipe</td>
|
package/css/smartphoto.css
CHANGED
|
@@ -132,6 +132,17 @@ dialog.smartphoto:not([open]) {
|
|
|
132
132
|
|
|
133
133
|
.smartphoto::backdrop {
|
|
134
134
|
background-color: var(--smartphoto-backdrop-color, rgba(0, 0, 0, 1));
|
|
135
|
+
/* iOS 26 Safari の「タブバー(下)」表示では、ページ本体はツールバーの背後
|
|
136
|
+
* (レイアウトビューポートの下端より下)までエッジツーエッジで描画されるのに対し、
|
|
137
|
+
* 既定の ::backdrop はビューポート下端で止まるため、サムネイルバーの下の帯から
|
|
138
|
+
* 裏のページが覗いてしまう。dialog 本体の高さを伸ばす方法は取らない
|
|
139
|
+
* (bottom:0 のサムネイルバーごとツールバーの背後に潜ってしまう)。
|
|
140
|
+
* レイアウトに影響しない ::backdrop 側だけを 100lvh + 下側セーフエリアまで
|
|
141
|
+
* 明示的に広げて帯を覆う。lvh 非対応ブラウザでは height 宣言ごと無効になり、
|
|
142
|
+
* 下の inset: 0 による従来のビューポート全面カバーにフォールバックする */
|
|
143
|
+
position: fixed;
|
|
144
|
+
inset: 0;
|
|
145
|
+
height: calc(100lvh + env(safe-area-inset-bottom, 0px));
|
|
135
146
|
}
|
|
136
147
|
|
|
137
148
|
/* View Transition(openPhotoWithViewTransition() 参照)の疑似要素ツリーは document の
|
|
@@ -146,6 +157,19 @@ dialog.smartphoto:not([open]) {
|
|
|
146
157
|
animation-timing-function: var(--smartphoto-animation-function, ease-out);
|
|
147
158
|
}
|
|
148
159
|
|
|
160
|
+
/* view-transition-name を付けなかった要素(サムネイル一覧のページ全体や、
|
|
161
|
+
* 新しく開く dialog の背景/矢印/キャプション等)は、既定では ::view-transition-*(root)
|
|
162
|
+
* が「開く前のページ」→「dialog が開いた後のページ」を丸ごとクロスフェードする。
|
|
163
|
+
* このクロスフェードは既定で mix-blend-mode: plus-lighter が掛かり、背景色が
|
|
164
|
+
* 大きく変わる(明るいページ→黒背景)場合に一瞬白っぽく光って見えたり、写真本体
|
|
165
|
+
* (smartphoto-hero)のモーフィングと重なって「一瞬消えてからまた出てくる」ように
|
|
166
|
+
* 見える原因になる。root 側のアニメーションは無効化し、写真の拡大だけを見せる */
|
|
167
|
+
::view-transition-old(root),
|
|
168
|
+
::view-transition-new(root) {
|
|
169
|
+
animation: none;
|
|
170
|
+
mix-blend-mode: normal;
|
|
171
|
+
}
|
|
172
|
+
|
|
149
173
|
.smartphoto-close {
|
|
150
174
|
opacity: 0;
|
|
151
175
|
}
|
package/css/smartphoto.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@keyframes smartphoto{0%{opacity:0}to{opacity:1}}@keyframes smartphoto-img-wrap{0%{opacity:0}to{opacity:1}}@keyframes smartphoto-inner{0%{transform:translateY(100px)}to{transform:translate(0)}}@keyframes smartphoto-loader{0%{opacity:.4;transform:rotate(0deg)}50%{opacity:1;transform:rotate(180deg)}to{opacity:.4;transform:rotate(1turn)}}@keyframes smartphoto-appear{0%{opacity:0}to{opacity:1}}@keyframes smartphoto-hide{0%{opacity:1}to{opacity:0}}:root:has(dialog.smartphoto[open]){overflow:hidden}.smartphoto{border:none;background:transparent;padding:0;margin:0;outline:none;position:fixed;inset:0;width:100%;height:100%;max-width:100%;max-height:100%;overflow:hidden;height:var(--smartphoto-vh,100dvh);max-height:var(--smartphoto-vh,100dvh);background-color:var(--smartphoto-backdrop-color,#000);opacity:1;font-family:sans-serif;cursor:pointer;transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out),display var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out) allow-discrete,overlay var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out) allow-discrete}.smartphoto:not([open]){opacity:0}dialog.smartphoto:not([open]){display:none!important}.smartphoto::backdrop{background-color:var(--smartphoto-backdrop-color,#000)}::view-transition-group(smartphoto-hero),::view-transition-new(smartphoto-hero),::view-transition-old(smartphoto-hero){animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-close{opacity:0}.smartphoto-count{display:inline-block;color:var(--smartphoto-icon-color,#fff);font-size:16px}.smartphoto-header{display:block;box-sizing:border-box;position:fixed;z-index:102;top:0;left:0;width:100%;height:50px;padding:15px;background-color:var(--smartphoto-header-color,rgba(0,0,0,.2))}.smartphoto-content{display:block;position:absolute;top:0;left:0;width:100%;height:100%;touch-action:none}.smartphoto-dismiss{display:block;position:absolute;top:15px;right:10px;width:20px;height:20px;padding:0;border:none;background-color:var(--smartphoto-icon-color,#fff);mask-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTU3Ni40MiAxNDA2Ljc2IDI3ODQgMTk5LjE5YTU2Ljg2IDU2Ljg2IDAgMCAwIDAtODAuMThsLTc4LjkyLTc4LjkyYTU2Ljg2IDU2Ljg2IDAgMCAwLTgwLjE4IDBMMTQxNy4zMiAxMjQ3LjY2IDIwOS43NSA0MC4wOWE1Ni44NiA1Ni44NiAwIDAgMC04MC4xOCAwTDUwLjY1IDExOWE1Ni44NiA1Ni44NiAwIDAgMCAwIDgwLjE4bDEyMDcuNTggMTIwNy41OEw1MC42NSAyNjE0LjM0YTU2Ljg2IDU2Ljg2IDAgMCAwIDAgODAuMThsNzguOTIgNzguOTJhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGwxMjA3LjU3LTEyMDcuNThMMjYyNC45IDI3NzMuNDRhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGw3OC45Mi03OC45MmE1Ni44NiA1Ni44NiAwIDAgMCAwLTgwLjE4WiIvPjwvc3ZnPg==);-webkit-mask-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTU3Ni40MiAxNDA2Ljc2IDI3ODQgMTk5LjE5YTU2Ljg2IDU2Ljg2IDAgMCAwIDAtODAuMThsLTc4LjkyLTc4LjkyYTU2Ljg2IDU2Ljg2IDAgMCAwLTgwLjE4IDBMMTQxNy4zMiAxMjQ3LjY2IDIwOS43NSA0MC4wOWE1Ni44NiA1Ni44NiAwIDAgMC04MC4xOCAwTDUwLjY1IDExOWE1Ni44NiA1Ni44NiAwIDAgMCAwIDgwLjE4bDEyMDcuNTggMTIwNy41OEw1MC42NSAyNjE0LjM0YTU2Ljg2IDU2Ljg2IDAgMCAwIDAgODAuMThsNzguOTIgNzguOTJhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGwxMjA3LjU3LTEyMDcuNThMMjYyNC45IDI3NzMuNDRhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGw3OC45Mi03OC45MmE1Ni44NiA1Ni44NiAwIDAgMCAwLTgwLjE4WiIvPjwvc3ZnPg==);mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-size:contain;-webkit-mask-size:contain;text-decoration:none;cursor:pointer;line-height:1}.smartphoto-body{z-index:102;margin:0 auto}.smartphoto-body,.smartphoto-inner{position:relative;width:100%;height:100%}.smartphoto-inner{vertical-align:top}.smartphoto-img{display:none;max-width:none;width:auto;height:auto;cursor:zoom-in;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:transform var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-webkit-user-drag:none}.smartphoto-img.active{display:block}.smartphoto-img-onmove{cursor:grab;cursor:-webkit-grab;transition:none}.smartphoto-img-elasticmove{transition:transform var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out)}.smartphoto-img-wrap{display:inline-block;opacity:1;touch-action:none;-webkit-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-moz-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-ms-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-o-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);animation-name:smartphoto-img-wrap;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-img-left{transform:translateX(150%)!important}.smartphoto-img-right{transform:translateX(-150%)!important}.smartphoto-arrows{list-style-type:none;margin:0;padding:0;position:relative;z-index:1002;top:50%;left:0;opacity:1;animation-name:smartphoto-appear;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-arrows[aria-hidden=true]{animation-name:smartphoto-hide;display:none}.smartphoto-arrows li{display:block;position:absolute;top:var(--smartphoto-arrow-top,50%);width:30px;height:30px;margin-top:-20px;box-sizing:content-box;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out);animation-name:smartphoto-appear}.smartphoto-arrows li:focus{outline:none}.smartphoto-arrows [aria-hidden=true]{animation-name:smartphoto-hide;display:none}.smartphoto-arrows button{appearance:none;display:block;width:100%;height:100%;margin:0;padding:0;border:none;background-color:transparent;cursor:pointer}.smartphoto-arrow-right{right:0;padding:5px 0;background-color:rgba(0,0,0,.5)}.smartphoto-arrow-right button{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTgzNy44OCAxNDE3LjMyIDY0My41OSAyMjNhNzIuMjEgNzIuMjEgMCAwIDEgMC0xMDEuODJMNzQzLjgyIDIxYTcyLjIxIDcyLjIxIDAgMCAxIDEwMS44MiAwbDEyNDUuMTkgMTI0NS4xOSAxMDAuMjMgMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAxIDAgMTAxLjgyTDg0NS42NCAyODEzLjY1YTcyLjIxIDcyLjIxIDAgMCAxLTEwMS44MiAwbC0xMDAuMjMtMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAxIDAtMTAxLjgyWiIvPjwvc3ZnPg==)}.smartphoto-arrow-left{left:0;padding:5px 0;background-color:rgba(0,0,0,.5)}.smartphoto-arrow-left button{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNOTk2Ljc3IDE0MTcuMzIgMjE5MS4wNiAyMjNhNzIuMjEgNzIuMjEgMCAwIDAgMC0xMDEuODJMMjA5MC44MyAyMUE3Mi4yMSA3Mi4yMSAwIDAgMCAxOTg5IDIxTDc0My44MiAxMjY2LjE5bC0xMDAuMjMgMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAwIDAgMTAxLjgyTDE5ODkgMjgxMy42NWE3Mi4yMSA3Mi4yMSAwIDAgMCAxMDEuODIgMGwxMDAuMjMtMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAwIDAtMTAxLjgyWiIvPjwvc3ZnPg==)}.smartPhotoArrowHideIcon{display:none}.smartphoto-nav{position:absolute;bottom:0;left:0;width:100%;padding-bottom:env(safe-area-inset-bottom,0);box-sizing:border-box;opacity:1;animation-name:smartphoto-appear;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-nav[aria-hidden=true]{animation-name:smartphoto-hide;display:none}.smartphoto-nav ul{display:block;overflow-x:auto;list-style:none;margin:0;padding:0;text-align:center;white-space:nowrap;-webkit-overflow-scrolling:touch}.smartphoto-nav li{display:inline-block;overflow:hidden;width:50px;height:50px}.smartphoto-nav button{appearance:none;display:block;width:100%;height:100%;margin:0;padding:0;border:none;background-color:#fff;background-position:50%;background-size:cover;opacity:.5;cursor:pointer}.smartphoto-nav button:focus{opacity:.8}.smartphoto-nav button.current{opacity:1}.smartphoto-nav img{width:auto;height:100%}.smartphoto-list{list-style-type:none;position:absolute;z-index:101;top:0;left:0;margin:0;padding:0;white-space:nowrap}.smartphoto-list li{display:block;position:absolute;top:0;left:0;width:100%;height:100%;transition:all var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out)}.smartphoto-list li:focus{outline:none}.smartphoto-list-onmove{transition:all .3s var(--smartphoto-animation-function,ease-out)}.smartphoto-caption{overflow:hidden;box-sizing:border-box;position:absolute;top:0;left:0;width:100%;height:50px;padding:0 50px;color:var(--smartphoto-icon-color,#fff);font-size:12px;text-align:center;line-height:50px;white-space:nowrap;text-overflow:ellipsis;margin:0;font-weight:400}.smartphoto-caption:focus{outline:none}.smartphoto-loader-wrap{display:block;position:relative;z-index:103;width:0;height:0;transform:translate(50vw,50vh);transform:translate(50vw,50dvh);transform:translate(50vw,calc(var(--smartphoto-vh, 100dvh)/2))}.smartphoto-loader{position:absolute;z-index:101;top:0;left:0;width:30px;height:30px;margin-top:-25px;margin-left:-25px;border:8px solid #17cddd;border-right-color:transparent;border-radius:50%;animation:smartphoto-loader .5s linear infinite}.smartphoto-img-clone{position:fixed;z-index:100;top:0;left:0;transition:all var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out)}.smartphoto-sr-only{overflow:hidden;position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;clip:rect(0,0,0,0)}
|
|
1
|
+
@keyframes smartphoto{0%{opacity:0}to{opacity:1}}@keyframes smartphoto-img-wrap{0%{opacity:0}to{opacity:1}}@keyframes smartphoto-inner{0%{transform:translateY(100px)}to{transform:translate(0)}}@keyframes smartphoto-loader{0%{opacity:.4;transform:rotate(0deg)}50%{opacity:1;transform:rotate(180deg)}to{opacity:.4;transform:rotate(1turn)}}@keyframes smartphoto-appear{0%{opacity:0}to{opacity:1}}@keyframes smartphoto-hide{0%{opacity:1}to{opacity:0}}:root:has(dialog.smartphoto[open]){overflow:hidden}.smartphoto{border:none;background:transparent;padding:0;margin:0;outline:none;position:fixed;inset:0;width:100%;height:100%;max-width:100%;max-height:100%;overflow:hidden;height:var(--smartphoto-vh,100dvh);max-height:var(--smartphoto-vh,100dvh);background-color:var(--smartphoto-backdrop-color,#000);opacity:1;font-family:sans-serif;cursor:pointer;transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out),display var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out) allow-discrete,overlay var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out) allow-discrete}.smartphoto:not([open]){opacity:0}dialog.smartphoto:not([open]){display:none!important}.smartphoto::backdrop{background-color:var(--smartphoto-backdrop-color,#000);position:fixed;inset:0;height:calc(100lvh + env(safe-area-inset-bottom, 0px))}::view-transition-group(smartphoto-hero),::view-transition-new(smartphoto-hero),::view-transition-old(smartphoto-hero){animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}::view-transition-new(root),::view-transition-old(root){animation:none;mix-blend-mode:normal}.smartphoto-close{opacity:0}.smartphoto-count{display:inline-block;color:var(--smartphoto-icon-color,#fff);font-size:16px}.smartphoto-header{display:block;box-sizing:border-box;position:fixed;z-index:102;top:0;left:0;width:100%;height:50px;padding:15px;background-color:var(--smartphoto-header-color,rgba(0,0,0,.2))}.smartphoto-content{display:block;position:absolute;top:0;left:0;width:100%;height:100%;touch-action:none}.smartphoto-dismiss{display:block;position:absolute;top:15px;right:10px;width:20px;height:20px;padding:0;border:none;background-color:var(--smartphoto-icon-color,#fff);mask-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTU3Ni40MiAxNDA2Ljc2IDI3ODQgMTk5LjE5YTU2Ljg2IDU2Ljg2IDAgMCAwIDAtODAuMThsLTc4LjkyLTc4LjkyYTU2Ljg2IDU2Ljg2IDAgMCAwLTgwLjE4IDBMMTQxNy4zMiAxMjQ3LjY2IDIwOS43NSA0MC4wOWE1Ni44NiA1Ni44NiAwIDAgMC04MC4xOCAwTDUwLjY1IDExOWE1Ni44NiA1Ni44NiAwIDAgMCAwIDgwLjE4bDEyMDcuNTggMTIwNy41OEw1MC42NSAyNjE0LjM0YTU2Ljg2IDU2Ljg2IDAgMCAwIDAgODAuMThsNzguOTIgNzguOTJhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGwxMjA3LjU3LTEyMDcuNThMMjYyNC45IDI3NzMuNDRhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGw3OC45Mi03OC45MmE1Ni44NiA1Ni44NiAwIDAgMCAwLTgwLjE4WiIvPjwvc3ZnPg==);-webkit-mask-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTU3Ni40MiAxNDA2Ljc2IDI3ODQgMTk5LjE5YTU2Ljg2IDU2Ljg2IDAgMCAwIDAtODAuMThsLTc4LjkyLTc4LjkyYTU2Ljg2IDU2Ljg2IDAgMCAwLTgwLjE4IDBMMTQxNy4zMiAxMjQ3LjY2IDIwOS43NSA0MC4wOWE1Ni44NiA1Ni44NiAwIDAgMC04MC4xOCAwTDUwLjY1IDExOWE1Ni44NiA1Ni44NiAwIDAgMCAwIDgwLjE4bDEyMDcuNTggMTIwNy41OEw1MC42NSAyNjE0LjM0YTU2Ljg2IDU2Ljg2IDAgMCAwIDAgODAuMThsNzguOTIgNzguOTJhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGwxMjA3LjU3LTEyMDcuNThMMjYyNC45IDI3NzMuNDRhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGw3OC45Mi03OC45MmE1Ni44NiA1Ni44NiAwIDAgMCAwLTgwLjE4WiIvPjwvc3ZnPg==);mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-size:contain;-webkit-mask-size:contain;text-decoration:none;cursor:pointer;line-height:1}.smartphoto-body{z-index:102;margin:0 auto}.smartphoto-body,.smartphoto-inner{position:relative;width:100%;height:100%}.smartphoto-inner{vertical-align:top}.smartphoto-img{display:none;max-width:none;width:auto;height:auto;cursor:zoom-in;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:transform var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-webkit-user-drag:none}.smartphoto-img.active{display:block}.smartphoto-img-onmove{cursor:grab;cursor:-webkit-grab;transition:none}.smartphoto-img-elasticmove{transition:transform var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out)}.smartphoto-img-wrap{display:inline-block;opacity:1;touch-action:none;-webkit-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-moz-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-ms-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);-o-transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);transition:opacity var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out);animation-name:smartphoto-img-wrap;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-img-left{transform:translateX(150%)!important}.smartphoto-img-right{transform:translateX(-150%)!important}.smartphoto-arrows{list-style-type:none;margin:0;padding:0;position:relative;z-index:1002;top:50%;left:0;opacity:1;animation-name:smartphoto-appear;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-arrows[aria-hidden=true]{animation-name:smartphoto-hide;display:none}.smartphoto-arrows li{display:block;position:absolute;top:var(--smartphoto-arrow-top,50%);width:30px;height:30px;margin-top:-20px;box-sizing:content-box;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out);animation-name:smartphoto-appear}.smartphoto-arrows li:focus{outline:none}.smartphoto-arrows [aria-hidden=true]{animation-name:smartphoto-hide;display:none}.smartphoto-arrows button{appearance:none;display:block;width:100%;height:100%;margin:0;padding:0;border:none;background-color:transparent;cursor:pointer}.smartphoto-arrow-right{right:0;padding:5px 0;background-color:rgba(0,0,0,.5)}.smartphoto-arrow-right button{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTgzNy44OCAxNDE3LjMyIDY0My41OSAyMjNhNzIuMjEgNzIuMjEgMCAwIDEgMC0xMDEuODJMNzQzLjgyIDIxYTcyLjIxIDcyLjIxIDAgMCAxIDEwMS44MiAwbDEyNDUuMTkgMTI0NS4xOSAxMDAuMjMgMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAxIDAgMTAxLjgyTDg0NS42NCAyODEzLjY1YTcyLjIxIDcyLjIxIDAgMCAxLTEwMS44MiAwbC0xMDAuMjMtMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAxIDAtMTAxLjgyWiIvPjwvc3ZnPg==)}.smartphoto-arrow-left{left:0;padding:5px 0;background-color:rgba(0,0,0,.5)}.smartphoto-arrow-left button{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNOTk2Ljc3IDE0MTcuMzIgMjE5MS4wNiAyMjNhNzIuMjEgNzIuMjEgMCAwIDAgMC0xMDEuODJMMjA5MC44MyAyMUE3Mi4yMSA3Mi4yMSAwIDAgMCAxOTg5IDIxTDc0My44MiAxMjY2LjE5bC0xMDAuMjMgMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAwIDAgMTAxLjgyTDE5ODkgMjgxMy42NWE3Mi4yMSA3Mi4yMSAwIDAgMCAxMDEuODIgMGwxMDAuMjMtMTAwLjIzYTcyLjIxIDcyLjIxIDAgMCAwIDAtMTAxLjgyWiIvPjwvc3ZnPg==)}.smartPhotoArrowHideIcon{display:none}.smartphoto-nav{position:absolute;bottom:0;left:0;width:100%;padding-bottom:env(safe-area-inset-bottom,0);box-sizing:border-box;opacity:1;animation-name:smartphoto-appear;animation-duration:var(--smartphoto-animation-speed,.45s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-nav[aria-hidden=true]{animation-name:smartphoto-hide;display:none}.smartphoto-nav ul{display:block;overflow-x:auto;list-style:none;margin:0;padding:0;text-align:center;white-space:nowrap;-webkit-overflow-scrolling:touch}.smartphoto-nav li{display:inline-block;overflow:hidden;width:50px;height:50px}.smartphoto-nav button{appearance:none;display:block;width:100%;height:100%;margin:0;padding:0;border:none;background-color:#fff;background-position:50%;background-size:cover;opacity:.5;cursor:pointer}.smartphoto-nav button:focus{opacity:.8}.smartphoto-nav button.current{opacity:1}.smartphoto-nav img{width:auto;height:100%}.smartphoto-list{list-style-type:none;position:absolute;z-index:101;top:0;left:0;margin:0;padding:0;white-space:nowrap}.smartphoto-list li{display:block;position:absolute;top:0;left:0;width:100%;height:100%;transition:all var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out)}.smartphoto-list li:focus{outline:none}.smartphoto-list-onmove{transition:all .3s var(--smartphoto-animation-function,ease-out)}.smartphoto-caption{overflow:hidden;box-sizing:border-box;position:absolute;top:0;left:0;width:100%;height:50px;padding:0 50px;color:var(--smartphoto-icon-color,#fff);font-size:12px;text-align:center;line-height:50px;white-space:nowrap;text-overflow:ellipsis;margin:0;font-weight:400}.smartphoto-caption:focus{outline:none}.smartphoto-loader-wrap{display:block;position:relative;z-index:103;width:0;height:0;transform:translate(50vw,50vh);transform:translate(50vw,50dvh);transform:translate(50vw,calc(var(--smartphoto-vh, 100dvh)/2))}.smartphoto-loader{position:absolute;z-index:101;top:0;left:0;width:30px;height:30px;margin-top:-25px;margin-left:-25px;border:8px solid #17cddd;border-right-color:transparent;border-radius:50%;animation:smartphoto-loader .5s linear infinite}.smartphoto-img-clone{position:fixed;z-index:100;top:0;left:0;transition:all var(--smartphoto-animation-speed,.45s) var(--smartphoto-animation-function,ease-out)}.smartphoto-sr-only{overflow:hidden;position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;clip:rect(0,0,0,0)}
|
package/js/jquery-smartphoto.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* SmartPhoto v2.1.
|
|
2
|
+
* SmartPhoto v2.1.13
|
|
3
3
|
* (c) appleple
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
const agent = navigator.userAgent;
|
|
11
11
|
return agent.indexOf("iPhone") > 0 || agent.indexOf("iPad") > 0 || agent.indexOf("ipod") > 0 || agent.indexOf("Android") > 0;
|
|
12
12
|
};
|
|
13
|
+
var isWebKit = () => {
|
|
14
|
+
return typeof window.webkitConvertPointFromNodeToPage === "function";
|
|
15
|
+
};
|
|
13
16
|
function deepExtend(out, ...args) {
|
|
14
17
|
var _a;
|
|
15
18
|
out = out || {};
|
|
@@ -148,6 +151,7 @@
|
|
|
148
151
|
verticalGravity: false,
|
|
149
152
|
useOrientationApi: false,
|
|
150
153
|
useHistoryApi: true,
|
|
154
|
+
useViewTransitionApi: true,
|
|
151
155
|
swipeTopToClose: false,
|
|
152
156
|
swipeBottomToClose: true,
|
|
153
157
|
swipeOffset: 100,
|
|
@@ -435,6 +439,7 @@
|
|
|
435
439
|
let oldPos = null;
|
|
436
440
|
let moveDir = null;
|
|
437
441
|
let swipeStartTime = 0;
|
|
442
|
+
let tapTarget = null;
|
|
438
443
|
let photoSwipable = false;
|
|
439
444
|
let firstPhotoPos = null;
|
|
440
445
|
let oldPhotoPos = null;
|
|
@@ -565,6 +570,7 @@
|
|
|
565
570
|
firstPos = pos;
|
|
566
571
|
oldPos = pos;
|
|
567
572
|
swipeStartTime = Date.now();
|
|
573
|
+
tapTarget = e.target;
|
|
568
574
|
}
|
|
569
575
|
function startPhotoDrag(e) {
|
|
570
576
|
photoSwipable = true;
|
|
@@ -706,11 +712,11 @@
|
|
|
706
712
|
const swipeHeight = last.y - first.y;
|
|
707
713
|
const noMove = swipeWidth === 0 && swipeHeight === 0;
|
|
708
714
|
if (!isSmartPhone2() && noMove) {
|
|
709
|
-
callbacks.onTap();
|
|
715
|
+
callbacks.onTap(tapTarget);
|
|
710
716
|
return;
|
|
711
717
|
}
|
|
712
718
|
if (Math.abs(offset) <= 500 && noMove) {
|
|
713
|
-
callbacks.onTap();
|
|
719
|
+
callbacks.onTap(tapTarget);
|
|
714
720
|
return;
|
|
715
721
|
}
|
|
716
722
|
tapSecond = now;
|
|
@@ -1035,6 +1041,9 @@
|
|
|
1035
1041
|
if (slideRefs.imgWrap && slideRefs.img) {
|
|
1036
1042
|
slideRefs.imgWrap.style.transform = `translate(${item.x}px,${item.y}px) scale(${item.scale})`;
|
|
1037
1043
|
slideRefs.img.style.width = `${item.width}px`;
|
|
1044
|
+
if (!isCurrent) {
|
|
1045
|
+
slideRefs.img.style.transform = "translate(0px,0px) scale(1)";
|
|
1046
|
+
}
|
|
1038
1047
|
slideRefs.img.classList.toggle("active", viewer.appear);
|
|
1039
1048
|
slideRefs.img.classList.toggle(
|
|
1040
1049
|
classNames.smartPhotoImgOnMove,
|
|
@@ -1118,6 +1127,23 @@
|
|
|
1118
1127
|
refs.list.style.transform = `translate(${viewer.translateX}px,${viewer.translateY}px)`;
|
|
1119
1128
|
refs.list.classList.toggle(classNames.smartPhotoListOnMove, viewer.onMove);
|
|
1120
1129
|
}
|
|
1130
|
+
function applyViewTransitionLayout(state) {
|
|
1131
|
+
for (const [item, slideRefs] of refs.slides) {
|
|
1132
|
+
if (item.index !== state.viewer.currentIndex) {
|
|
1133
|
+
continue;
|
|
1134
|
+
}
|
|
1135
|
+
const { img, imgWrap } = slideRefs;
|
|
1136
|
+
if (!img || !imgWrap || !item.width || !item.scale || item.scale >= 1) {
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
const before = img.getBoundingClientRect();
|
|
1140
|
+
img.style.width = `${item.width * item.scale}px`;
|
|
1141
|
+
imgWrap.style.transform = `translate(${item.x}px,${item.y}px) scale(1)`;
|
|
1142
|
+
const after = img.getBoundingClientRect();
|
|
1143
|
+
imgWrap.style.transform = `translate(${item.x + before.left - after.left}px,${item.y + before.top - after.top}px) scale(1)`;
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1121
1147
|
function showAppearEffect(effect) {
|
|
1122
1148
|
const clone = document.createElement("img");
|
|
1123
1149
|
clone.className = classNames.smartPhotoImgClone;
|
|
@@ -1142,6 +1168,7 @@
|
|
|
1142
1168
|
render,
|
|
1143
1169
|
syncSlides,
|
|
1144
1170
|
updatePhotoTransform,
|
|
1171
|
+
applyViewTransitionLayout,
|
|
1145
1172
|
updateListTransform,
|
|
1146
1173
|
showAppearEffect,
|
|
1147
1174
|
removeAppearEffect,
|
|
@@ -1178,6 +1205,13 @@
|
|
|
1178
1205
|
// doHideEffect() の後始末(画像に設定した translateY の除去と promise 解決)を
|
|
1179
1206
|
// transitionend を待たずに即時実行するための関数。後始末が済むと null に戻る
|
|
1180
1207
|
this.finishHideEffect = null;
|
|
1208
|
+
// 開く View Transition が進行中かどうか。進行中にリサイズ由来の再計算(commit)が
|
|
1209
|
+
// 走ると、モーフの目標位置は古いビューポート基準のままなのに実要素だけ新しい
|
|
1210
|
+
// 位置へ動いて「一旦ずれた位置に出てから正位置へ戻る」ように見え、さらに
|
|
1211
|
+
// モーフ用レイアウト(applyViewTransitionLayout)も巻き戻されてしまう。
|
|
1212
|
+
// そのため進行中はリサイズ再計算を保留し、finished 後にまとめて実行する
|
|
1213
|
+
this.isViewTransitionActive = false;
|
|
1214
|
+
this.pendingViewTransitionResync = false;
|
|
1181
1215
|
this.timeouts = [];
|
|
1182
1216
|
this.loadAllFired = /* @__PURE__ */ new Set();
|
|
1183
1217
|
this.syncedGroupId = null;
|
|
@@ -1236,16 +1270,24 @@
|
|
|
1236
1270
|
if (!this.isSmartPhoneFlag || !this.state.viewer.isOpen || !currentItems(this.state)) {
|
|
1237
1271
|
return;
|
|
1238
1272
|
}
|
|
1273
|
+
if (this.isViewTransitionActive) {
|
|
1274
|
+
this.pendingViewTransitionResync = true;
|
|
1275
|
+
return;
|
|
1276
|
+
}
|
|
1239
1277
|
this.resetTranslateCurrent();
|
|
1240
1278
|
this.setPosByCurrentIndex();
|
|
1241
1279
|
this.setSizeByScreen();
|
|
1242
1280
|
this.commit();
|
|
1243
1281
|
};
|
|
1244
1282
|
this.handleResize = () => {
|
|
1245
|
-
if (!currentItems(this.state)) {
|
|
1283
|
+
if (!this.state.viewer.isOpen || !currentItems(this.state)) {
|
|
1246
1284
|
return;
|
|
1247
1285
|
}
|
|
1248
1286
|
this.updateViewportHeight();
|
|
1287
|
+
if (this.isViewTransitionActive) {
|
|
1288
|
+
this.pendingViewTransitionResync = true;
|
|
1289
|
+
return;
|
|
1290
|
+
}
|
|
1249
1291
|
this.resetTranslateCurrent();
|
|
1250
1292
|
this.setPosByCurrentIndex();
|
|
1251
1293
|
this.setSizeByScreen();
|
|
@@ -1265,7 +1307,11 @@
|
|
|
1265
1307
|
}
|
|
1266
1308
|
};
|
|
1267
1309
|
this.handleOrientationChange = () => {
|
|
1268
|
-
if (!currentItems(this.state)) {
|
|
1310
|
+
if (!this.state.viewer.isOpen || !currentItems(this.state)) {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
if (this.isViewTransitionActive) {
|
|
1314
|
+
this.pendingViewTransitionResync = true;
|
|
1269
1315
|
return;
|
|
1270
1316
|
}
|
|
1271
1317
|
this.updateViewportHeight();
|
|
@@ -1278,6 +1324,9 @@
|
|
|
1278
1324
|
const timeout = 500;
|
|
1279
1325
|
const poll = (time) => {
|
|
1280
1326
|
this.scheduleTimeout(() => {
|
|
1327
|
+
if (!this.state.viewer.isOpen) {
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1281
1330
|
if (prevWidth !== getWindowWidth2()) {
|
|
1282
1331
|
this.updateViewportHeight();
|
|
1283
1332
|
this.resetTranslateCurrent();
|
|
@@ -1430,10 +1479,26 @@
|
|
|
1430
1479
|
this.state.viewer.photoPosY = 0;
|
|
1431
1480
|
this.view.updatePhotoTransform(this.state);
|
|
1432
1481
|
this.scheduleTimeout(() => {
|
|
1482
|
+
if (!this.state.viewer.isOpen) {
|
|
1483
|
+
return;
|
|
1484
|
+
}
|
|
1433
1485
|
this.state.viewer.scale = true;
|
|
1434
1486
|
this.view.updatePhotoTransform(this.state);
|
|
1435
1487
|
this.fireEvent("zoomin");
|
|
1436
|
-
},
|
|
1488
|
+
}, this.state.options.animationSpeed);
|
|
1489
|
+
}
|
|
1490
|
+
// zoomPhoto() と同じ「ズームの余地があるか」の判定(scaleBorder <= 1 なら
|
|
1491
|
+
// ズームしても見た目が変わらない)。zoomPhoto() 自体は公開 API の契約
|
|
1492
|
+
// (ズームできなければ何もしない)を保つ必要があるため、タップの
|
|
1493
|
+
// zoom-or-close 分岐(§7)用に判定だけを切り出している
|
|
1494
|
+
canZoomCurrentPhoto() {
|
|
1495
|
+
const item = currentItem(this.state);
|
|
1496
|
+
return !!item && scaleBorder(
|
|
1497
|
+
item,
|
|
1498
|
+
getWindowWidth2(),
|
|
1499
|
+
getWindowHeight2(),
|
|
1500
|
+
this.isSmartPhoneFlag
|
|
1501
|
+
) > 1;
|
|
1437
1502
|
}
|
|
1438
1503
|
zoomOutPhoto() {
|
|
1439
1504
|
this.state.viewer.scaleSize = 1;
|
|
@@ -1644,6 +1709,7 @@
|
|
|
1644
1709
|
this.state.options.headerHeight,
|
|
1645
1710
|
this.state.options.footerHeight
|
|
1646
1711
|
);
|
|
1712
|
+
this.syncFillScale();
|
|
1647
1713
|
}
|
|
1648
1714
|
// resize/orientationchange ハンドラは呼び出し前に currentItems の存在を確認済み
|
|
1649
1715
|
resetTranslateCurrent() {
|
|
@@ -1657,9 +1723,18 @@
|
|
|
1657
1723
|
}
|
|
1658
1724
|
return null;
|
|
1659
1725
|
}
|
|
1726
|
+
currentLiElement() {
|
|
1727
|
+
for (const [item, slideRefs] of this.view.refs.slides) {
|
|
1728
|
+
if (item.index === this.state.viewer.currentIndex) {
|
|
1729
|
+
return slideRefs.li;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
return null;
|
|
1733
|
+
}
|
|
1660
1734
|
// ---- 内部: dialog 制御(§8) ----
|
|
1661
1735
|
syncDialog() {
|
|
1662
1736
|
const { dialog, caption } = this.view.refs;
|
|
1737
|
+
dialog.style.transition = this.state.options.showAnimation === false ? "none" : "";
|
|
1663
1738
|
if (this.state.viewer.isOpen && !dialog.open) {
|
|
1664
1739
|
dialog.style.removeProperty("display");
|
|
1665
1740
|
dialog.showModal();
|
|
@@ -1671,6 +1746,7 @@
|
|
|
1671
1746
|
}
|
|
1672
1747
|
commit() {
|
|
1673
1748
|
this.view.render(this.state);
|
|
1749
|
+
this.view.updatePhotoTransform(this.state);
|
|
1674
1750
|
this.syncDialog();
|
|
1675
1751
|
}
|
|
1676
1752
|
// ---- 内部: 開く演出 ----
|
|
@@ -1689,20 +1765,34 @@
|
|
|
1689
1765
|
this.setPosByCurrentIndex();
|
|
1690
1766
|
this.setSizeByScreen();
|
|
1691
1767
|
setArrow(this.state);
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1768
|
+
}
|
|
1769
|
+
// resizeStyle: 'fill' はスマートフォンでのみ、画面を隙間なく覆うよう
|
|
1770
|
+
// scaleBorder() の倍率を viewer.scaleSize に適用する。fit用の item.scale に
|
|
1771
|
+
// 依存するため、setSizeByScreen() の末尾から必ず呼ばれる(個別に呼ぶ必要はない)
|
|
1772
|
+
syncFillScale() {
|
|
1773
|
+
if (this.state.options.resizeStyle !== "fill" || !this.isSmartPhoneFlag) {
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
const item = currentItem(this.state);
|
|
1777
|
+
if (!item) {
|
|
1778
|
+
return;
|
|
1702
1779
|
}
|
|
1780
|
+
this.state.viewer.scale = true;
|
|
1781
|
+
this.state.viewer.hideUi = true;
|
|
1782
|
+
this.state.viewer.scaleSize = scaleBorder(
|
|
1783
|
+
item,
|
|
1784
|
+
getWindowWidth2(),
|
|
1785
|
+
getWindowHeight2(),
|
|
1786
|
+
this.isSmartPhoneFlag
|
|
1787
|
+
);
|
|
1703
1788
|
}
|
|
1704
1789
|
supportsViewTransition() {
|
|
1705
|
-
return typeof document.startViewTransition === "function"
|
|
1790
|
+
return this.state.options.useViewTransitionApi && typeof document.startViewTransition === "function" && // WebKit には「view-transition-name 付き要素が root スナップショットから
|
|
1791
|
+
// 除外されず、モーフ中に最終位置へ二重描画される」実装バグがあり、開く演出が
|
|
1792
|
+
// 「一旦ずれた位置に出てから正位置へ戻る」ように乱れる。API 対応の有無では
|
|
1793
|
+
// 検出できないため、WebKit ではクローン演出(addAppearEffect)へフォールバック
|
|
1794
|
+
// する(§util.isWebKit)
|
|
1795
|
+
!isWebKit();
|
|
1706
1796
|
}
|
|
1707
1797
|
openPhotoWithViewTransition(trigger) {
|
|
1708
1798
|
var _a, _b;
|
|
@@ -1715,7 +1805,8 @@
|
|
|
1715
1805
|
if (thumbImg) {
|
|
1716
1806
|
thumbImg.style.viewTransitionName = transitionName;
|
|
1717
1807
|
}
|
|
1718
|
-
const
|
|
1808
|
+
const cleanup = () => {
|
|
1809
|
+
this.isViewTransitionActive = false;
|
|
1719
1810
|
if (thumbImg) {
|
|
1720
1811
|
thumbImg.style.viewTransitionName = "";
|
|
1721
1812
|
}
|
|
@@ -1723,6 +1814,21 @@
|
|
|
1723
1814
|
if (img) {
|
|
1724
1815
|
img.style.viewTransitionName = "";
|
|
1725
1816
|
}
|
|
1817
|
+
if (!this.state.viewer.isOpen) {
|
|
1818
|
+
this.pendingViewTransitionResync = false;
|
|
1819
|
+
return;
|
|
1820
|
+
}
|
|
1821
|
+
if (this.pendingViewTransitionResync && currentItems(this.state)) {
|
|
1822
|
+
this.pendingViewTransitionResync = false;
|
|
1823
|
+
this.updateViewportHeight();
|
|
1824
|
+
this.resetTranslateCurrent();
|
|
1825
|
+
this.setPosByCurrentIndex();
|
|
1826
|
+
this.setSizeByScreen();
|
|
1827
|
+
this.commit();
|
|
1828
|
+
return;
|
|
1829
|
+
}
|
|
1830
|
+
this.pendingViewTransitionResync = false;
|
|
1831
|
+
this.view.render(this.state);
|
|
1726
1832
|
};
|
|
1727
1833
|
const transition = (_b = document.startViewTransition) == null ? void 0 : _b.call(document, () => {
|
|
1728
1834
|
this.initPhoto();
|
|
@@ -1732,11 +1838,16 @@
|
|
|
1732
1838
|
thumbImg.style.viewTransitionName = "";
|
|
1733
1839
|
}
|
|
1734
1840
|
this.currentImgElement().style.viewTransitionName = transitionName;
|
|
1841
|
+
this.view.applyViewTransitionLayout(this.state);
|
|
1735
1842
|
});
|
|
1736
|
-
|
|
1737
|
-
|
|
1843
|
+
if (!transition) {
|
|
1844
|
+
return;
|
|
1845
|
+
}
|
|
1846
|
+
this.isViewTransitionActive = true;
|
|
1847
|
+
transition.ready.catch(() => {
|
|
1848
|
+
cleanup();
|
|
1738
1849
|
});
|
|
1739
|
-
transition
|
|
1850
|
+
transition.finished.then(cleanup, cleanup);
|
|
1740
1851
|
}
|
|
1741
1852
|
// doOpen() の呼び出し元でこの分岐に来る時点で showAnimation !== false が保証されている
|
|
1742
1853
|
addAppearEffect(trigger, item) {
|
|
@@ -1846,10 +1957,14 @@
|
|
|
1846
1957
|
if (getWindowWidth2() === winWidthBefore && getWindowHeight2() === winHeightBefore) {
|
|
1847
1958
|
return;
|
|
1848
1959
|
}
|
|
1960
|
+
if (this.isViewTransitionActive) {
|
|
1961
|
+
this.pendingViewTransitionResync = true;
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1849
1964
|
this.resetTranslateCurrent();
|
|
1850
1965
|
this.setPosByCurrentIndex();
|
|
1851
1966
|
this.setSizeByScreen();
|
|
1852
|
-
this.
|
|
1967
|
+
this.commit();
|
|
1853
1968
|
});
|
|
1854
1969
|
}
|
|
1855
1970
|
openPhoto(item, trigger) {
|
|
@@ -1871,25 +1986,42 @@
|
|
|
1871
1986
|
}
|
|
1872
1987
|
doHideEffect(dir) {
|
|
1873
1988
|
return new Promise((resolve) => {
|
|
1989
|
+
if (this.state.options.showAnimation === false) {
|
|
1990
|
+
resolve();
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1874
1993
|
const dialog = this.view.refs.dialog;
|
|
1875
|
-
const
|
|
1994
|
+
const item = currentItem(this.state);
|
|
1995
|
+
const li = item ? this.currentLiElement() : null;
|
|
1876
1996
|
const height = getWindowHeight2();
|
|
1877
|
-
const
|
|
1878
|
-
|
|
1997
|
+
const img = this.currentImgElement();
|
|
1998
|
+
let frozenTransform = null;
|
|
1999
|
+
if (img) {
|
|
2000
|
+
const rendered = getComputedStyle(img).transform;
|
|
2001
|
+
if (rendered && rendered !== "none") {
|
|
2002
|
+
img.style.transform = rendered;
|
|
2003
|
+
frozenTransform = img.style.transform;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
if (li && item) {
|
|
2007
|
+
const offsetY = dir === "top" ? -height : height;
|
|
2008
|
+
li.style.transform = `translate(${item.translateX}px,${item.translateY + offsetY}px)`;
|
|
2009
|
+
}
|
|
2010
|
+
const finish = (e) => {
|
|
1879
2011
|
if (this.finishHideEffect !== finish) {
|
|
1880
2012
|
return;
|
|
1881
2013
|
}
|
|
2014
|
+
if (e && e.target !== dialog) {
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
1882
2017
|
this.finishHideEffect = null;
|
|
1883
2018
|
dialog.removeEventListener("transitionend", finish, true);
|
|
1884
|
-
if (img && img.style.transform ===
|
|
2019
|
+
if (img && frozenTransform && img.style.transform === frozenTransform) {
|
|
1885
2020
|
img.style.transform = "";
|
|
1886
2021
|
}
|
|
1887
2022
|
resolve();
|
|
1888
2023
|
};
|
|
1889
2024
|
this.finishHideEffect = finish;
|
|
1890
|
-
if (img) {
|
|
1891
|
-
img.style.transform = applied;
|
|
1892
|
-
}
|
|
1893
2025
|
dialog.addEventListener("transitionend", finish, true);
|
|
1894
2026
|
this.scheduleTimeout(finish, this.state.options.animationSpeed + 100);
|
|
1895
2027
|
});
|
|
@@ -1960,7 +2092,9 @@
|
|
|
1960
2092
|
const item = currentItem(this.state);
|
|
1961
2093
|
this.state.viewer.onMove = false;
|
|
1962
2094
|
setArrow(this.state);
|
|
1963
|
-
this.
|
|
2095
|
+
if (this.state.viewer.isOpen) {
|
|
2096
|
+
this.commit();
|
|
2097
|
+
}
|
|
1964
2098
|
if (this.state.viewer.oldIndex !== this.state.viewer.currentIndex) {
|
|
1965
2099
|
this.fireEvent("change");
|
|
1966
2100
|
}
|
|
@@ -2045,7 +2179,21 @@
|
|
|
2045
2179
|
}
|
|
2046
2180
|
this.slideList();
|
|
2047
2181
|
},
|
|
2048
|
-
|
|
2182
|
+
// 主要ライトボックスのデファクトスタンダード(PhotoSwipe: bgClickAction
|
|
2183
|
+
// 'close' / imageClickAction 'zoom-or-close'、Fancybox: backdropClick
|
|
2184
|
+
// 'close'、GLightbox: closeOnOutsideClick、lightGallery: closable)に合わせ、
|
|
2185
|
+
// 写真の上のタップはズーム、写真の外(背景)のタップは閉じる。ズームの
|
|
2186
|
+
// 余地がない(scaleBorder <= 1 で zoomPhoto() が何もしない)写真の上の
|
|
2187
|
+
// タップも、無反応にせず 'zoom-or-close' に倣って閉じる
|
|
2188
|
+
onTap: (target) => {
|
|
2189
|
+
const img = this.currentImgElement();
|
|
2190
|
+
const onPhoto = !!img && target instanceof Node && img.contains(target);
|
|
2191
|
+
if (onPhoto && this.canZoomCurrentPhoto()) {
|
|
2192
|
+
this.zoomPhoto();
|
|
2193
|
+
} else {
|
|
2194
|
+
this.hidePhoto();
|
|
2195
|
+
}
|
|
2196
|
+
},
|
|
2049
2197
|
onGestureStart: () => {
|
|
2050
2198
|
this.fireEvent("gesturestart");
|
|
2051
2199
|
this.view.updatePhotoTransform(this.state);
|