smartphoto 2.1.2 → 2.1.4
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 -1
- package/css/smartphoto.css +78 -10
- package/css/smartphoto.min.css +1 -1
- package/js/jquery-smartphoto.js +59 -4
- package/js/jquery-smartphoto.min.js +2 -2
- package/js/smartphoto.js +59 -4
- package/js/smartphoto.min.js +2 -2
- package/lib/smartphoto.js +58 -3
- package/lib/smartphoto.mjs +58 -3
- package/lib/types/core/index.d.ts +1 -0
- package/lib/types/core/types.d.ts +1 -0
- package/package.json +10 -8
- package/css/smartphoto.css.map +0 -1
package/README.md
CHANGED
|
@@ -17,7 +17,6 @@ If you are Japasese, See here [https://www.appleple.com/blog/javascript/smartpho
|
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
19
19
|
- [npm](https://www.npmjs.com/package/smartphoto)
|
|
20
|
-
- [standalone](https://raw.githubusercontent.com/appleple/smart-photo/master/js/smartphoto.js)
|
|
21
20
|
|
|
22
21
|
via npm
|
|
23
22
|
```shell
|
|
@@ -189,6 +188,11 @@ Slide fields:
|
|
|
189
188
|
<td>minimum swipe distance (px) to trigger navigation/close</td>
|
|
190
189
|
<td>100</td>
|
|
191
190
|
</tr>
|
|
191
|
+
<tr>
|
|
192
|
+
<td>swipeVelocity</td>
|
|
193
|
+
<td>minimum swipe speed (px/ms) that triggers navigation even below swipeOffset (fast flicks)</td>
|
|
194
|
+
<td>0.5</td>
|
|
195
|
+
</tr>
|
|
192
196
|
<tr>
|
|
193
197
|
<td>headerHeight</td>
|
|
194
198
|
<td>height (px) reserved for the header when fitting images</td>
|
package/css/smartphoto.css
CHANGED
|
@@ -2,26 +2,32 @@
|
|
|
2
2
|
from {
|
|
3
3
|
opacity: 0;
|
|
4
4
|
}
|
|
5
|
+
|
|
5
6
|
to {
|
|
6
7
|
opacity: 1;
|
|
7
8
|
}
|
|
8
9
|
}
|
|
10
|
+
|
|
9
11
|
@keyframes smartphoto-img-wrap {
|
|
10
12
|
from {
|
|
11
13
|
opacity: 0;
|
|
12
14
|
}
|
|
15
|
+
|
|
13
16
|
to {
|
|
14
17
|
opacity: 1;
|
|
15
18
|
}
|
|
16
19
|
}
|
|
20
|
+
|
|
17
21
|
@keyframes smartphoto-inner {
|
|
18
22
|
from {
|
|
19
23
|
transform: translate(0, 100px);
|
|
20
24
|
}
|
|
25
|
+
|
|
21
26
|
to {
|
|
22
27
|
transform: translate(0, 0);
|
|
23
28
|
}
|
|
24
29
|
}
|
|
30
|
+
|
|
25
31
|
@keyframes smartphoto-loader {
|
|
26
32
|
0% {
|
|
27
33
|
opacity: 0.4;
|
|
@@ -36,14 +42,23 @@
|
|
|
36
42
|
transform: rotate(360deg);
|
|
37
43
|
}
|
|
38
44
|
}
|
|
45
|
+
|
|
46
|
+
/* display の切り替えをキーフレーム内でアニメーションさせていた版は、閉じている間
|
|
47
|
+
* (dialog が display:none)にアニメーションのタイムラインが進まなくなり、再度開いた
|
|
48
|
+
* 際に 0%/1% の display:none で止まったままになる実機バグがあった(矢印/ナビが
|
|
49
|
+
* クリック不能になり、その下の背景をタップしたと判定されてモーダルが閉じてしまう)。
|
|
50
|
+
* 表示/非表示そのものは常に aria-hidden 属性のセレクタ側(下記)で確定させ、
|
|
51
|
+
* ここでは opacity のフェードのみをアニメーションする */
|
|
39
52
|
@keyframes smartphoto-appear {
|
|
40
53
|
0% {
|
|
41
54
|
opacity: 0;
|
|
42
55
|
}
|
|
56
|
+
|
|
43
57
|
100% {
|
|
44
58
|
opacity: 1;
|
|
45
59
|
}
|
|
46
60
|
}
|
|
61
|
+
|
|
47
62
|
@keyframes smartphoto-hide {
|
|
48
63
|
0% {
|
|
49
64
|
opacity: 1;
|
|
@@ -52,36 +67,72 @@
|
|
|
52
67
|
opacity: 0;
|
|
53
68
|
}
|
|
54
69
|
}
|
|
70
|
+
|
|
55
71
|
:root:has(dialog.smartphoto[open]) {
|
|
56
72
|
overflow: hidden;
|
|
57
73
|
}
|
|
58
74
|
|
|
75
|
+
/* dialogタグの表示制御 */
|
|
59
76
|
.smartphoto {
|
|
77
|
+
/* dialogタグのデフォルトスタイルをリセット */
|
|
60
78
|
border: none;
|
|
61
79
|
background: transparent;
|
|
62
80
|
padding: 0;
|
|
63
81
|
margin: 0;
|
|
64
82
|
outline: none;
|
|
83
|
+
/* 既存のスタイルを適用 */
|
|
65
84
|
position: fixed;
|
|
66
85
|
inset: 0;
|
|
67
86
|
width: 100%;
|
|
68
87
|
height: 100%;
|
|
69
88
|
max-width: 100%;
|
|
70
89
|
max-height: 100%;
|
|
90
|
+
/* dialog 自体には overflow の既定値が無く、子要素(nav/arrows 等)が僅かに
|
|
91
|
+
* ボックスを超えるだけで dialog 自身がスクロール可能になってしまう。
|
|
92
|
+
* 内側のスクロールは常に禁止し、外側の背景スクロール抑制(:root:has())と
|
|
93
|
+
* 合わせて完全に固定表示にする */
|
|
71
94
|
overflow: hidden;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
95
|
+
/* モバイルでスクロールに伴いアドレスバーが表示/非表示になり可視領域が変化しても
|
|
96
|
+
* 追従するよう、dvh (動的ビューポート高さ) を優先する
|
|
97
|
+
* (see: https://github.com/appleple/SmartPhoto/issues/90)。
|
|
98
|
+
* dvh はブラウザによってはアドレスバーの伸縮への追従が実装依存で不安定なため、
|
|
99
|
+
* JS で実測して設定する --smartphoto-vh (updateViewportHeight() 参照) があれば
|
|
100
|
+
* それを優先し、JS 無効時やブラウザ未対応時は height:100%/max-height:100% に
|
|
101
|
+
* フォールバックする */
|
|
102
|
+
height: var(--smartphoto-vh, 100dvh);
|
|
103
|
+
max-height: var(--smartphoto-vh, 100dvh);
|
|
104
|
+
background-color: var(--smartphoto-backdrop-color, rgba(0, 0, 0, 1));
|
|
75
105
|
opacity: 1;
|
|
76
106
|
font-family: sans-serif;
|
|
77
107
|
cursor: pointer;
|
|
78
|
-
|
|
108
|
+
/* close() は [open] 属性を外すと同時にネイティブに display:none / トップレイヤー
|
|
109
|
+
* からの除外を行う(§8)。display・overlay を allow-discrete で transition
|
|
110
|
+
* 対象に加えることで、opacity のフェードが完了するまでその適用を1フレーム分
|
|
111
|
+
* 遅らせ、閉じる瞬間に「ぱっと」消えず滑らかにフェードアウトするようにする */
|
|
112
|
+
transition:
|
|
113
|
+
opacity var(--smartphoto-animation-speed, 0.3s) var(--smartphoto-animation-function, ease-out),
|
|
114
|
+
display var(--smartphoto-animation-speed, 0.3s) var(--smartphoto-animation-function, ease-out) allow-discrete,
|
|
115
|
+
overlay var(--smartphoto-animation-speed, 0.3s) var(--smartphoto-animation-function, ease-out) allow-discrete;
|
|
79
116
|
}
|
|
117
|
+
|
|
80
118
|
.smartphoto:not([open]) {
|
|
81
119
|
opacity: 0;
|
|
82
120
|
}
|
|
121
|
+
|
|
83
122
|
.smartphoto::backdrop {
|
|
84
|
-
background-color: var(--smartphoto-backdrop-color,
|
|
123
|
+
background-color: var(--smartphoto-backdrop-color, rgba(0, 0, 0, 1));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* View Transition(openPhotoWithViewTransition() 参照)の疑似要素ツリーは document の
|
|
127
|
+
* ルート要素(html)の子として扱われ、dialog に設定した --smartphoto-animation-speed を
|
|
128
|
+
* 継承しない。そのため JS 側では document.documentElement にも同じ変数を設定しており、
|
|
129
|
+
* ここではその値を参照する。指定がなければブラウザ既定(実装依存, 概ね0.25s前後で
|
|
130
|
+
* 速すぎるとの声があった)の代わりに 0.3s を使う */
|
|
131
|
+
::view-transition-group(smartphoto-hero),
|
|
132
|
+
::view-transition-old(smartphoto-hero),
|
|
133
|
+
::view-transition-new(smartphoto-hero) {
|
|
134
|
+
animation-duration: var(--smartphoto-animation-speed, 0.3s);
|
|
135
|
+
animation-timing-function: var(--smartphoto-animation-function, ease-out);
|
|
85
136
|
}
|
|
86
137
|
|
|
87
138
|
.smartphoto-close {
|
|
@@ -114,6 +165,7 @@
|
|
|
114
165
|
left: 0;
|
|
115
166
|
width: 100%;
|
|
116
167
|
height: 100%;
|
|
168
|
+
/* Pointer Events(swipe/pinch)がブラウザ既定のスクロール・ズームと衝突しないようにする */
|
|
117
169
|
touch-action: none;
|
|
118
170
|
}
|
|
119
171
|
|
|
@@ -162,6 +214,7 @@
|
|
|
162
214
|
-ms-user-select: none;
|
|
163
215
|
user-select: none;
|
|
164
216
|
transition: transform var(--smartphoto-animation-speed, 0.3s) var(--smartphoto-animation-function, ease-out);
|
|
217
|
+
|
|
165
218
|
-webkit-user-drag: none;
|
|
166
219
|
}
|
|
167
220
|
|
|
@@ -182,6 +235,7 @@
|
|
|
182
235
|
.smartphoto-img-wrap {
|
|
183
236
|
display: inline-block;
|
|
184
237
|
opacity: 1;
|
|
238
|
+
/* Pointer Events(ピンチ/ドラッグ)がブラウザ既定のスクロール・ズームと衝突しないようにする */
|
|
185
239
|
touch-action: none;
|
|
186
240
|
-webkit-transition: opacity var(--smartphoto-animation-speed, 0.3s) var(--smartphoto-animation-function, ease-out);
|
|
187
241
|
-moz-transition: opacity var(--smartphoto-animation-speed, 0.3s) var(--smartphoto-animation-function, ease-out);
|
|
@@ -215,7 +269,7 @@
|
|
|
215
269
|
animation-timing-function: var(--smartphoto-animation-function, ease-out);
|
|
216
270
|
}
|
|
217
271
|
|
|
218
|
-
.smartphoto-arrows[aria-hidden=true] {
|
|
272
|
+
.smartphoto-arrows[aria-hidden='true'] {
|
|
219
273
|
animation-name: smartphoto-hide;
|
|
220
274
|
display: none;
|
|
221
275
|
}
|
|
@@ -232,16 +286,19 @@
|
|
|
232
286
|
animation-timing-function: var(--smartphoto-animation-function, ease-out);
|
|
233
287
|
animation-name: smartphoto-appear;
|
|
234
288
|
}
|
|
289
|
+
|
|
235
290
|
.smartphoto-arrows li:focus {
|
|
236
291
|
outline: none;
|
|
237
292
|
}
|
|
238
293
|
|
|
239
|
-
.smartphoto-arrows [aria-hidden=true] {
|
|
294
|
+
.smartphoto-arrows [aria-hidden='true'] {
|
|
240
295
|
animation-name: smartphoto-hide;
|
|
241
296
|
display: none;
|
|
242
297
|
}
|
|
243
298
|
|
|
244
299
|
.smartphoto-arrows button {
|
|
300
|
+
/* <button> の UA デフォルト(border/padding/背景/appearance)をリセットし、
|
|
301
|
+
* 旧 <a> と同じ「全面クリック領域 + 背景 SVG アイコン」の見た目を維持する */
|
|
245
302
|
appearance: none;
|
|
246
303
|
display: block;
|
|
247
304
|
width: 100%;
|
|
@@ -258,6 +315,7 @@
|
|
|
258
315
|
padding: 5px 0;
|
|
259
316
|
background-color: rgba(0, 0, 0, 0.5);
|
|
260
317
|
}
|
|
318
|
+
|
|
261
319
|
.smartphoto-arrow-right button {
|
|
262
320
|
background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiAiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTgzNy44OCwxNDE3LjMyLDY0My41OSwyMjNhNzIuMjEsNzIuMjEsMCwwLDEsMC0xMDEuODJMNzQzLjgyLDIxYTcyLjIxLDcyLjIxLDAsMCwxLDEwMS44MiwwTDIwOTAuODMsMTI2Ni4xOWwxMDAuMjMsMTAwLjIzYTcyLjIxLDcyLjIxLDAsMCwxLDAsMTAxLjgyTDg0NS42NCwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwxLTEwMS44MiwwTDY0My41OSwyNzEzLjQyYTcyLjIxLDcyLjIxLDAsMCwxLDAtMTAxLjgyWiIvPjwvc3ZnPg==);
|
|
263
321
|
}
|
|
@@ -267,6 +325,7 @@
|
|
|
267
325
|
padding: 5px 0;
|
|
268
326
|
background-color: rgba(0, 0, 0, 0.5);
|
|
269
327
|
}
|
|
328
|
+
|
|
270
329
|
.smartphoto-arrow-left button {
|
|
271
330
|
background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiI+PHRpdGxlPmljb248L3RpdGxlPjxwYXRoIGQ9Ik05OTYuNzcsMTQxNy4zMiwyMTkxLjA2LDIyM2E3Mi4yMSw3Mi4yMSwwLDAsMCwwLTEwMS44MkwyMDkwLjgzLDIxQTcyLjIxLDcyLjIxLDAsMCwwLDE5ODksMjFMNzQzLjgyLDEyNjYuMTksNjQzLjU5LDEzNjYuNDJhNzIuMjEsNzIuMjEsMCwwLDAsMCwxMDEuODJMMTk4OSwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwwLDEwMS44MiwwbDEwMC4yMy0xMDAuMjNhNzIuMjEsNzIuMjEsMCwwLDAsMC0xMDEuODJaIi8+PC9zdmc+);
|
|
272
331
|
}
|
|
@@ -286,7 +345,7 @@
|
|
|
286
345
|
animation-timing-function: var(--smartphoto-animation-function, ease-out);
|
|
287
346
|
}
|
|
288
347
|
|
|
289
|
-
.smartphoto-nav[aria-hidden=true] {
|
|
348
|
+
.smartphoto-nav[aria-hidden='true'] {
|
|
290
349
|
animation-name: smartphoto-hide;
|
|
291
350
|
display: none;
|
|
292
351
|
}
|
|
@@ -299,6 +358,7 @@
|
|
|
299
358
|
padding: 0;
|
|
300
359
|
text-align: center;
|
|
301
360
|
white-space: nowrap;
|
|
361
|
+
|
|
302
362
|
-webkit-overflow-scrolling: touch;
|
|
303
363
|
}
|
|
304
364
|
|
|
@@ -310,6 +370,8 @@
|
|
|
310
370
|
}
|
|
311
371
|
|
|
312
372
|
.smartphoto-nav button {
|
|
373
|
+
/* <button> の UA デフォルト(border/padding/appearance)をリセットし、
|
|
374
|
+
* 旧 <a> と同じサムネイル背景画像ボタンの見た目を維持する */
|
|
313
375
|
appearance: none;
|
|
314
376
|
display: block;
|
|
315
377
|
width: 100%;
|
|
@@ -323,6 +385,7 @@
|
|
|
323
385
|
opacity: 0.5;
|
|
324
386
|
cursor: pointer;
|
|
325
387
|
}
|
|
388
|
+
|
|
326
389
|
.smartphoto-nav button:focus {
|
|
327
390
|
opacity: 0.8;
|
|
328
391
|
}
|
|
@@ -346,6 +409,7 @@
|
|
|
346
409
|
padding: 0;
|
|
347
410
|
white-space: nowrap;
|
|
348
411
|
}
|
|
412
|
+
|
|
349
413
|
.smartphoto-list li {
|
|
350
414
|
display: block;
|
|
351
415
|
position: absolute;
|
|
@@ -355,6 +419,7 @@
|
|
|
355
419
|
height: 100%;
|
|
356
420
|
transition: all var(--smartphoto-animation-speed, 0.3s) var(--smartphoto-animation-function, ease-out);
|
|
357
421
|
}
|
|
422
|
+
|
|
358
423
|
.smartphoto-list li:focus {
|
|
359
424
|
outline: none;
|
|
360
425
|
}
|
|
@@ -381,6 +446,7 @@
|
|
|
381
446
|
margin: 0;
|
|
382
447
|
font-weight: normal;
|
|
383
448
|
}
|
|
449
|
+
|
|
384
450
|
.smartphoto-caption:focus {
|
|
385
451
|
outline: none;
|
|
386
452
|
}
|
|
@@ -392,7 +458,11 @@
|
|
|
392
458
|
width: 0;
|
|
393
459
|
height: 0;
|
|
394
460
|
transform: translate(50vw, 50vh);
|
|
461
|
+
/* dvh 対応ブラウザでは動的ビューポート高さを基準に中央寄せする
|
|
462
|
+
* (see: https://github.com/appleple/SmartPhoto/issues/90)。
|
|
463
|
+
* --smartphoto-vh (updateViewportHeight() 参照) が設定されていればそちらを優先する(§) */
|
|
395
464
|
transform: translate(50vw, 50dvh);
|
|
465
|
+
transform: translate(50vw, calc(var(--smartphoto-vh, 100dvh) / 2));
|
|
396
466
|
}
|
|
397
467
|
|
|
398
468
|
.smartphoto-loader {
|
|
@@ -428,5 +498,3 @@
|
|
|
428
498
|
border: 0;
|
|
429
499
|
clip: rect(0, 0, 0, 0);
|
|
430
500
|
}
|
|
431
|
-
|
|
432
|
-
/*# sourceMappingURL=smartphoto.css.map */
|
package/css/smartphoto.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@keyframes smartphoto{
|
|
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,.3s) var(--smartphoto-animation-function,ease-out),display var(--smartphoto-animation-speed,.3s) var(--smartphoto-animation-function,ease-out) allow-discrete,overlay var(--smartphoto-animation-speed,.3s) var(--smartphoto-animation-function,ease-out) allow-discrete}.smartphoto:not([open]){opacity:0}.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,.3s);animation-timing-function:var(--smartphoto-animation-function,ease-out)}.smartphoto-close{opacity:0}.smartphoto-count{display:inline-block;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:transparent;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHZpZXdCb3g9IjAgMCAyODM0LjY1IDI4MzQuNjUiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTU3Ni40MiAxNDA2Ljc2IDI3ODQgMTk5LjE5YTU2Ljg2IDU2Ljg2IDAgMCAwIDAtODAuMThsLTc4LjkyLTc4LjkyYTU2Ljg2IDU2Ljg2IDAgMCAwLTgwLjE4IDBMMTQxNy4zMiAxMjQ3LjY2IDIwOS43NSA0MC4wOWE1Ni44NiA1Ni44NiAwIDAgMC04MC4xOCAwTDUwLjY1IDExOWE1Ni44NiA1Ni44NiAwIDAgMCAwIDgwLjE4bDEyMDcuNTggMTIwNy41OEw1MC42NSAyNjE0LjM0YTU2Ljg2IDU2Ljg2IDAgMCAwIDAgODAuMThsNzguOTIgNzguOTJhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGwxMjA3LjU3LTEyMDcuNThMMjYyNC45IDI3NzMuNDRhNTYuODYgNTYuODYgMCAwIDAgODAuMTggMGw3OC45Mi03OC45MmE1Ni44NiA1Ni44NiAwIDAgMCAwLTgwLjE4WiIvPjwvc3ZnPg==);text-shadow:0 1px 0 #fff;color:#fff;font-size:30px;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,.3s) 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,.3s) var(--smartphoto-animation-function,ease-out)}.smartphoto-img-wrap{display:inline-block;opacity:1;touch-action:none;-webkit-transition:opacity var(--smartphoto-animation-speed,.3s) var(--smartphoto-animation-function,ease-out);-moz-transition:opacity var(--smartphoto-animation-speed,.3s) var(--smartphoto-animation-function,ease-out);-ms-transition:opacity var(--smartphoto-animation-speed,.3s) var(--smartphoto-animation-function,ease-out);-o-transition:opacity var(--smartphoto-animation-speed,.3s) var(--smartphoto-animation-function,ease-out);transition:opacity var(--smartphoto-animation-speed,.3s) var(--smartphoto-animation-function,ease-out);animation-name:smartphoto-img-wrap;animation-duration:var(--smartphoto-animation-speed,.3s);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,.3s);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:50%;width:30px;height:30px;margin-top:-20px;box-sizing:content-box;animation-duration:var(--smartphoto-animation-speed,.3s);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%;opacity:1;animation-name:smartphoto-appear;animation-duration:var(--smartphoto-animation-speed,.3s);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,.3s) 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:#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,.3s) 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.4
|
|
3
3
|
* (c) appleple
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
swipeTopToClose: false,
|
|
107
107
|
swipeBottomToClose: true,
|
|
108
108
|
swipeOffset: 100,
|
|
109
|
+
swipeVelocity: 0.5,
|
|
109
110
|
headerHeight: 60,
|
|
110
111
|
footerHeight: 60,
|
|
111
112
|
forceInterval: 10,
|
|
@@ -366,6 +367,7 @@
|
|
|
366
367
|
const y = p1.y - p2.y;
|
|
367
368
|
return Math.sqrt(x * x + y * y);
|
|
368
369
|
}
|
|
370
|
+
var MIN_FLICK_DISTANCE = 10;
|
|
369
371
|
function getForceAndTheta(x, y) {
|
|
370
372
|
return { force: Math.sqrt(x * x + y * y), theta: Math.atan2(y, x) };
|
|
371
373
|
}
|
|
@@ -383,6 +385,7 @@
|
|
|
383
385
|
let firstPos = null;
|
|
384
386
|
let oldPos = null;
|
|
385
387
|
let moveDir = null;
|
|
388
|
+
let swipeStartTime = 0;
|
|
386
389
|
let photoSwipable = false;
|
|
387
390
|
let firstPhotoPos = null;
|
|
388
391
|
let oldPhotoPos = null;
|
|
@@ -390,6 +393,7 @@
|
|
|
390
393
|
let photoVY = 0;
|
|
391
394
|
let pinching = false;
|
|
392
395
|
let oldDistance = 0;
|
|
396
|
+
let pinchMoveFrame = null;
|
|
393
397
|
let vx = 0;
|
|
394
398
|
let vy = 0;
|
|
395
399
|
function isSmartPhone2() {
|
|
@@ -511,6 +515,7 @@
|
|
|
511
515
|
dragStart = true;
|
|
512
516
|
firstPos = pos;
|
|
513
517
|
oldPos = pos;
|
|
518
|
+
swipeStartTime = Date.now();
|
|
514
519
|
}
|
|
515
520
|
function startPhotoDrag(e) {
|
|
516
521
|
photoSwipable = true;
|
|
@@ -535,6 +540,23 @@
|
|
|
535
540
|
}
|
|
536
541
|
startSwipe(e);
|
|
537
542
|
}
|
|
543
|
+
function scheduleGestureMove() {
|
|
544
|
+
if (pinchMoveFrame !== null) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
pinchMoveFrame = requestAnimationFrame(() => {
|
|
548
|
+
pinchMoveFrame = null;
|
|
549
|
+
callbacks.onGestureMove();
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
function flushGestureMove() {
|
|
553
|
+
if (pinchMoveFrame === null) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
cancelAnimationFrame(pinchMoveFrame);
|
|
557
|
+
pinchMoveFrame = null;
|
|
558
|
+
callbacks.onGestureMove();
|
|
559
|
+
}
|
|
538
560
|
function movePinch() {
|
|
539
561
|
const points = Array.from(activePointers.values());
|
|
540
562
|
const dist = distance(
|
|
@@ -559,7 +581,7 @@
|
|
|
559
581
|
state.viewer.hideUi = state.viewer.scaleSize < 1 || state.viewer.scaleSize > border;
|
|
560
582
|
}
|
|
561
583
|
oldDistance = dist;
|
|
562
|
-
|
|
584
|
+
scheduleGestureMove();
|
|
563
585
|
}
|
|
564
586
|
function moveSwipe(e) {
|
|
565
587
|
const pos = getPos(e);
|
|
@@ -608,6 +630,7 @@
|
|
|
608
630
|
}
|
|
609
631
|
function endPinch() {
|
|
610
632
|
pinching = false;
|
|
633
|
+
flushGestureMove();
|
|
611
634
|
const item = currentItem(state);
|
|
612
635
|
if (!item) {
|
|
613
636
|
return;
|
|
@@ -645,9 +668,11 @@
|
|
|
645
668
|
const items = (_a = currentItems(state)) != null ? _a : [];
|
|
646
669
|
if (moveDir === "horizontal") {
|
|
647
670
|
let result = "stay";
|
|
648
|
-
|
|
671
|
+
const elapsedMs = Math.max(now - swipeStartTime, 1);
|
|
672
|
+
const isFlick = Math.abs(swipeWidth) >= MIN_FLICK_DISTANCE && Math.abs(swipeWidth) / elapsedMs >= state.options.swipeVelocity;
|
|
673
|
+
if ((swipeWidth >= state.options.swipeOffset || isFlick && swipeWidth > 0) && state.viewer.currentIndex !== 0) {
|
|
649
674
|
result = "prev";
|
|
650
|
-
} else if (swipeWidth <= -state.options.swipeOffset && state.viewer.currentIndex !== items.length - 1) {
|
|
675
|
+
} else if ((swipeWidth <= -state.options.swipeOffset || isFlick && swipeWidth < 0) && state.viewer.currentIndex !== items.length - 1) {
|
|
651
676
|
result = "next";
|
|
652
677
|
}
|
|
653
678
|
callbacks.onSwipeEnd(result);
|
|
@@ -738,6 +763,10 @@
|
|
|
738
763
|
}
|
|
739
764
|
function detach() {
|
|
740
765
|
clearInterval(interval);
|
|
766
|
+
if (pinchMoveFrame !== null) {
|
|
767
|
+
cancelAnimationFrame(pinchMoveFrame);
|
|
768
|
+
pinchMoveFrame = null;
|
|
769
|
+
}
|
|
741
770
|
}
|
|
742
771
|
return { attach, detach };
|
|
743
772
|
}
|
|
@@ -1075,6 +1104,10 @@
|
|
|
1075
1104
|
return document.documentElement.clientWidth;
|
|
1076
1105
|
}
|
|
1077
1106
|
function getWindowHeight() {
|
|
1107
|
+
const visualViewport = window.visualViewport;
|
|
1108
|
+
if (visualViewport) {
|
|
1109
|
+
return visualViewport.height * visualViewport.scale;
|
|
1110
|
+
}
|
|
1078
1111
|
return document.documentElement.clientHeight;
|
|
1079
1112
|
}
|
|
1080
1113
|
function isElementArray(source) {
|
|
@@ -1107,6 +1140,12 @@
|
|
|
1107
1140
|
this.loadAllFired = /* @__PURE__ */ new Set();
|
|
1108
1141
|
this.syncedGroupId = null;
|
|
1109
1142
|
// ---- 内部: window イベント ----
|
|
1143
|
+
this.updateViewportHeight = () => {
|
|
1144
|
+
this.view.refs.dialog.style.setProperty(
|
|
1145
|
+
"--smartphoto-vh",
|
|
1146
|
+
`${getWindowHeight()}px`
|
|
1147
|
+
);
|
|
1148
|
+
};
|
|
1110
1149
|
this.handleResize = () => {
|
|
1111
1150
|
if (!currentItems(this.state)) {
|
|
1112
1151
|
return;
|
|
@@ -1186,6 +1225,18 @@
|
|
|
1186
1225
|
this.openPhoto(restored, null);
|
|
1187
1226
|
}
|
|
1188
1227
|
}
|
|
1228
|
+
this.updateViewportHeight();
|
|
1229
|
+
if (window.visualViewport) {
|
|
1230
|
+
window.visualViewport.addEventListener(
|
|
1231
|
+
"resize",
|
|
1232
|
+
this.updateViewportHeight,
|
|
1233
|
+
{ signal: this.abortController.signal }
|
|
1234
|
+
);
|
|
1235
|
+
} else {
|
|
1236
|
+
window.addEventListener("resize", this.updateViewportHeight, {
|
|
1237
|
+
signal: this.abortController.signal
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1189
1240
|
if (!this.isSmartPhoneFlag) {
|
|
1190
1241
|
window.addEventListener("resize", this.handleResize, {
|
|
1191
1242
|
signal: this.abortController.signal
|
|
@@ -1494,6 +1545,10 @@
|
|
|
1494
1545
|
}
|
|
1495
1546
|
openPhotoWithViewTransition(trigger) {
|
|
1496
1547
|
var _a, _b;
|
|
1548
|
+
document.documentElement.style.setProperty(
|
|
1549
|
+
"--smartphoto-animation-speed",
|
|
1550
|
+
`${this.state.options.animationSpeed}ms`
|
|
1551
|
+
);
|
|
1497
1552
|
const transitionName = "smartphoto-hero";
|
|
1498
1553
|
const thumbImg = (_a = trigger == null ? void 0 : trigger.querySelector("img")) != null ? _a : null;
|
|
1499
1554
|
if (thumbImg) {
|