intranet-pictures 2.1.0 → 3.0.0.rc1

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.
@@ -39,9 +39,14 @@
39
39
 
40
40
  .pswp__dynamic-caption--mobile {
41
41
  width: 100%;
42
- top: auto;
43
- right: 0;
44
- bottom: 0;
45
42
  background: rgba(0,0,0,0.5);
46
43
  padding: 10px 15px;
44
+
45
+ right: 0;
46
+ bottom: 0;
47
+
48
+ /* override styles that were set via JS.
49
+ as they interfere with size measurement */
50
+ top: auto !important;
51
+ left: 0 !important;
47
52
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * PhotoSwipe Dynamic Caption plugin v1.1.0
2
+ * PhotoSwipe Dynamic Caption plugin v1.2.7
3
3
  * https://github.com/dimsemenov/photoswipe-dynamic-caption-plugin
4
4
  *
5
5
  * By https://dimsemenov.com
@@ -11,6 +11,7 @@ const defaultOptions = {
11
11
  horizontalEdgeThreshold: 20,
12
12
  mobileCaptionOverlapRatio: 0.3,
13
13
  mobileLayoutBreakpoint: 600,
14
+ verticallyCenterImage: false
14
15
  };
15
16
 
16
17
  class PhotoSwipeDynamicCaption {
@@ -23,28 +24,8 @@ class PhotoSwipeDynamicCaption {
23
24
  this.lightbox = lightbox;
24
25
 
25
26
  this.lightbox.on('init', () => {
26
- this.initPlugin();
27
- });
28
- }
29
-
30
- initPlugin() {
31
- this.pswp = this.lightbox.pswp;
32
- this.isCaptionHidden = false;
33
- this.tempCaption = false;
34
- this.captionElement = false;
35
-
36
- this.pswp.on('uiRegister', () => {
37
- this.pswp.ui.registerElement({
38
- name: 'dynamic-caption',
39
- order: 9,
40
- isButton: false,
41
- appendTo: 'root',
42
- html: '',
43
- onInit: (el) => {
44
- this.captionElement = el;
45
- this.initCaption();
46
- }
47
- });
27
+ this.pswp = this.lightbox.pswp;
28
+ this.initCaption();
48
29
  });
49
30
  }
50
31
 
@@ -52,51 +33,72 @@ class PhotoSwipeDynamicCaption {
52
33
  const { pswp } = this;
53
34
 
54
35
  pswp.on('change', () => {
55
- this.updateCaptionHTML();
56
- this.updateCurrentCaptionPosition();
57
-
58
36
  // make sure caption is displayed after slides are switched
59
- this.showCaption();
37
+ this.showCaption(this.pswp.currSlide);
60
38
  });
61
39
 
62
40
  pswp.on('calcSlideSize', (e) => this.onCalcSlideSize(e));
63
41
 
64
- // hide caption if mainscroll is shifted (dragging)
65
- pswp.on('moveMainScroll', () => {
66
- if (!this.useMobileLayout()) {
67
- if (this.pswp.mainScroll.isShifted()) {
68
- this.hideCaption();
69
- } else {
70
- this.showCaption();
42
+ pswp.on('slideDestroy', (e) => {
43
+ if (e.slide.dynamicCaption) {
44
+ if (e.slide.dynamicCaption.element) {
45
+ e.slide.dynamicCaption.element.remove();
71
46
  }
47
+ delete e.slide.dynamicCaption;
72
48
  }
73
49
  });
74
50
 
75
51
  // hide caption if zoomed
76
- pswp.on('zoomPanUpdate', () => {
77
- if (pswp.currSlide.currZoomLevel > pswp.currSlide.zoomLevels.initial) {
78
- this.hideCaption();
79
- } else {
80
- this.showCaption();
52
+ pswp.on('zoomPanUpdate', ({ slide }) => {
53
+ if (pswp.opener.isOpen && slide.dynamicCaption) {
54
+ if (slide.currZoomLevel > slide.zoomLevels.initial) {
55
+ this.hideCaption(slide);
56
+ } else {
57
+ this.showCaption(slide);
58
+ }
59
+
60
+ // move caption on vertical drag
61
+ if (slide.dynamicCaption.element) {
62
+ let captionYOffset = 0;
63
+ if (slide.currZoomLevel <= slide.zoomLevels.initial) {
64
+ const shiftedAmount = slide.pan.y - slide.bounds.center.y;
65
+ if (Math.abs(shiftedAmount) > 1) {
66
+ captionYOffset = shiftedAmount;
67
+ }
68
+ }
69
+
70
+ this.setCaptionYOffset(slide.dynamicCaption.element, captionYOffset);
71
+ }
72
+
73
+ this.adjustPanArea(slide, slide.currZoomLevel);
81
74
  }
82
75
  });
83
76
 
84
77
  pswp.on('beforeZoomTo', (e) => {
85
- const { currSlide } = pswp;
78
+ this.adjustPanArea(pswp.currSlide, e.destZoomLevel);
79
+ });
86
80
 
87
- if (currSlide.__dcAdjustedPanAreaSize) {
88
- if (e.destZoomLevel > currSlide.zoomLevels.initial) {
89
- currSlide.panAreaSize.x = currSlide.__dcOriginalPanAreaSize.x;
90
- currSlide.panAreaSize.y = currSlide.__dcOriginalPanAreaSize.y;
91
- } else {
92
- // Restore panAreaSize after we zoom back to initial position
93
- currSlide.panAreaSize.x = currSlide.__dcAdjustedPanAreaSize.x;
94
- currSlide.panAreaSize.y = currSlide.__dcAdjustedPanAreaSize.y;
95
- }
81
+ // Stop default action of tap when tapping on the caption
82
+ pswp.on('tapAction', (e) => {
83
+ if (e.originalEvent.target.closest('.pswp__dynamic-caption')) {
84
+ e.preventDefault();
96
85
  }
97
86
  });
98
87
  }
99
88
 
89
+ adjustPanArea(slide, zoomLevel) {
90
+ if (slide.dynamicCaption && slide.dynamicCaption.adjustedPanAreaSize) {
91
+ if (zoomLevel > slide.zoomLevels.initial) {
92
+ slide.panAreaSize.x = slide.dynamicCaption.originalPanAreaSize.x;
93
+ slide.panAreaSize.y = slide.dynamicCaption.originalPanAreaSize.y;
94
+ } else {
95
+ // Restore panAreaSize after we zoom back to initial position
96
+ slide.panAreaSize.x = slide.dynamicCaption.adjustedPanAreaSize.x;
97
+ slide.panAreaSize.y = slide.dynamicCaption.adjustedPanAreaSize.y;
98
+ }
99
+ }
100
+ }
101
+
100
102
  useMobileLayout() {
101
103
  const { mobileLayoutBreakpoint } = this.options;
102
104
 
@@ -111,43 +113,59 @@ class PhotoSwipeDynamicCaption {
111
113
  return false;
112
114
  }
113
115
 
114
- hideCaption() {
115
- if (!this.isCaptionHidden) {
116
- this.isCaptionHidden = true;
117
- this.captionElement.classList.add('pswp__dynamic-caption--faded');
116
+ hideCaption(slide) {
117
+ if (slide.dynamicCaption && !slide.dynamicCaption.hidden) {
118
+ const captionElement = slide.dynamicCaption.element;
119
+
120
+ if (!captionElement) {
121
+ return;
122
+ }
123
+
124
+ slide.dynamicCaption.hidden = true;
125
+ captionElement.classList.add('pswp__dynamic-caption--faded');
118
126
 
119
127
  // Disable caption visibility with the delay, so it's not interactable
120
- if (this.captionFadeTimeout) {
121
- clearTimeout(this.captionFadeTimeout);
128
+ if (slide.captionFadeTimeout) {
129
+ clearTimeout(slide.captionFadeTimeout);
122
130
  }
123
- this.captionFadeTimeout = setTimeout(() => {
124
- this.captionElement.style.visibility = 'hidden';
125
- this.captionFadeTimeout = null;
131
+ slide.captionFadeTimeout = setTimeout(() => {
132
+ captionElement.style.visibility = 'hidden';
133
+ delete slide.captionFadeTimeout;
126
134
  }, 400);
127
135
  }
128
136
  }
129
137
 
130
- showCaption() {
131
- if (this.isCaptionHidden) {
132
- this.isCaptionHidden = false;
133
- this.captionElement.style.visibility = 'visible';
138
+ setCaptionYOffset(el, y) {
139
+ el.style.transform = `translateY(${y}px)`;
140
+ }
141
+
142
+ showCaption(slide) {
143
+ if (slide.dynamicCaption && slide.dynamicCaption.hidden) {
144
+ const captionElement = slide.dynamicCaption.element;
145
+
146
+ if (!captionElement) {
147
+ return;
148
+ }
149
+
150
+ slide.dynamicCaption.hidden = false;
151
+ captionElement.style.visibility = 'visible';
134
152
 
135
- clearTimeout(this.captionFadeTimeout);
136
- this.captionFadeTimeout = setTimeout(() => {
137
- this.captionElement.classList.remove('pswp__dynamic-caption--faded');
138
- this.captionFadeTimeout = null;
153
+ clearTimeout(slide.captionFadeTimeout);
154
+ slide.captionFadeTimeout = setTimeout(() => {
155
+ captionElement.classList.remove('pswp__dynamic-caption--faded');
156
+ delete slide.captionFadeTimeout;;
139
157
  }, 50);
140
158
  }
141
159
  }
142
160
 
143
- setCaptionPosition(x, y) {
161
+ setCaptionPosition(captionEl, x, y) {
144
162
  const isOnHorizontalEdge = (x <= this.options.horizontalEdgeThreshold);
145
- this.captionElement.classList[
163
+ captionEl.classList[
146
164
  isOnHorizontalEdge ? 'add' : 'remove'
147
165
  ]('pswp__dynamic-caption--on-hor-edge');
148
166
 
149
- this.captionElement.style.left = x + 'px';
150
- this.captionElement.style.top = y + 'px';
167
+ captionEl.style.left = x + 'px';
168
+ captionEl.style.top = y + 'px';
151
169
  }
152
170
 
153
171
  setCaptionWidth(captionEl, width) {
@@ -167,67 +185,84 @@ class PhotoSwipeDynamicCaption {
167
185
  }
168
186
  }
169
187
 
170
- updateCurrentCaptionPosition() {
171
- const slide = this.pswp.currSlide;
172
-
173
- if (!slide.dynamicCaptionType) {
188
+ updateCaptionPosition(slide) {
189
+ if (!slide.dynamicCaption || !slide.dynamicCaption.type || !slide.dynamicCaption.element) {
174
190
  return;
175
191
  }
176
192
 
177
- if (slide.dynamicCaptionType === 'mobile') {
178
- this.setCaptionType(this.captionElement, slide.dynamicCaptionType);
193
+ if (slide.dynamicCaption.type === 'mobile') {
194
+ this.setCaptionType(
195
+ slide.dynamicCaption.element,
196
+ slide.dynamicCaption.type
197
+ );
179
198
 
180
- this.captionElement.style.removeProperty('left');
181
- this.captionElement.style.removeProperty('top');
182
- this.setCaptionWidth(this.captionElement, false);
199
+ slide.dynamicCaption.element.style.removeProperty('left');
200
+ slide.dynamicCaption.element.style.removeProperty('top');
201
+ this.setCaptionWidth(slide.dynamicCaption.element, false);
183
202
  return;
184
203
  }
185
204
 
186
205
  const zoomLevel = slide.zoomLevels.initial;
187
206
  const imageWidth = Math.ceil(slide.width * zoomLevel);
188
207
  const imageHeight = Math.ceil(slide.height * zoomLevel);
189
-
190
208
 
191
- this.setCaptionType(this.captionElement, slide.dynamicCaptionType);
192
- if (slide.dynamicCaptionType === 'aside') {
209
+ this.setCaptionType(slide.dynamicCaption.element, slide.dynamicCaption.type);
210
+ if (slide.dynamicCaption.type === 'aside') {
193
211
  this.setCaptionPosition(
194
- this.pswp.currSlide.bounds.center.x + imageWidth,
195
- this.pswp.currSlide.bounds.center.y
212
+ slide.dynamicCaption.element,
213
+ slide.bounds.center.x + imageWidth,
214
+ slide.bounds.center.y
196
215
  );
197
- this.setCaptionWidth(this.captionElement, false);
198
- } else if (slide.dynamicCaptionType === 'below') {
216
+ this.setCaptionWidth(slide.dynamicCaption.element, false);
217
+ } else if (slide.dynamicCaption.type === 'below') {
199
218
  this.setCaptionPosition(
200
- this.pswp.currSlide.bounds.center.x,
201
- this.pswp.currSlide.bounds.center.y + imageHeight
219
+ slide.dynamicCaption.element,
220
+ slide.bounds.center.x,
221
+ slide.bounds.center.y + imageHeight
202
222
  );
203
- this.setCaptionWidth(this.captionElement, imageWidth);
223
+ this.setCaptionWidth(slide.dynamicCaption.element, imageWidth);
204
224
  }
205
225
  }
206
226
 
207
- /**
208
- * Temporary caption is used to measure size for the current/next/previous captions,
209
- * (it has visibility:hidden)
210
- */
211
- createTemporaryCaption() {
212
- this.tempCaption = document.createElement('div');
213
- this.tempCaption.className = 'pswp__dynamic-caption pswp__dynamic-caption--temp';
214
- this.tempCaption.style.visibility = 'hidden';
215
- this.tempCaption.setAttribute('aria-hidden', 'true');
216
- // move caption element, so it's after BG,
217
- // so that other controls can freely overlap it
218
- this.pswp.bg.after(this.captionElement);
219
- this.captionElement.after(this.tempCaption);
220
- }
221
-
222
227
  onCalcSlideSize(e) {
223
228
  const { slide } = e;
224
-
225
- const captionHTML = this.getCaptionHTML(e.slide);
226
- let useMobileVersion = false;
227
229
  let captionSize;
230
+ let useMobileVersion;
231
+
232
+ if (!slide.dynamicCaption) {
233
+ slide.dynamicCaption = {
234
+ element: undefined,
235
+ type: false,
236
+ hidden: false
237
+ };
238
+ } // INTRANET-CHANGE: even if the slide already has a caption, reevaluate its content
239
+
240
+ const captionHTML = this.getCaptionHTML(slide);
228
241
 
229
242
  if (!captionHTML) {
230
- slide.dynamicCaptionType = false;
243
+ return;
244
+ }
245
+
246
+ // INTRANET-CHANGE: remove previous element from DOM, if required
247
+ if (e.slide.dynamicCaption.element) {
248
+ if (captionHTML != slide.dynamicCaption.element.innerHTML) {
249
+ e.slide.dynamicCaption.element.remove();
250
+ }
251
+ }
252
+
253
+ slide.dynamicCaption.element = document.createElement('div');
254
+ slide.dynamicCaption.element.className = 'pswp__dynamic-caption pswp__hide-on-close';
255
+ slide.dynamicCaption.element.innerHTML = captionHTML;
256
+
257
+ this.pswp.dispatch('dynamicCaptionUpdateHTML', {
258
+ captionElement: slide.dynamicCaption.element,
259
+ slide
260
+ });
261
+
262
+ slide.holderElement.appendChild(slide.dynamicCaption.element);
263
+ //}
264
+
265
+ if (!slide.dynamicCaption.element) {
231
266
  return;
232
267
  }
233
268
 
@@ -236,33 +271,32 @@ class PhotoSwipeDynamicCaption {
236
271
  slide.bounds.update(slide.zoomLevels.initial);
237
272
 
238
273
  if (this.useMobileLayout()) {
239
- slide.dynamicCaptionType = 'mobile';
274
+ slide.dynamicCaption.type = 'mobile';
240
275
  useMobileVersion = true;
241
276
  } else {
242
277
  if (this.options.type === 'auto') {
243
278
  if (slide.bounds.center.x > slide.bounds.center.y) {
244
- slide.dynamicCaptionType = 'aside';
279
+ slide.dynamicCaption.type = 'aside';
245
280
  } else {
246
- slide.dynamicCaptionType = 'below';
281
+ slide.dynamicCaption.type = 'below';
247
282
  }
248
283
  } else {
249
- slide.dynamicCaptionType = this.options.type;
284
+ slide.dynamicCaption.type = this.options.type;
250
285
  }
251
286
  }
252
287
 
253
288
  const imageWidth = Math.ceil(slide.width * slide.zoomLevels.initial);
254
289
  const imageHeight = Math.ceil(slide.height * slide.zoomLevels.initial);
255
290
 
256
- if (!this.tempCaption) {
257
- this.createTemporaryCaption();
258
- }
291
+ this.setCaptionType(
292
+ slide.dynamicCaption.element,
293
+ slide.dynamicCaption.type
294
+ );
259
295
 
260
- this.setCaptionType(this.tempCaption, slide.dynamicCaptionType);
296
+ if (slide.dynamicCaption.type === 'aside') {
297
+ this.setCaptionWidth(slide.dynamicCaption.element, false);
298
+ captionSize = this.measureCaptionSize(slide.dynamicCaption.element, e.slide);
261
299
 
262
- if (slide.dynamicCaptionType === 'aside') {
263
- this.tempCaption.innerHTML = this.getCaptionHTML(e.slide);
264
- this.setCaptionWidth(this.tempCaption, false);
265
- captionSize = this.measureCaptionSize(this.tempCaption, e.slide);
266
300
  const captionWidth = captionSize.x;
267
301
 
268
302
  const horizontalEnding = imageWidth + slide.bounds.center.x;
@@ -274,60 +308,53 @@ class PhotoSwipeDynamicCaption {
274
308
  } else {
275
309
  // do nothing, caption will fit aside without any adjustments
276
310
  }
277
- } else if (slide.dynamicCaptionType === 'below' || useMobileVersion) {
311
+ } else if (slide.dynamicCaption.type === 'below' || useMobileVersion) {
278
312
  this.setCaptionWidth(
279
- this.tempCaption,
313
+ slide.dynamicCaption.element,
280
314
  useMobileVersion ? this.pswp.viewportSize.x : imageWidth
281
315
  );
282
- this.tempCaption.innerHTML = this.getCaptionHTML(e.slide);
283
- captionSize = this.measureCaptionSize(this.tempCaption, e.slide);
316
+
317
+ captionSize = this.measureCaptionSize(slide.dynamicCaption.element, e.slide);
284
318
  const captionHeight = captionSize.y;
285
319
 
320
+ if (this.options.verticallyCenterImage) {
321
+ slide.panAreaSize.y -= captionHeight;
322
+ this.recalculateZoomLevelAndBounds(slide);
323
+ } else {
324
+ // Lift up the image only by caption height
286
325
 
287
- // vertical ending of the image
288
- const verticalEnding = imageHeight + slide.bounds.center.y;
326
+ // vertical ending of the image
327
+ const verticalEnding = imageHeight + slide.bounds.center.y;
289
328
 
290
- // height between bottom of the screen and ending of the image
291
- // (before any adjustments applied)
292
- const verticalLeftover = slide.panAreaSize.y - verticalEnding;
293
- const initialPanAreaHeight = slide.panAreaSize.y;
329
+ // height between bottom of the screen and ending of the image
330
+ // (before any adjustments applied)
331
+ const verticalLeftover = slide.panAreaSize.y - verticalEnding;
332
+ const initialPanAreaHeight = slide.panAreaSize.y;
294
333
 
295
- if (verticalLeftover <= captionHeight) {
296
- // lift up the image to give more space for caption
297
- slide.panAreaSize.y -= Math.min((captionHeight - verticalLeftover) * 2, captionHeight);
334
+ if (verticalLeftover <= captionHeight) {
335
+ // lift up the image to give more space for caption
336
+ slide.panAreaSize.y -= Math.min((captionHeight - verticalLeftover) * 2, captionHeight);
298
337
 
299
- // we reduce viewport size, thus we need to update zoom level and pan bounds
300
- this.recalculateZoomLevelAndBounds(slide);
338
+ // we reduce viewport size, thus we need to update zoom level and pan bounds
339
+ this.recalculateZoomLevelAndBounds(slide);
301
340
 
302
- const maxPositionX = slide.panAreaSize.x * this.options.mobileCaptionOverlapRatio / 2;
341
+ const maxPositionX = slide.panAreaSize.x * this.options.mobileCaptionOverlapRatio / 2;
303
342
 
304
- // Do not reduce viewport height if too few space available
305
- if (useMobileVersion
306
- && slide.bounds.center.x > maxPositionX) {
307
- // Restore the default position
308
- slide.panAreaSize.y = initialPanAreaHeight;
309
- this.recalculateZoomLevelAndBounds(slide);
343
+ // Do not reduce viewport height if too few space available
344
+ if (useMobileVersion
345
+ && slide.bounds.center.x > maxPositionX) {
346
+ // Restore the default position
347
+ slide.panAreaSize.y = initialPanAreaHeight;
348
+ this.recalculateZoomLevelAndBounds(slide);
349
+ }
310
350
  }
311
351
  }
312
-
313
-
314
-
315
- // if (this.useMobileLayout && slide.bounds.center.x > 100) {
316
- // // do nothing, caption will overlap the bottom part of the image
317
- // } else if (verticalLeftover <= captionHeight) {
318
-
319
- // } else {
320
- // // do nothing, caption will fit below the image without any adjustments
321
- // }
322
352
  } else {
323
353
  // mobile
324
354
  }
325
355
 
326
356
  this.storeAdjustedPanAreaSize(slide);
327
-
328
- if (slide === this.pswp.currSlide) {
329
- this.updateCurrentCaptionPosition();
330
- }
357
+ this.updateCaptionPosition(slide);
331
358
  }
332
359
 
333
360
  measureCaptionSize(captionEl, slide) {
@@ -349,19 +376,23 @@ class PhotoSwipeDynamicCaption {
349
376
  }
350
377
 
351
378
  storeAdjustedPanAreaSize(slide) {
352
- if (!slide.__dcAdjustedPanAreaSize) {
353
- slide.__dcAdjustedPanAreaSize = {};
379
+ if (slide.dynamicCaption) {
380
+ if (!slide.dynamicCaption.adjustedPanAreaSize) {
381
+ slide.dynamicCaption.adjustedPanAreaSize = {};
382
+ }
383
+ slide.dynamicCaption.adjustedPanAreaSize.x = slide.panAreaSize.x;
384
+ slide.dynamicCaption.adjustedPanAreaSize.y = slide.panAreaSize.y;
354
385
  }
355
- slide.__dcAdjustedPanAreaSize.x = slide.panAreaSize.x;
356
- slide.__dcAdjustedPanAreaSize.y = slide.panAreaSize.y;
357
386
  }
358
387
 
359
388
  storeOriginalPanAreaSize(slide) {
360
- if (!slide.__dcOriginalPanAreaSize) {
361
- slide.__dcOriginalPanAreaSize = {};
389
+ if (slide.dynamicCaption) {
390
+ if (!slide.dynamicCaption.originalPanAreaSize) {
391
+ slide.dynamicCaption.originalPanAreaSize = {};
392
+ }
393
+ slide.dynamicCaption.originalPanAreaSize.x = slide.panAreaSize.x;
394
+ slide.dynamicCaption.originalPanAreaSize.y = slide.panAreaSize.y;
362
395
  }
363
- slide.__dcOriginalPanAreaSize.x = slide.panAreaSize.x;
364
- slide.__dcOriginalPanAreaSize.y = slide.panAreaSize.y;
365
396
  }
366
397
 
367
398
  getCaptionHTML(slide) {
@@ -386,15 +417,6 @@ class PhotoSwipeDynamicCaption {
386
417
  }
387
418
  return captionHTML;
388
419
  }
389
-
390
- updateCaptionHTML() {
391
- const captionHTML = this.getCaptionHTML(this.pswp.currSlide);
392
- this.captionElement.style.visibility = captionHTML ? 'visible' : 'hidden';
393
- this.captionElement.innerHTML = captionHTML || '';
394
- this.pswp.dispatch('dynamicCaptionUpdateHTML', {
395
- captionElement: this.captionElement
396
- });
397
- }
398
420
  }
399
421
 
400
422
  export default PhotoSwipeDynamicCaption;