1 | |
---|
2 | function RVGTLine(margin, rowHeight) { |
---|
3 | this.elements = new Array; |
---|
4 | this.margin = margin; |
---|
5 | this.rowHeight = rowHeight; |
---|
6 | this.maxHeight = 0; |
---|
7 | } |
---|
8 | |
---|
9 | RVGTLine.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 RVGThumbs(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.resizeThreshold = 1.01; |
---|
62 | this.opts.resizeFactor = 0.95; |
---|
63 | this.opts.extraRowHeight = 6; /*loose sharpness but only for small screens when we could "almost" fit with full sharpness*/ |
---|
64 | this.opts.rowHeight = Math.round(this.opts.rowHeight / dpr ) + this.opts.extraRowHeight; |
---|
65 | } |
---|
66 | this.process(); |
---|
67 | |
---|
68 | var that = this; |
---|
69 | $(window).on('resize', function() { |
---|
70 | if (Math.abs(that.$thumbs.width() - that.prevContainerWidth)>1) |
---|
71 | that.process(); |
---|
72 | }) |
---|
73 | .on('RVTS_loaded', function(evt, down) { |
---|
74 | that.process( down && that.$thumbs.width() == that.prevContainerWidth ? that.prevLastLineFirstThumbIndex : 0); |
---|
75 | } ); |
---|
76 | } |
---|
77 | |
---|
78 | RVGThumbs.prototype = { |
---|
79 | prevContainerWidth:0, |
---|
80 | prevLastLineFirstThumbIndex: 0, |
---|
81 | |
---|
82 | process: function(startIndex) { |
---|
83 | startIndex = startIndex ? startIndex : 0; |
---|
84 | var containerWidth = this.$thumbs.width() |
---|
85 | , maxExtraMarginPerThumb = 1; |
---|
86 | this.prevContainerWidth = containerWidth; |
---|
87 | |
---|
88 | var $elts = $('li>a>img', this.$thumbs) |
---|
89 | , line = new RVGTLine(this.opts.hMargin, this.opts.rowHeight); |
---|
90 | |
---|
91 | for (var i=startIndex; i<$elts.length; i++) { |
---|
92 | var $elt = $( $elts[i] ); |
---|
93 | |
---|
94 | line.add($elt, i); |
---|
95 | if (line.width >= containerWidth - maxExtraMarginPerThumb * line.elements.length) { |
---|
96 | this.processLine(line, containerWidth); |
---|
97 | line.clear(); |
---|
98 | } |
---|
99 | }; |
---|
100 | |
---|
101 | if(line.elements.length) |
---|
102 | this.processLine(line, containerWidth, true); |
---|
103 | this.prevLastLineFirstThumbIndex = line.firstThumbIndex; |
---|
104 | }, |
---|
105 | |
---|
106 | processLine: function(line, containerWidth, lastLine) { |
---|
107 | var toRecover, eltW, eltH |
---|
108 | , rowHeight = line.maxHeight ? line.maxHeight : line.elements[0].h; |
---|
109 | |
---|
110 | if (line.width / containerWidth > this.opts.resizeThreshold) { |
---|
111 | var ratio = line.elementsWidth / (line.elementsWidth + containerWidth - line.width); |
---|
112 | var adjustedRowHeight = rowHeight / (1 + (ratio-1) * this.opts.resizeFactor ); |
---|
113 | adjustedRowHeight = 6 * Math.round( adjustedRowHeight/6 ); |
---|
114 | if (adjustedRowHeight < rowHeight / ratio ) { |
---|
115 | adjustedRowHeight = Math.ceil( rowHeight / ratio ); |
---|
116 | var missing = this.opts.rowHeight - this.opts.extraRowHeight - adjustedRowHeight; |
---|
117 | if (missing>0 && missing<6) |
---|
118 | adjustedRowHeight += missing; |
---|
119 | } |
---|
120 | if (adjustedRowHeight < rowHeight) |
---|
121 | rowHeight = adjustedRowHeight; |
---|
122 | } |
---|
123 | else if (lastLine) |
---|
124 | rowHeight = Math.min( rowHeight, this.opts.rowHeight - this.opts.extraRowHeight); |
---|
125 | |
---|
126 | toRecover = line.width - containerWidth; |
---|
127 | if (lastLine) |
---|
128 | toRecover = 0; |
---|
129 | |
---|
130 | for(var i=0; i<line.elements.length; i++) { |
---|
131 | var eltObj = line.elements[i] |
---|
132 | , eltW=eltObj.w |
---|
133 | , eltH=eltObj.h |
---|
134 | , eltToRecover; |
---|
135 | |
---|
136 | if (i==line.elements.length-1) |
---|
137 | eltToRecover = toRecover; |
---|
138 | else |
---|
139 | eltToRecover = Math.round(toRecover * eltW / line.elementsWidth); |
---|
140 | |
---|
141 | toRecover -= eltToRecover; |
---|
142 | line.elementsWidth -= eltW; |
---|
143 | |
---|
144 | if (eltH > rowHeight ) { |
---|
145 | eltW = Math.round( eltW * rowHeight/eltObj.h ); |
---|
146 | eltH = rowHeight; |
---|
147 | eltToRecover -= eltObj.w - eltW; |
---|
148 | if (lastLine) |
---|
149 | eltToRecover = 0; |
---|
150 | } |
---|
151 | |
---|
152 | this.reposition(eltObj.$elt, eltW, eltH, eltW-eltToRecover, rowHeight); |
---|
153 | } |
---|
154 | }, |
---|
155 | |
---|
156 | reposition: function($img, imgW, imgH, liW, liH) { |
---|
157 | $img.attr("width", imgW) |
---|
158 | .attr("height", imgH); |
---|
159 | |
---|
160 | $img.closest("li").css( { |
---|
161 | width: liW+"px", |
---|
162 | height: liH+"px" |
---|
163 | }); |
---|
164 | |
---|
165 | $img.parent("a").css( { |
---|
166 | left: Math.round((liW-imgW)/2)+"px", |
---|
167 | top: Math.round((liH-imgH)/2)+"px" |
---|
168 | }); |
---|
169 | } |
---|
170 | |
---|
171 | } |
---|
172 | |
---|