intranet-pictures 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;