PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 3.37
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v3.37
3.37 3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 All 142 releases
photonic / include / js / front-end / src / Layouts / Justified.js

Justified.js in Photonic Gallery & Lightbox for Flickr, SmugMug & Others 3.37, at include/js/front-end/src/Layouts/Justified.js

228 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Photonic Justified Grid Layout (JS-based)
3 * Photonic can render a justified grid using CSS or JS. The CSS layout is the default. The JS one is used when the sizes of the images are not available upfront.
4 * The CSS layout renders quicker, but the JS layouts are a lot prettier.
5 *
6 * License: GPL v3.0
7 */
8
9 import {Core} from "../Core.js";
10 import * as Util from "../Util.js";
11
12 const linearMin = arr => {
13 let computed, result, x, _i, _len;
14 for (_i = 0, _len = arr.length; _i < _len; _i++) {
15 x = arr[_i];
16 computed = x[0];
17 if (!result || computed < result.computed) {
18 result = {
19 value: x,
20 computed: computed
21 };
22 }
23 }
24 return result.value;
25 };
26
27 const linearPartition = (seq, k) => {
28 let ans, i, j, m, n, solution, table, x, y, _i, _j, _k, _l;
29 n = seq.length;
30 if (k <= 0) {
31 return [];
32 }
33 if (k > n) {
34 return seq.map(x => [x]);
35 }
36 table = (() => {
37 let _i, _results;
38 _results = [];
39 for (y = _i = 0; 0 <= n ? _i < n : _i > n; y = 0 <= n ? ++_i : --_i) {
40 _results.push((function() {
41 let _j, _results1;
42 _results1 = [];
43 for (x = _j = 0; 0 <= k ? _j < k : _j > k; x = 0 <= k ? ++_j : --_j) {
44 _results1.push(0);
45 }
46 return _results1;
47 })());
48 }
49 return _results;
50 })();
51 solution = (() => {
52 let _i, _ref, _results;
53 _results = [];
54 for (y = _i = 0, _ref = n - 1; 0 <= _ref ? _i < _ref : _i > _ref; y = 0 <= _ref ? ++_i : --_i) {
55 _results.push((function() {
56 let _j, _ref1, _results1;
57 _results1 = [];
58 for (x = _j = 0, _ref1 = k - 1; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; x = 0 <= _ref1 ? ++_j : --_j) {
59 _results1.push(0);
60 }
61 return _results1;
62 })());
63 }
64 return _results;
65 })();
66
67 for (i = _i = 0; 0 <= n ? _i < n : _i > n; i = 0 <= n ? ++_i : --_i) {
68 table[i][0] = seq[i] + (i ? table[i - 1][0] : 0);
69 }
70 for (j = _j = 0; 0 <= k ? _j < k : _j > k; j = 0 <= k ? ++_j : --_j) {
71 table[0][j] = seq[0];
72 }
73 for (i = _k = 1; 1 <= n ? _k < n : _k > n; i = 1 <= n ? ++_k : --_k) {
74 for (j = _l = 1; 1 <= k ? _l < k : _l > k; j = 1 <= k ? ++_l : --_l) {
75 m = linearMin((() => {
76 let _m, _results;
77 _results = [];
78 for (x = _m = 0; 0 <= i ? _m < i : _m > i; x = 0 <= i ? ++_m : --_m) {
79 _results.push([Math.max(table[x][j - 1], table[i][0] - table[x][0]), x]);
80 }
81 return _results;
82 })());
83 table[i][j] = m[0];
84 solution[i - 1][j - 1] = m[1];
85 }
86 }
87 n = n - 1;
88 k = k - 2;
89 ans = [];
90 while (k >= 0) {
91 ans = [
92 (() => {
93 let _m, _ref, _ref1, _results;
94 _results = [];
95 for (i = _m = _ref = solution[n - 1][k] + 1, _ref1 = n + 1; _ref <= _ref1 ? _m < _ref1 : _m > _ref1; i = _ref <= _ref1 ? ++_m : --_m) {
96 _results.push(seq[i]);
97 }
98 return _results;
99 })()
100 ].concat(ans);
101 n = solution[n - 1][k];
102 k = k - 1;
103 }
104 return [
105 (() => {
106 let _m, _ref, _results;
107 _results = [];
108 for (i = _m = 0, _ref = n + 1; 0 <= _ref ? _m < _ref : _m > _ref; i = 0 <= _ref ? ++_m : --_m) {
109 _results.push(seq[i]);
110 }
111 return _results;
112 })()
113 ].concat(ans);
114 };
115
116 function part(seq, k) {
117 if (k <= 0) {
118 return [];
119 }
120 while (k) {
121 try {
122 return linearPartition(seq, k--);
123 }
124 catch (_error) {
125 //
126 }
127 }
128 }
129
130 export const JustifiedGrid = (resized, jsLoaded, selector, lightbox) => {
131 if (console !== undefined && Photonic_JS.debug_on !== '0' && Photonic_JS.debug_on !== '') console.time('Justified Grid');
132 let selection = document.querySelectorAll(selector);
133
134 if (selector == null || selection.length === 0) {
135 selection = document.querySelectorAll('.photonic-random-layout');
136 }
137
138 if (!resized && selection.length > 0) {
139 Core.showSpinner();
140 }
141
142 const setupTitles = () => {
143 Core.blankSlideupTitle();
144 Core.showSlideupTitle();
145 if (!resized && !jsLoaded) {
146 Core.hideLoading();
147 }
148 };
149
150 selection.forEach((container) => {
151 // If there are some nodes for which the sizes are missing, play safe and run this in JS mode.
152 // Otherwise render the gallery using CSS, and just display the images once they have downloaded.
153 if (container.classList.contains('sizes-missing') || !window.CSS || !CSS.supports('color', 'var(--fake-var)')) {
154 const viewportWidth = Math.floor(container.getBoundingClientRect().width),
155 windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
156 idealHeight = Math.max(parseInt(windowHeight / 4), Photonic_JS.tile_min_height);
157
158 const gap = Photonic_JS.tile_spacing * 2;
159
160 Core.waitForImages(container).then(() => {
161 const photos = [],
162 images = Array.from(container.getElementsByTagName('img'));
163
164 images.forEach(image => {
165 if (image.closest('.photonic-panel') !== null) {
166 return;
167 }
168
169 const div = image.parentNode.parentNode;
170
171 if (!(image.naturalHeight === 0 || image.naturalHeight === undefined || image.naturalWidth === undefined)) {
172 photos.push({tile: div, aspect_ratio: (image.naturalWidth) / (image.naturalHeight)});
173 }
174 });
175
176 const summedWidth = photos.reduce(((sum, p) => sum += p.aspect_ratio * idealHeight + gap), 0);
177
178 const rows = Math.max(Math.round(summedWidth / viewportWidth), 1), // At least 1 row should be shown
179 weights = photos.map(p => Math.round(p.aspect_ratio * 100));
180
181 const partition = part(weights, rows);
182 let index = 0;
183
184 const oLen = partition.length;
185 for (let o = 0; o < oLen; o++) {
186 const onePart = partition[o];
187 let summedRatios;
188 const rowBuffer = photos.slice(index, index + onePart.length);
189 index = index + onePart.length;
190
191 summedRatios = rowBuffer.reduce(((sum, p) => sum += p.aspect_ratio), 0);
192
193 const rLen = rowBuffer.length;
194 for (let r = 0; r < rLen; r++) {
195 const item = rowBuffer[r],
196 existing = item.tile;
197 existing.style.width = parseInt(viewportWidth / summedRatios * item.aspect_ratio)+"px";
198 existing.style.height = parseInt(viewportWidth / summedRatios)+"px";
199 }
200 }
201
202 container.querySelectorAll('.photonic-thumb, .photonic-thumb img').forEach((thumb) => Util.fadeIn(thumb));
203 setupTitles();
204 });
205 }
206 else {
207 Core.watchForImages(container);
208 setupTitles();
209 }
210
211 if (lightbox && !resized) {
212 if (Photonic_JS.lightbox_library === 'lightcase') {
213 lightbox.initialize('.photonic-random-layout');
214 }
215 else if (['bigpicture', 'featherlight', 'glightbox'].indexOf(Photonic_JS.lightbox_library) > -1) {
216 lightbox.initialize(container);
217 }
218 else if (Photonic_JS.lightbox_library === 'fancybox3') {
219 lightbox.initialize('.photonic-random-layout');
220 }
221 else if (Photonic_JS.lightbox_library === 'photoswipe') {
222 lightbox.initialize();
223 }
224 }
225 });
226 if (console !== undefined && Photonic_JS.debug_on !== '0' && Photonic_JS.debug_on !== '') console.timeEnd('Justified Grid');
227 };
228