smartphoto 2.1.12 → 2.1.14
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 +194 -33
- package/js/jquery-smartphoto.min.js +2 -2
- package/js/smartphoto.js +194 -33
- package/js/smartphoto.min.js +2 -2
- package/lib/smartphoto.js +192 -32
- package/lib/smartphoto.mjs +192 -32
- 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 +2 -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.14
|
|
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,32 @@
|
|
|
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
|
+
}
|
|
1147
|
+
function resetViewTransitionLayout() {
|
|
1148
|
+
for (const [item, slideRefs] of refs.slides) {
|
|
1149
|
+
const { img, imgWrap } = slideRefs;
|
|
1150
|
+
if (img && imgWrap) {
|
|
1151
|
+
imgWrap.style.transform = `translate(${item.x}px,${item.y}px) scale(${item.scale})`;
|
|
1152
|
+
img.style.width = `${item.width}px`;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1121
1156
|
function showAppearEffect(effect) {
|
|
1122
1157
|
const clone = document.createElement("img");
|
|
1123
1158
|
clone.className = classNames.smartPhotoImgClone;
|
|
@@ -1142,6 +1177,8 @@
|
|
|
1142
1177
|
render,
|
|
1143
1178
|
syncSlides,
|
|
1144
1179
|
updatePhotoTransform,
|
|
1180
|
+
applyViewTransitionLayout,
|
|
1181
|
+
resetViewTransitionLayout,
|
|
1145
1182
|
updateListTransform,
|
|
1146
1183
|
showAppearEffect,
|
|
1147
1184
|
removeAppearEffect,
|
|
@@ -1178,6 +1215,13 @@
|
|
|
1178
1215
|
// doHideEffect() の後始末(画像に設定した translateY の除去と promise 解決)を
|
|
1179
1216
|
// transitionend を待たずに即時実行するための関数。後始末が済むと null に戻る
|
|
1180
1217
|
this.finishHideEffect = null;
|
|
1218
|
+
// 開く View Transition が進行中かどうか。進行中にリサイズ由来の再計算(commit)が
|
|
1219
|
+
// 走ると、モーフの目標位置は古いビューポート基準のままなのに実要素だけ新しい
|
|
1220
|
+
// 位置へ動いて「一旦ずれた位置に出てから正位置へ戻る」ように見え、さらに
|
|
1221
|
+
// モーフ用レイアウト(applyViewTransitionLayout)も巻き戻されてしまう。
|
|
1222
|
+
// そのため進行中はリサイズ再計算を保留し、finished 後にまとめて実行する
|
|
1223
|
+
this.isViewTransitionActive = false;
|
|
1224
|
+
this.pendingViewTransitionResync = false;
|
|
1181
1225
|
this.timeouts = [];
|
|
1182
1226
|
this.loadAllFired = /* @__PURE__ */ new Set();
|
|
1183
1227
|
this.syncedGroupId = null;
|
|
@@ -1236,16 +1280,24 @@
|
|
|
1236
1280
|
if (!this.isSmartPhoneFlag || !this.state.viewer.isOpen || !currentItems(this.state)) {
|
|
1237
1281
|
return;
|
|
1238
1282
|
}
|
|
1283
|
+
if (this.isViewTransitionActive) {
|
|
1284
|
+
this.pendingViewTransitionResync = true;
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1239
1287
|
this.resetTranslateCurrent();
|
|
1240
1288
|
this.setPosByCurrentIndex();
|
|
1241
1289
|
this.setSizeByScreen();
|
|
1242
1290
|
this.commit();
|
|
1243
1291
|
};
|
|
1244
1292
|
this.handleResize = () => {
|
|
1245
|
-
if (!currentItems(this.state)) {
|
|
1293
|
+
if (!this.state.viewer.isOpen || !currentItems(this.state)) {
|
|
1246
1294
|
return;
|
|
1247
1295
|
}
|
|
1248
1296
|
this.updateViewportHeight();
|
|
1297
|
+
if (this.isViewTransitionActive) {
|
|
1298
|
+
this.pendingViewTransitionResync = true;
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1249
1301
|
this.resetTranslateCurrent();
|
|
1250
1302
|
this.setPosByCurrentIndex();
|
|
1251
1303
|
this.setSizeByScreen();
|
|
@@ -1265,7 +1317,11 @@
|
|
|
1265
1317
|
}
|
|
1266
1318
|
};
|
|
1267
1319
|
this.handleOrientationChange = () => {
|
|
1268
|
-
if (!currentItems(this.state)) {
|
|
1320
|
+
if (!this.state.viewer.isOpen || !currentItems(this.state)) {
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
if (this.isViewTransitionActive) {
|
|
1324
|
+
this.pendingViewTransitionResync = true;
|
|
1269
1325
|
return;
|
|
1270
1326
|
}
|
|
1271
1327
|
this.updateViewportHeight();
|
|
@@ -1278,6 +1334,9 @@
|
|
|
1278
1334
|
const timeout = 500;
|
|
1279
1335
|
const poll = (time) => {
|
|
1280
1336
|
this.scheduleTimeout(() => {
|
|
1337
|
+
if (!this.state.viewer.isOpen) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1281
1340
|
if (prevWidth !== getWindowWidth2()) {
|
|
1282
1341
|
this.updateViewportHeight();
|
|
1283
1342
|
this.resetTranslateCurrent();
|
|
@@ -1376,10 +1435,14 @@
|
|
|
1376
1435
|
this.destroy();
|
|
1377
1436
|
}
|
|
1378
1437
|
gotoSlide(index) {
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1438
|
+
var _a, _b;
|
|
1439
|
+
const parsed = Number.parseInt(String(index), 10);
|
|
1440
|
+
const next = Number.isNaN(parsed) ? 0 : parsed;
|
|
1441
|
+
const total = (_b = (_a = currentItems(this.state)) == null ? void 0 : _a.length) != null ? _b : 0;
|
|
1442
|
+
if (next < 0 || next >= total) {
|
|
1443
|
+
return;
|
|
1382
1444
|
}
|
|
1445
|
+
this.state.viewer.currentIndex = next;
|
|
1383
1446
|
this.slideList();
|
|
1384
1447
|
}
|
|
1385
1448
|
hidePhoto(dir = "bottom") {
|
|
@@ -1430,10 +1493,26 @@
|
|
|
1430
1493
|
this.state.viewer.photoPosY = 0;
|
|
1431
1494
|
this.view.updatePhotoTransform(this.state);
|
|
1432
1495
|
this.scheduleTimeout(() => {
|
|
1496
|
+
if (!this.state.viewer.isOpen) {
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1433
1499
|
this.state.viewer.scale = true;
|
|
1434
1500
|
this.view.updatePhotoTransform(this.state);
|
|
1435
1501
|
this.fireEvent("zoomin");
|
|
1436
|
-
},
|
|
1502
|
+
}, this.state.options.animationSpeed);
|
|
1503
|
+
}
|
|
1504
|
+
// zoomPhoto() と同じ「ズームの余地があるか」の判定(scaleBorder <= 1 なら
|
|
1505
|
+
// ズームしても見た目が変わらない)。zoomPhoto() 自体は公開 API の契約
|
|
1506
|
+
// (ズームできなければ何もしない)を保つ必要があるため、タップの
|
|
1507
|
+
// zoom-or-close 分岐(§7)用に判定だけを切り出している
|
|
1508
|
+
canZoomCurrentPhoto() {
|
|
1509
|
+
const item = currentItem(this.state);
|
|
1510
|
+
return !!item && scaleBorder(
|
|
1511
|
+
item,
|
|
1512
|
+
getWindowWidth2(),
|
|
1513
|
+
getWindowHeight2(),
|
|
1514
|
+
this.isSmartPhoneFlag
|
|
1515
|
+
) > 1;
|
|
1437
1516
|
}
|
|
1438
1517
|
zoomOutPhoto() {
|
|
1439
1518
|
this.state.viewer.scaleSize = 1;
|
|
@@ -1644,6 +1723,7 @@
|
|
|
1644
1723
|
this.state.options.headerHeight,
|
|
1645
1724
|
this.state.options.footerHeight
|
|
1646
1725
|
);
|
|
1726
|
+
this.syncFillScale();
|
|
1647
1727
|
}
|
|
1648
1728
|
// resize/orientationchange ハンドラは呼び出し前に currentItems の存在を確認済み
|
|
1649
1729
|
resetTranslateCurrent() {
|
|
@@ -1657,9 +1737,18 @@
|
|
|
1657
1737
|
}
|
|
1658
1738
|
return null;
|
|
1659
1739
|
}
|
|
1740
|
+
currentLiElement() {
|
|
1741
|
+
for (const [item, slideRefs] of this.view.refs.slides) {
|
|
1742
|
+
if (item.index === this.state.viewer.currentIndex) {
|
|
1743
|
+
return slideRefs.li;
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
return null;
|
|
1747
|
+
}
|
|
1660
1748
|
// ---- 内部: dialog 制御(§8) ----
|
|
1661
1749
|
syncDialog() {
|
|
1662
1750
|
const { dialog, caption } = this.view.refs;
|
|
1751
|
+
dialog.style.transition = this.state.options.showAnimation === false ? "none" : "";
|
|
1663
1752
|
if (this.state.viewer.isOpen && !dialog.open) {
|
|
1664
1753
|
dialog.style.removeProperty("display");
|
|
1665
1754
|
dialog.showModal();
|
|
@@ -1671,6 +1760,7 @@
|
|
|
1671
1760
|
}
|
|
1672
1761
|
commit() {
|
|
1673
1762
|
this.view.render(this.state);
|
|
1763
|
+
this.view.updatePhotoTransform(this.state);
|
|
1674
1764
|
this.syncDialog();
|
|
1675
1765
|
}
|
|
1676
1766
|
// ---- 内部: 開く演出 ----
|
|
@@ -1689,20 +1779,34 @@
|
|
|
1689
1779
|
this.setPosByCurrentIndex();
|
|
1690
1780
|
this.setSizeByScreen();
|
|
1691
1781
|
setArrow(this.state);
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
getWindowHeight2(),
|
|
1700
|
-
this.isSmartPhoneFlag
|
|
1701
|
-
);
|
|
1782
|
+
}
|
|
1783
|
+
// resizeStyle: 'fill' はスマートフォンでのみ、画面を隙間なく覆うよう
|
|
1784
|
+
// scaleBorder() の倍率を viewer.scaleSize に適用する。fit用の item.scale に
|
|
1785
|
+
// 依存するため、setSizeByScreen() の末尾から必ず呼ばれる(個別に呼ぶ必要はない)
|
|
1786
|
+
syncFillScale() {
|
|
1787
|
+
if (this.state.options.resizeStyle !== "fill" || !this.isSmartPhoneFlag) {
|
|
1788
|
+
return;
|
|
1702
1789
|
}
|
|
1790
|
+
const item = currentItem(this.state);
|
|
1791
|
+
if (!item) {
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1794
|
+
this.state.viewer.scale = true;
|
|
1795
|
+
this.state.viewer.hideUi = true;
|
|
1796
|
+
this.state.viewer.scaleSize = scaleBorder(
|
|
1797
|
+
item,
|
|
1798
|
+
getWindowWidth2(),
|
|
1799
|
+
getWindowHeight2(),
|
|
1800
|
+
this.isSmartPhoneFlag
|
|
1801
|
+
);
|
|
1703
1802
|
}
|
|
1704
1803
|
supportsViewTransition() {
|
|
1705
|
-
return typeof document.startViewTransition === "function"
|
|
1804
|
+
return this.state.options.useViewTransitionApi && typeof document.startViewTransition === "function" && // WebKit には「view-transition-name 付き要素が root スナップショットから
|
|
1805
|
+
// 除外されず、モーフ中に最終位置へ二重描画される」実装バグがあり、開く演出が
|
|
1806
|
+
// 「一旦ずれた位置に出てから正位置へ戻る」ように乱れる。API 対応の有無では
|
|
1807
|
+
// 検出できないため、WebKit ではクローン演出(addAppearEffect)へフォールバック
|
|
1808
|
+
// する(§util.isWebKit)
|
|
1809
|
+
!isWebKit();
|
|
1706
1810
|
}
|
|
1707
1811
|
openPhotoWithViewTransition(trigger) {
|
|
1708
1812
|
var _a, _b;
|
|
@@ -1715,7 +1819,8 @@
|
|
|
1715
1819
|
if (thumbImg) {
|
|
1716
1820
|
thumbImg.style.viewTransitionName = transitionName;
|
|
1717
1821
|
}
|
|
1718
|
-
const
|
|
1822
|
+
const cleanup = () => {
|
|
1823
|
+
this.isViewTransitionActive = false;
|
|
1719
1824
|
if (thumbImg) {
|
|
1720
1825
|
thumbImg.style.viewTransitionName = "";
|
|
1721
1826
|
}
|
|
@@ -1723,6 +1828,21 @@
|
|
|
1723
1828
|
if (img) {
|
|
1724
1829
|
img.style.viewTransitionName = "";
|
|
1725
1830
|
}
|
|
1831
|
+
if (!this.state.viewer.isOpen) {
|
|
1832
|
+
this.pendingViewTransitionResync = false;
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1835
|
+
if (this.pendingViewTransitionResync && currentItems(this.state)) {
|
|
1836
|
+
this.pendingViewTransitionResync = false;
|
|
1837
|
+
this.updateViewportHeight();
|
|
1838
|
+
this.resetTranslateCurrent();
|
|
1839
|
+
this.setPosByCurrentIndex();
|
|
1840
|
+
this.setSizeByScreen();
|
|
1841
|
+
this.commit();
|
|
1842
|
+
return;
|
|
1843
|
+
}
|
|
1844
|
+
this.pendingViewTransitionResync = false;
|
|
1845
|
+
this.view.resetViewTransitionLayout();
|
|
1726
1846
|
};
|
|
1727
1847
|
const transition = (_b = document.startViewTransition) == null ? void 0 : _b.call(document, () => {
|
|
1728
1848
|
this.initPhoto();
|
|
@@ -1732,11 +1852,16 @@
|
|
|
1732
1852
|
thumbImg.style.viewTransitionName = "";
|
|
1733
1853
|
}
|
|
1734
1854
|
this.currentImgElement().style.viewTransitionName = transitionName;
|
|
1855
|
+
this.view.applyViewTransitionLayout(this.state);
|
|
1735
1856
|
});
|
|
1736
|
-
|
|
1737
|
-
|
|
1857
|
+
if (!transition) {
|
|
1858
|
+
return;
|
|
1859
|
+
}
|
|
1860
|
+
this.isViewTransitionActive = true;
|
|
1861
|
+
transition.ready.catch(() => {
|
|
1862
|
+
cleanup();
|
|
1738
1863
|
});
|
|
1739
|
-
transition
|
|
1864
|
+
transition.finished.then(cleanup, cleanup);
|
|
1740
1865
|
}
|
|
1741
1866
|
// doOpen() の呼び出し元でこの分岐に来る時点で showAnimation !== false が保証されている
|
|
1742
1867
|
addAppearEffect(trigger, item) {
|
|
@@ -1846,10 +1971,14 @@
|
|
|
1846
1971
|
if (getWindowWidth2() === winWidthBefore && getWindowHeight2() === winHeightBefore) {
|
|
1847
1972
|
return;
|
|
1848
1973
|
}
|
|
1974
|
+
if (this.isViewTransitionActive) {
|
|
1975
|
+
this.pendingViewTransitionResync = true;
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1849
1978
|
this.resetTranslateCurrent();
|
|
1850
1979
|
this.setPosByCurrentIndex();
|
|
1851
1980
|
this.setSizeByScreen();
|
|
1852
|
-
this.
|
|
1981
|
+
this.commit();
|
|
1853
1982
|
});
|
|
1854
1983
|
}
|
|
1855
1984
|
openPhoto(item, trigger) {
|
|
@@ -1871,21 +2000,37 @@
|
|
|
1871
2000
|
}
|
|
1872
2001
|
doHideEffect(dir) {
|
|
1873
2002
|
return new Promise((resolve) => {
|
|
2003
|
+
if (this.state.options.showAnimation === false) {
|
|
2004
|
+
resolve();
|
|
2005
|
+
return;
|
|
2006
|
+
}
|
|
1874
2007
|
const dialog = this.view.refs.dialog;
|
|
1875
|
-
const
|
|
2008
|
+
const item = currentItem(this.state);
|
|
2009
|
+
const li = item ? this.currentLiElement() : null;
|
|
1876
2010
|
const height = getWindowHeight2();
|
|
1877
|
-
const
|
|
2011
|
+
const img = this.currentImgElement();
|
|
2012
|
+
let frozenTransform = null;
|
|
1878
2013
|
if (img) {
|
|
1879
|
-
img.
|
|
2014
|
+
const rendered = getComputedStyle(img).transform;
|
|
2015
|
+
if (rendered && rendered !== "none") {
|
|
2016
|
+
img.style.transform = rendered;
|
|
2017
|
+
frozenTransform = img.style.transform;
|
|
2018
|
+
}
|
|
1880
2019
|
}
|
|
1881
|
-
|
|
1882
|
-
|
|
2020
|
+
if (li && item) {
|
|
2021
|
+
const offsetY = dir === "top" ? -height : height;
|
|
2022
|
+
li.style.transform = `translate(${item.translateX}px,${item.translateY + offsetY}px)`;
|
|
2023
|
+
}
|
|
2024
|
+
const finish = (e) => {
|
|
1883
2025
|
if (this.finishHideEffect !== finish) {
|
|
1884
2026
|
return;
|
|
1885
2027
|
}
|
|
2028
|
+
if (e && e.target !== dialog) {
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
1886
2031
|
this.finishHideEffect = null;
|
|
1887
2032
|
dialog.removeEventListener("transitionend", finish, true);
|
|
1888
|
-
if (img && img.style.transform ===
|
|
2033
|
+
if (img && frozenTransform && img.style.transform === frozenTransform) {
|
|
1889
2034
|
img.style.transform = "";
|
|
1890
2035
|
}
|
|
1891
2036
|
resolve();
|
|
@@ -1961,7 +2106,9 @@
|
|
|
1961
2106
|
const item = currentItem(this.state);
|
|
1962
2107
|
this.state.viewer.onMove = false;
|
|
1963
2108
|
setArrow(this.state);
|
|
1964
|
-
this.
|
|
2109
|
+
if (this.state.viewer.isOpen) {
|
|
2110
|
+
this.commit();
|
|
2111
|
+
}
|
|
1965
2112
|
if (this.state.viewer.oldIndex !== this.state.viewer.currentIndex) {
|
|
1966
2113
|
this.fireEvent("change");
|
|
1967
2114
|
}
|
|
@@ -2046,7 +2193,21 @@
|
|
|
2046
2193
|
}
|
|
2047
2194
|
this.slideList();
|
|
2048
2195
|
},
|
|
2049
|
-
|
|
2196
|
+
// 主要ライトボックスのデファクトスタンダード(PhotoSwipe: bgClickAction
|
|
2197
|
+
// 'close' / imageClickAction 'zoom-or-close'、Fancybox: backdropClick
|
|
2198
|
+
// 'close'、GLightbox: closeOnOutsideClick、lightGallery: closable)に合わせ、
|
|
2199
|
+
// 写真の上のタップはズーム、写真の外(背景)のタップは閉じる。ズームの
|
|
2200
|
+
// 余地がない(scaleBorder <= 1 で zoomPhoto() が何もしない)写真の上の
|
|
2201
|
+
// タップも、無反応にせず 'zoom-or-close' に倣って閉じる
|
|
2202
|
+
onTap: (target) => {
|
|
2203
|
+
const img = this.currentImgElement();
|
|
2204
|
+
const onPhoto = !!img && target instanceof Node && img.contains(target);
|
|
2205
|
+
if (onPhoto && this.canZoomCurrentPhoto()) {
|
|
2206
|
+
this.zoomPhoto();
|
|
2207
|
+
} else {
|
|
2208
|
+
this.hidePhoto();
|
|
2209
|
+
}
|
|
2210
|
+
},
|
|
2050
2211
|
onGestureStart: () => {
|
|
2051
2212
|
this.fireEvent("gesturestart");
|
|
2052
2213
|
this.view.updatePhotoTransform(this.state);
|