1 | |
---|
2 | function SPTLine(margin, rowHeight) { |
---|
3 | this.elements = new Array; |
---|
4 | this.margin = margin; |
---|
5 | this.rowHeight = rowHeight; |
---|
6 | this.maxHeight = 0; |
---|
7 | } |
---|
8 | |
---|
9 | SPTLine.prototype = { |
---|
10 | width: 0, |
---|
11 | elementsWidth: 0, |
---|
12 | firstThumbIndex: 0, |
---|
13 | |
---|
14 | add: function($elt, absIndex) { |
---|
15 | if (this.elements.length === 0) |
---|
16 | this.firstThumbIndex = absIndex; |
---|
17 | if (!$elt.data("w")) |
---|
18 | { |
---|
19 | var w=$elt.width(), h=$elt.height(); |
---|
20 | if (h > this.rowHeight) { |
---|
21 | w = Math.round(w * this.rowHeight/h); |
---|
22 | h = this.rowHeight; |
---|
23 | } |
---|
24 | $elt.data("w", w) |
---|
25 | .data("h", h); |
---|
26 | } |
---|
27 | |
---|
28 | var eltObj = { |
---|
29 | $elt: $elt, |
---|
30 | w: $elt.data("w"), |
---|
31 | h: $elt.data("h") |
---|
32 | }; |
---|
33 | this.elements.push(eltObj); |
---|
34 | |
---|
35 | if (eltObj.h > this.maxHeight) |
---|
36 | this.maxHeight = eltObj.h; |
---|
37 | |
---|
38 | this.width += this.margin + eltObj.w; |
---|
39 | this.elementsWidth += eltObj.w; |
---|
40 | }, |
---|
41 | |
---|
42 | clear: function() { |
---|
43 | if (!this.elements.length) return; |
---|
44 | this.width = this.elementsWidth = 0; |
---|
45 | this.maxHeight = 0; |
---|
46 | this.elements.length = 0; |
---|
47 | } |
---|
48 | } |
---|
49 | |
---|
50 | |
---|
51 | function SPThumbs(options) { |
---|
52 | this.opts = options; |
---|
53 | |
---|
54 | this.$thumbs = $('.thumbnails'); |
---|
55 | if (this.$thumbs.length==0) return; |
---|
56 | this.$thumbs.css('text-align', 'left'); |
---|
57 | |
---|
58 | this.opts.extraRowHeight = 0; |
---|
59 | if (window.devicePixelRatio > 1) { |
---|
60 | var dpr = window.devicePixelRatio; |
---|
61 | this.opts.extraRowHeight = 6; /*loose sharpness but only for small screens when we could "almost" fit with full sharpness*/ |
---|
62 | this.opts.rowHeight = Math.round(this.opts.rowHeight / dpr ) + this.opts.extraRowHeight; |
---|
63 | } |
---|
64 | this.process(); |
---|
65 | |
---|
66 | var that = this; |
---|
67 | $(window).on('resize', function() { |
---|
68 | if (Math.abs(that.$thumbs.width() - that.prevContainerWidth)>1) |
---|
69 | that.process(); |
---|
70 | }) |
---|
71 | .on('RVTS_loaded', function(evt, down) { |
---|
72 | that.process( down && that.$thumbs.width() == that.prevContainerWidth ? that.prevLastLineFirstThumbIndex : 0); |
---|
73 | } ); |
---|
74 | } |
---|
75 | |
---|
76 | SPThumbs.prototype = { |
---|
77 | prevContainerWidth:0, |
---|
78 | prevLastLineFirstThumbIndex: 0, |
---|
79 | |
---|
80 | process: function(startIndex) { |
---|
81 | startIndex = startIndex ? startIndex : 0; |
---|
82 | var containerWidth = this.$thumbs.width() |
---|
83 | , maxExtraMarginPerThumb = 1; |
---|
84 | this.prevContainerWidth = containerWidth; |
---|
85 | |
---|
86 | var $elts = $('li.liVisible>a>img', this.$thumbs) |
---|
87 | , line = new SPTLine(this.opts.hMargin, this.opts.rowHeight); |
---|
88 | |
---|
89 | for (var i=startIndex; i<$elts.length; i++) { |
---|
90 | var $elt = $( $elts[i] ); |
---|
91 | |
---|
92 | line.add($elt, i); |
---|
93 | if (line.width >= containerWidth - maxExtraMarginPerThumb * line.elements.length) { |
---|
94 | this.processLine(line, containerWidth); |
---|
95 | line.clear(); |
---|
96 | } |
---|
97 | }; |
---|
98 | |
---|
99 | if(line.elements.length) |
---|
100 | this.processLine(line, containerWidth, true); |
---|
101 | this.prevLastLineFirstThumbIndex = line.firstThumbIndex; |
---|
102 | }, |
---|
103 | |
---|
104 | processLine: function(line, containerWidth, lastLine) { |
---|
105 | var toRecover, eltW, eltH |
---|
106 | , rowHeight = line.maxHeight ? line.maxHeight : line.elements[0].h; |
---|
107 | |
---|
108 | if (line.width / containerWidth > 1.01) { |
---|
109 | var ratio = line.elementsWidth / (line.elementsWidth + containerWidth - line.width); |
---|
110 | var adjustedRowHeight = rowHeight / (1 + (ratio-1) * 0.95 ); |
---|
111 | adjustedRowHeight = 6 * Math.round( adjustedRowHeight/6 ); |
---|
112 | if (adjustedRowHeight < rowHeight / ratio ) { |
---|
113 | adjustedRowHeight = Math.ceil( rowHeight / ratio ); |
---|
114 | var missing = this.opts.rowHeight - this.opts.extraRowHeight - adjustedRowHeight; |
---|
115 | if (missing>0 && missing<6) |
---|
116 | adjustedRowHeight += missing; |
---|
117 | } |
---|
118 | if (adjustedRowHeight < rowHeight) |
---|
119 | rowHeight = adjustedRowHeight; |
---|
120 | } |
---|
121 | else if (lastLine) |
---|
122 | rowHeight = Math.min( rowHeight, this.opts.rowHeight - this.opts.extraRowHeight); |
---|
123 | |
---|
124 | toRecover = line.width - containerWidth; |
---|
125 | if (lastLine) |
---|
126 | toRecover = 0; |
---|
127 | |
---|
128 | for(var i=0; i<line.elements.length; i++) { |
---|
129 | var eltObj = line.elements[i] |
---|
130 | , eltW=eltObj.w |
---|
131 | , eltH=eltObj.h |
---|
132 | , eltToRecover; |
---|
133 | |
---|
134 | if (i==line.elements.length-1) |
---|
135 | eltToRecover = toRecover; |
---|
136 | else |
---|
137 | eltToRecover = Math.round(toRecover * eltW / line.elementsWidth); |
---|
138 | |
---|
139 | toRecover -= eltToRecover; |
---|
140 | line.elementsWidth -= eltW; |
---|
141 | |
---|
142 | if (eltH > rowHeight ) { |
---|
143 | eltW = Math.round( eltW * rowHeight/eltObj.h ); |
---|
144 | eltH = rowHeight; |
---|
145 | eltToRecover -= eltObj.w - eltW; |
---|
146 | if (lastLine) |
---|
147 | eltToRecover = 0; |
---|
148 | } |
---|
149 | |
---|
150 | this.reposition(eltObj.$elt, eltW, eltH, eltW-eltToRecover, rowHeight); |
---|
151 | } |
---|
152 | }, |
---|
153 | |
---|
154 | reposition: function($img, imgW, imgH, liW, liH) { |
---|
155 | $img.attr("width", imgW) |
---|
156 | .attr("height", imgH); |
---|
157 | |
---|
158 | $img.closest("li").css( { |
---|
159 | width: liW+"px", |
---|
160 | height: liH+"px" |
---|
161 | }); |
---|
162 | |
---|
163 | $img.parent("a").css( { |
---|
164 | left: Math.round((liW-imgW)/2)+"px", |
---|
165 | top: Math.round((liH-imgH)/2)+"px" |
---|
166 | }); |
---|
167 | } |
---|
168 | |
---|
169 | } |
---|
170 | |
---|