jekyll-pig 0.0.3 → 0.0.5
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.
- checksums.yaml +4 -4
- data/lib/jekyll-pig.rb +294 -295
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc22ff1902fb72ae001ac574bb84687afabcb815c54169d470b96dad48315ad7
|
4
|
+
data.tar.gz: d91b9e706a8a81841ec856a64870c6a5831030327e444d390bb27e92217c169d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e63a1cee3e5aa25416246030f113ac8271bb3e5872038ea7317c1873029cfe4d3c66b96d753d4dee6c7b22914399a3a876a10520b619fa70bb15e1f9926719e5
|
7
|
+
data.tar.gz: 38ee6decfa0bff283ee334362ea1bf2552874abeec76339b963b819b12e9bc873238a48e5a853c6fae9b6159ed1d8f07af29e1743322f6dc578197cdc8aa39d7
|
data/lib/jekyll-pig.rb
CHANGED
@@ -1,295 +1,294 @@
|
|
1
|
-
|
2
|
-
require 'fileutils'
|
3
|
-
require 'json'
|
4
|
-
require 'mini_magick'
|
5
|
-
|
6
|
-
module JekyllPig
|
7
|
-
|
8
|
-
class SourceGallery
|
9
|
-
def initialize(path, name)
|
10
|
-
@path = path
|
11
|
-
@name = name
|
12
|
-
end
|
13
|
-
def to_s
|
14
|
-
"gallery #{@name} at #{@path}"
|
15
|
-
end
|
16
|
-
def path
|
17
|
-
@path
|
18
|
-
end
|
19
|
-
def name
|
20
|
-
@name
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class JekyllPig < Jekyll::Generator
|
25
|
-
|
26
|
-
@@image_cache = {}
|
27
|
-
|
28
|
-
@@pig_min_js = '!function(t){"use strict";var i,e,s=(e=!(i=[]),{add:function(t){i.length||window.addEventListener("resize",n),i.push(t)},disable:function(){window.removeEventListener("resize",n)},reEnable:function(){window.addEventListener("resize",n)}});function n(){e||(e=!0,window.requestAnimationFrame?window.requestAnimationFrame(o):setTimeout(o,66))}function o(){i.forEach(function(t){t()}),e=!1}function a(t,i){return this.inRAF=!1,this.isTransitioning=!1,this.minAspectRatioRequiresTransition=!1,this.minAspectRatio=null,this.latestYOffset=0,this.lastWindowWidth=window.innerWidth,this.scrollDirection="down",this.visibleImages=[],this.settings={containerId:"pig",scroller:window,classPrefix:"pig",figureTagName:"figure",spaceBetweenImages:8,transitionSpeed:500,primaryImageBufferHeight:1e3,secondaryImageBufferHeight:300,thumbnailSize:20,urlForSize:function(t,i){return"/img/"+i+"/"+t},onClickHandler:function(t){},getMinAspectRatio:function(t){return t<=640?2:t<=1280?4:t<=1920?5:6},getImageSize:function(t){return t<=640?100:t<=1920?250:500}},function(t,i){for(var e in i)i.hasOwnProperty(e)&&(t[e]=i[e])}(this.settings,i||{}),this.container=document.getElementById(this.settings.containerId),this.container||console.error("Could not find element with ID "+this.settings.containerId),this.scroller=this.settings.scroller,this.images=this._parseImageData(t),function(t,i,e){var s="#"+t+" { position: relative;}."+i+"-figure { background-color: #D5D5D5; overflow: hidden; left: 0; position: absolute; top: 0; margin: 0;}."+i+"-figure img { left: 0; position: absolute; top: 0; height: 100%; width: 100%; opacity: 0; transition: "+e/1e3+"s ease opacity; -webkit-transition: "+e/1e3+"s ease opacity;}."+i+"-figure img."+i+"-thumbnail { -webkit-filter: blur(30px); filter: blur(30px); left: auto; position: relative; width: auto;}."+i+"-figure img."+i+"-loaded { opacity: 1;}",n=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",o.styleSheet?o.styleSheet.cssText=s:o.appendChild(document.createTextNode(s)),n.appendChild(o)}(this.settings.containerId,this.settings.classPrefix,this.settings.transitionSpeed),this}function r(t,i,e){return this.existsOnPage=!1,this.aspectRatio=t.aspectRatio,this.filename=t.filename,this.index=i,this.pig=e,this.classNames={figure:e.settings.classPrefix+"-figure",thumbnail:e.settings.classPrefix+"-thumbnail",loaded:e.settings.classPrefix+"-loaded"},this}a.prototype._getTransitionTimeout=function(){return 1.5*this.settings.transitionSpeed},a.prototype._getTransitionString=function(){return this.isTransitioning?this.settings.transitionSpeed/1e3+"s transform ease":"none"},a.prototype._recomputeMinAspectRatio=function(){var t=this.minAspectRatio;this.minAspectRatio=this.settings.getMinAspectRatio(this.lastWindowWidth),null!==t&&t!==this.minAspectRatio?this.minAspectRatioRequiresTransition=!0:this.minAspectRatioRequiresTransition=!1},a.prototype._parseImageData=function(t){var s=[];return t.forEach(function(t,i){var e=new r(t,i,this);s.push(e)}.bind(this)),s},a.prototype._computeLayout=function(){var s=parseInt(this.container.clientWidth),n=[],o=0,a=0,r=0;this._recomputeMinAspectRatio(),!this.isTransitioning&&this.minAspectRatioRequiresTransition&&(this.isTransitioning=!0,setTimeout(function(){this.isTransitioning=!1},this._getTransitionTimeout()));var h=this._getTransitionString();[].forEach.call(this.images,function(t,i){if(r+=parseFloat(t.aspectRatio),n.push(t),r>=this.minAspectRatio||i+1===this.images.length){r=Math.max(r,this.minAspectRatio);var e=(s-this.settings.spaceBetweenImages*(n.length-1))/r;n.forEach(function(t){var i=e*t.aspectRatio;t.style={width:parseInt(i),height:parseInt(e),translateX:o,translateY:a,transition:h},o+=i+this.settings.spaceBetweenImages}.bind(this)),n=[],r=0,a+=parseInt(e)+this.settings.spaceBetweenImages,o=0}}.bind(this)),this.totalHeight=a-this.settings.spaceBetweenImages},a.prototype._doLayout=function(){this.container.style.height=this.totalHeight+"px";var t="up"===this.scrollDirection?this.settings.primaryImageBufferHeight:this.settings.secondaryImageBufferHeight,i="down"===this.scrollDirection?this.settings.secondaryImageBufferHeight:this.settings.primaryImageBufferHeight,e=function(t){for(var i=0;isNaN(t.offsetTop)||(i+=t.offsetTop),t=t.offsetParent;);return i}(this.container),s=this.scroller===window?window.innerHeight:this.scroller.offsetHeight,n=this.latestYOffset-e-t,o=this.latestYOffset-e+s+i;this.images.forEach(function(t){t.style.translateY+t.style.height<n||t.style.translateY>o?t.hide():t.load()}.bind(this))},a.prototype._getOnScroll=function(){var i=this;return function(){var t=i.scroller===window?window.pageYOffset:i.scroller.scrollTop;i.previousYOffset=i.latestYOffset||t,i.latestYOffset=t,i.scrollDirection=i.latestYOffset>i.previousYOffset?"down":"up",i.inRAF||(i.inRAF=!0,window.requestAnimationFrame(function(){i._doLayout(),i.inRAF=!1}))}},a.prototype.enable=function(){return this.onScroll=this._getOnScroll(),this.scroller.addEventListener("scroll",this.onScroll),this.onScroll(),this._computeLayout(),this._doLayout(),s.add(function(){this.lastWindowWidth=this.scroller===window?window.innerWidth:this.scroller.offsetWidth,this._computeLayout(),this._doLayout()}.bind(this)),this},a.prototype.disable=function(){return this.scroller.removeEventListener("scroll",this.onScroll),s.disable(),this},r.prototype.load=function(){this.existsOnPage=!0,this._updateStyles(),this.pig.container.appendChild(this.getElement()),setTimeout(function(){this.existsOnPage&&(this.thumbnail||(this.thumbnail=new Image,this.thumbnail.src=this.pig.settings.urlForSize(this.filename,this.pig.settings.thumbnailSize),this.thumbnail.className=this.classNames.thumbnail,this.thumbnail.onload=function(){this.thumbnail&&(this.thumbnail.className+=" "+this.classNames.loaded)}.bind(this),this.getElement().appendChild(this.thumbnail)),this.fullImage||(this.fullImage=new Image,this.fullImage.src=this.pig.settings.urlForSize(this.filename,this.pig.settings.getImageSize(this.pig.lastWindowWidth)),this.fullImage.onload=function(){this.fullImage&&(this.fullImage.className+=" "+this.classNames.loaded)}.bind(this),this.getElement().appendChild(this.fullImage)))}.bind(this),100)},r.prototype.hide=function(){this.getElement()&&(this.thumbnail&&(this.thumbnail.src="",this.getElement().removeChild(this.thumbnail),delete this.thumbnail),this.fullImage&&(this.fullImage.src="",this.getElement().removeChild(this.fullImage),delete this.fullImage)),this.existsOnPage&&this.pig.container.removeChild(this.getElement()),this.existsOnPage=!1},r.prototype.getElement=function(){return this.element||(this.element=document.createElement(this.pig.settings.figureTagName),this.element.className=this.classNames.figure,this.element.addEventListener("click",function(){this.pig.settings.onClickHandler(this.filename)}.bind(this)),this._updateStyles()),this.element},r.prototype._updateStyles=function(){this.getElement().style.transition=this.style.transition,this.getElement().style.width=this.style.width+"px",this.getElement().style.height=this.style.height+"px",this.getElement().style.transform="translate3d("+this.style.translateX+"px,"+this.style.translateY+"px, 0)"},"function"==typeof define&&define.amd?define([],function(){return a}):"undefined"!=typeof module&&module.exports?module.exports=a:t.Pig=a}("undefined"!=typeof window?window:this);'
|
29
|
-
|
30
|
-
def full_size_html(gallery_name, name, date, prev_url, next_url)
|
31
|
-
"---\n" \
|
32
|
-
"layout: post\n" \
|
33
|
-
"title: #{name}\n" \
|
34
|
-
"date: #{date.strftime("%Y-%m-%d %H:%M:%S")}\n" \
|
35
|
-
"permalink: /assets/html/#{gallery_name}/#{name}.html\n" \
|
36
|
-
"exclude: true\n" \
|
37
|
-
"---\n" \
|
38
|
-
"<div><a href=\"#{prev_url}\" style=\"display:inline;\">prev</a><a href=\"#{next_url}\" style=\"display:inline; float:right\">next</a></div>\n" \
|
39
|
-
"<img src=\"{{site.baseurl}}/assets/img/#{gallery_name}/1024/#{name}\"/>\n"
|
40
|
-
end
|
41
|
-
|
42
|
-
def gallery_html(id, image_data)
|
43
|
-
"<div id='#{id}_pig'></div>\n" \
|
44
|
-
"<script src='{{site.baseurl}}/assets/js/pig.min.js'></script>\n" \
|
45
|
-
"<script>\n" \
|
46
|
-
"var #{id}_pig = new Pig(\n" \
|
47
|
-
" #{image_data.to_json()},\n" \
|
48
|
-
" {\n" \
|
49
|
-
" containerId: '#{id}_pig',\n" \
|
50
|
-
" classPrefix: '#{id}_pig',\n" \
|
51
|
-
" urlForSize: function(filename, size) {\n" \
|
52
|
-
" return '{{site.baseurl}}/assets/img/#{id}/' + size + '/' + filename;\n" \
|
53
|
-
" },\n" \
|
54
|
-
" onClickHandler: function(filename) {\n" \
|
55
|
-
" window.location.href = '{{site.baseurl}}/assets/html/#{id}/' + filename + '.html';\n" \
|
56
|
-
" }\n" \
|
57
|
-
" }\n" \
|
58
|
-
").enable();\n" \
|
59
|
-
"</script>"
|
60
|
-
end
|
61
|
-
|
62
|
-
def image_html_url(gallery_name, image_name)
|
63
|
-
"/assets/html/#{gallery_name}/#{image_name}.html"
|
64
|
-
end
|
65
|
-
|
66
|
-
#read the image data from the _includes folder
|
67
|
-
def get_image_data(gallery_name)
|
68
|
-
image_data = []
|
69
|
-
#read image_data if existing
|
70
|
-
if File.exists?(File.join(@data_path, "#{gallery_name}.json"))
|
71
|
-
File.open(File.join(@data_path, "#{gallery_name}.json"), 'r') { |file|
|
72
|
-
#get array of image data (drop 'var imageData = ' and ';')
|
73
|
-
image_data = JSON.parse(file.read)
|
74
|
-
}
|
75
|
-
end
|
76
|
-
image_data
|
77
|
-
end
|
78
|
-
|
79
|
-
#get a list of image file names from a given path
|
80
|
-
def get_images(path)
|
81
|
-
patterns = ['*.jpg', '*.jpeg', '*.png'].map { |ext| File.join(path, ext) }
|
82
|
-
Dir.glob(patterns).map { |filepath| File.basename(filepath) }
|
83
|
-
end
|
84
|
-
|
85
|
-
def get_image(gallery_path, image_name)
|
86
|
-
image = @@image_cache[File.join(gallery_path, image_name)]
|
87
|
-
if image == nil
|
88
|
-
image = MiniMagick::Image.open(File.join(gallery_path, image_name))
|
89
|
-
@@image_cache[File.join(gallery_path, image_name)] = image
|
90
|
-
end
|
91
|
-
image
|
92
|
-
end
|
93
|
-
|
94
|
-
def get_image_date(gallery_path, image_name)
|
95
|
-
image_date = nil
|
96
|
-
begin
|
97
|
-
image = get_image(gallery_path, image_name)
|
98
|
-
exif_date = image.exif['DateTimeOriginal']
|
99
|
-
if exif_date == nil
|
100
|
-
#no exif date, try to get from file name
|
101
|
-
image_date = Time.strptime(image_name, "%Y-%m-%d")
|
102
|
-
else
|
103
|
-
#try to get the image date from exif
|
104
|
-
image_date = Time.strptime(exif_date, "%Y:%m:%d %H:%M:%S")
|
105
|
-
end
|
106
|
-
rescue
|
107
|
-
#get the date from file if possible
|
108
|
-
image_date = File.mtime(File.join(gallery_path, image_name))
|
109
|
-
end
|
110
|
-
image_date
|
111
|
-
end
|
112
|
-
|
113
|
-
def get_previous_url(image_data, gallery_name, image_name)
|
114
|
-
index = image_data.index { |data| data['filename'] == image_name }
|
115
|
-
index = index - 1
|
116
|
-
if index < 0
|
117
|
-
index = image_data.length - 1
|
118
|
-
end
|
119
|
-
image_html_url(gallery_name, image_data[index]['filename'])
|
120
|
-
end
|
121
|
-
|
122
|
-
def get_next_url(image_data, gallery_name, image_name)
|
123
|
-
index = image_data.index { |data| data['filename'] == image_name }
|
124
|
-
index = index + 1
|
125
|
-
if index >= image_data.length
|
126
|
-
index = 0
|
127
|
-
end
|
128
|
-
image_html_url(gallery_name, image_data[index]['filename'])
|
129
|
-
end
|
130
|
-
|
131
|
-
#create thumbnails and fullsize image assets
|
132
|
-
def process_images(image_data, gallery_id, gallery_path, images)
|
133
|
-
#create thumbs
|
134
|
-
sizes = [1024, 500, 250, 100, 20]
|
135
|
-
sizes.each { |size|
|
136
|
-
#output path for current size
|
137
|
-
size_out_path = File.join(@img_path, gallery_id, size.to_s)
|
138
|
-
FileUtils.mkdir_p size_out_path unless File.exists? size_out_path
|
139
|
-
|
140
|
-
#images that have already been processed for the current size
|
141
|
-
done_images = get_images(size_out_path)
|
142
|
-
#all images in the gallery with the ones already done taken away
|
143
|
-
todo_images = images - done_images
|
144
|
-
|
145
|
-
#function to get the source path to use for creating the given size thumbnail
|
146
|
-
#i.e. use the 500px sized images to make the 250px versions
|
147
|
-
source_for_size = -> (size) {
|
148
|
-
index = sizes.index(size)
|
149
|
-
source = gallery_path
|
150
|
-
if index != nil && index != 0
|
151
|
-
source = File.join(@img_path, gallery_id, sizes[index - 1].to_s)
|
152
|
-
end
|
153
|
-
source
|
154
|
-
}
|
155
|
-
|
156
|
-
#do the processing in a batch
|
157
|
-
mog = MiniMagick::Tool::Mogrify.new
|
158
|
-
mog.resize("x#{size}")
|
159
|
-
mog.sampling_factor('4:2:0')
|
160
|
-
mog.
|
161
|
-
mog.
|
162
|
-
mog.
|
163
|
-
mog.
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
@
|
190
|
-
@
|
191
|
-
@
|
192
|
-
@
|
193
|
-
@
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
config_galleries
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
FileUtils.mkdir_p @
|
218
|
-
FileUtils.mkdir_p @
|
219
|
-
FileUtils.mkdir_p @
|
220
|
-
FileUtils.mkdir_p @
|
221
|
-
FileUtils.mkdir_p @
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
'
|
235
|
-
'
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
galleries
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
html_output_path
|
251
|
-
|
252
|
-
img_output_path
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
#
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
#
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
end
|
1
|
+
|
2
|
+
require 'fileutils'
|
3
|
+
require 'json'
|
4
|
+
require 'mini_magick'
|
5
|
+
|
6
|
+
module JekyllPig
|
7
|
+
|
8
|
+
class SourceGallery
|
9
|
+
def initialize(path, name)
|
10
|
+
@path = path
|
11
|
+
@name = name
|
12
|
+
end
|
13
|
+
def to_s
|
14
|
+
"gallery #{@name} at #{@path}"
|
15
|
+
end
|
16
|
+
def path
|
17
|
+
@path
|
18
|
+
end
|
19
|
+
def name
|
20
|
+
@name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class JekyllPig < Jekyll::Generator
|
25
|
+
|
26
|
+
@@image_cache = {}
|
27
|
+
|
28
|
+
@@pig_min_js = '!function(t){"use strict";var i,e,s=(e=!(i=[]),{add:function(t){i.length||window.addEventListener("resize",n),i.push(t)},disable:function(){window.removeEventListener("resize",n)},reEnable:function(){window.addEventListener("resize",n)}});function n(){e||(e=!0,window.requestAnimationFrame?window.requestAnimationFrame(o):setTimeout(o,66))}function o(){i.forEach(function(t){t()}),e=!1}function a(t,i){return this.inRAF=!1,this.isTransitioning=!1,this.minAspectRatioRequiresTransition=!1,this.minAspectRatio=null,this.latestYOffset=0,this.lastWindowWidth=window.innerWidth,this.scrollDirection="down",this.visibleImages=[],this.settings={containerId:"pig",scroller:window,classPrefix:"pig",figureTagName:"figure",spaceBetweenImages:8,transitionSpeed:500,primaryImageBufferHeight:1e3,secondaryImageBufferHeight:300,thumbnailSize:20,urlForSize:function(t,i){return"/img/"+i+"/"+t},onClickHandler:function(t){},getMinAspectRatio:function(t){return t<=640?2:t<=1280?4:t<=1920?5:6},getImageSize:function(t){return t<=640?100:t<=1920?250:500}},function(t,i){for(var e in i)i.hasOwnProperty(e)&&(t[e]=i[e])}(this.settings,i||{}),this.container=document.getElementById(this.settings.containerId),this.container||console.error("Could not find element with ID "+this.settings.containerId),this.scroller=this.settings.scroller,this.images=this._parseImageData(t),function(t,i,e){var s="#"+t+" { position: relative;}."+i+"-figure { background-color: #D5D5D5; overflow: hidden; left: 0; position: absolute; top: 0; margin: 0;}."+i+"-figure img { left: 0; position: absolute; top: 0; height: 100%; width: 100%; opacity: 0; transition: "+e/1e3+"s ease opacity; -webkit-transition: "+e/1e3+"s ease opacity;}."+i+"-figure img."+i+"-thumbnail { -webkit-filter: blur(30px); filter: blur(30px); left: auto; position: relative; width: auto;}."+i+"-figure img."+i+"-loaded { opacity: 1;}",n=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",o.styleSheet?o.styleSheet.cssText=s:o.appendChild(document.createTextNode(s)),n.appendChild(o)}(this.settings.containerId,this.settings.classPrefix,this.settings.transitionSpeed),this}function r(t,i,e){return this.existsOnPage=!1,this.aspectRatio=t.aspectRatio,this.filename=t.filename,this.index=i,this.pig=e,this.classNames={figure:e.settings.classPrefix+"-figure",thumbnail:e.settings.classPrefix+"-thumbnail",loaded:e.settings.classPrefix+"-loaded"},this}a.prototype._getTransitionTimeout=function(){return 1.5*this.settings.transitionSpeed},a.prototype._getTransitionString=function(){return this.isTransitioning?this.settings.transitionSpeed/1e3+"s transform ease":"none"},a.prototype._recomputeMinAspectRatio=function(){var t=this.minAspectRatio;this.minAspectRatio=this.settings.getMinAspectRatio(this.lastWindowWidth),null!==t&&t!==this.minAspectRatio?this.minAspectRatioRequiresTransition=!0:this.minAspectRatioRequiresTransition=!1},a.prototype._parseImageData=function(t){var s=[];return t.forEach(function(t,i){var e=new r(t,i,this);s.push(e)}.bind(this)),s},a.prototype._computeLayout=function(){var s=parseInt(this.container.clientWidth),n=[],o=0,a=0,r=0;this._recomputeMinAspectRatio(),!this.isTransitioning&&this.minAspectRatioRequiresTransition&&(this.isTransitioning=!0,setTimeout(function(){this.isTransitioning=!1},this._getTransitionTimeout()));var h=this._getTransitionString();[].forEach.call(this.images,function(t,i){if(r+=parseFloat(t.aspectRatio),n.push(t),r>=this.minAspectRatio||i+1===this.images.length){r=Math.max(r,this.minAspectRatio);var e=(s-this.settings.spaceBetweenImages*(n.length-1))/r;n.forEach(function(t){var i=e*t.aspectRatio;t.style={width:parseInt(i),height:parseInt(e),translateX:o,translateY:a,transition:h},o+=i+this.settings.spaceBetweenImages}.bind(this)),n=[],r=0,a+=parseInt(e)+this.settings.spaceBetweenImages,o=0}}.bind(this)),this.totalHeight=a-this.settings.spaceBetweenImages},a.prototype._doLayout=function(){this.container.style.height=this.totalHeight+"px";var t="up"===this.scrollDirection?this.settings.primaryImageBufferHeight:this.settings.secondaryImageBufferHeight,i="down"===this.scrollDirection?this.settings.secondaryImageBufferHeight:this.settings.primaryImageBufferHeight,e=function(t){for(var i=0;isNaN(t.offsetTop)||(i+=t.offsetTop),t=t.offsetParent;);return i}(this.container),s=this.scroller===window?window.innerHeight:this.scroller.offsetHeight,n=this.latestYOffset-e-t,o=this.latestYOffset-e+s+i;this.images.forEach(function(t){t.style.translateY+t.style.height<n||t.style.translateY>o?t.hide():t.load()}.bind(this))},a.prototype._getOnScroll=function(){var i=this;return function(){var t=i.scroller===window?window.pageYOffset:i.scroller.scrollTop;i.previousYOffset=i.latestYOffset||t,i.latestYOffset=t,i.scrollDirection=i.latestYOffset>i.previousYOffset?"down":"up",i.inRAF||(i.inRAF=!0,window.requestAnimationFrame(function(){i._doLayout(),i.inRAF=!1}))}},a.prototype.enable=function(){return this.onScroll=this._getOnScroll(),this.scroller.addEventListener("scroll",this.onScroll),this.onScroll(),this._computeLayout(),this._doLayout(),s.add(function(){this.lastWindowWidth=this.scroller===window?window.innerWidth:this.scroller.offsetWidth,this._computeLayout(),this._doLayout()}.bind(this)),this},a.prototype.disable=function(){return this.scroller.removeEventListener("scroll",this.onScroll),s.disable(),this},r.prototype.load=function(){this.existsOnPage=!0,this._updateStyles(),this.pig.container.appendChild(this.getElement()),setTimeout(function(){this.existsOnPage&&(this.thumbnail||(this.thumbnail=new Image,this.thumbnail.src=this.pig.settings.urlForSize(this.filename,this.pig.settings.thumbnailSize),this.thumbnail.className=this.classNames.thumbnail,this.thumbnail.onload=function(){this.thumbnail&&(this.thumbnail.className+=" "+this.classNames.loaded)}.bind(this),this.getElement().appendChild(this.thumbnail)),this.fullImage||(this.fullImage=new Image,this.fullImage.src=this.pig.settings.urlForSize(this.filename,this.pig.settings.getImageSize(this.pig.lastWindowWidth)),this.fullImage.onload=function(){this.fullImage&&(this.fullImage.className+=" "+this.classNames.loaded)}.bind(this),this.getElement().appendChild(this.fullImage)))}.bind(this),100)},r.prototype.hide=function(){this.getElement()&&(this.thumbnail&&(this.thumbnail.src="",this.getElement().removeChild(this.thumbnail),delete this.thumbnail),this.fullImage&&(this.fullImage.src="",this.getElement().removeChild(this.fullImage),delete this.fullImage)),this.existsOnPage&&this.pig.container.removeChild(this.getElement()),this.existsOnPage=!1},r.prototype.getElement=function(){return this.element||(this.element=document.createElement(this.pig.settings.figureTagName),this.element.className=this.classNames.figure,this.element.addEventListener("click",function(){this.pig.settings.onClickHandler(this.filename)}.bind(this)),this._updateStyles()),this.element},r.prototype._updateStyles=function(){this.getElement().style.transition=this.style.transition,this.getElement().style.width=this.style.width+"px",this.getElement().style.height=this.style.height+"px",this.getElement().style.transform="translate3d("+this.style.translateX+"px,"+this.style.translateY+"px, 0)"},"function"==typeof define&&define.amd?define([],function(){return a}):"undefined"!=typeof module&&module.exports?module.exports=a:t.Pig=a}("undefined"!=typeof window?window:this);'
|
29
|
+
|
30
|
+
def full_size_html(gallery_name, name, date, prev_url, next_url)
|
31
|
+
"---\n" \
|
32
|
+
"layout: post\n" \
|
33
|
+
"title: #{name}\n" \
|
34
|
+
"date: #{date.strftime("%Y-%m-%d %H:%M:%S")}\n" \
|
35
|
+
"permalink: /assets/html/#{gallery_name}/#{name}.html\n" \
|
36
|
+
"exclude: true\n" \
|
37
|
+
"---\n" \
|
38
|
+
"<div><a href=\"#{prev_url}\" style=\"display:inline;\">prev</a><a href=\"#{next_url}\" style=\"display:inline; float:right\">next</a></div>\n" \
|
39
|
+
"<img src=\"{{site.baseurl}}/assets/img/#{gallery_name}/1024/#{name}\"/>\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
def gallery_html(id, image_data)
|
43
|
+
"<div id='#{id}_pig'></div>\n" \
|
44
|
+
"<script src='{{site.baseurl}}/assets/js/pig.min.js'></script>\n" \
|
45
|
+
"<script>\n" \
|
46
|
+
"var #{id}_pig = new Pig(\n" \
|
47
|
+
" #{image_data.to_json()},\n" \
|
48
|
+
" {\n" \
|
49
|
+
" containerId: '#{id}_pig',\n" \
|
50
|
+
" classPrefix: '#{id}_pig',\n" \
|
51
|
+
" urlForSize: function(filename, size) {\n" \
|
52
|
+
" return '{{site.baseurl}}/assets/img/#{id}/' + size + '/' + filename;\n" \
|
53
|
+
" },\n" \
|
54
|
+
" onClickHandler: function(filename) {\n" \
|
55
|
+
" window.location.href = '{{site.baseurl}}/assets/html/#{id}/' + filename + '.html';\n" \
|
56
|
+
" }\n" \
|
57
|
+
" }\n" \
|
58
|
+
").enable();\n" \
|
59
|
+
"</script>"
|
60
|
+
end
|
61
|
+
|
62
|
+
def image_html_url(gallery_name, image_name)
|
63
|
+
"/assets/html/#{gallery_name}/#{image_name}.html"
|
64
|
+
end
|
65
|
+
|
66
|
+
#read the image data from the _includes folder
|
67
|
+
def get_image_data(gallery_name)
|
68
|
+
image_data = []
|
69
|
+
#read image_data if existing
|
70
|
+
if File.exists?(File.join(@data_path, "#{gallery_name}.json"))
|
71
|
+
File.open(File.join(@data_path, "#{gallery_name}.json"), 'r') { |file|
|
72
|
+
#get array of image data (drop 'var imageData = ' and ';')
|
73
|
+
image_data = JSON.parse(file.read)
|
74
|
+
}
|
75
|
+
end
|
76
|
+
image_data
|
77
|
+
end
|
78
|
+
|
79
|
+
#get a list of image file names from a given path
|
80
|
+
def get_images(path)
|
81
|
+
patterns = ['*.jpg', '*.jpeg', '*.png'].map { |ext| File.join(path, ext) }
|
82
|
+
Dir.glob(patterns).map { |filepath| File.basename(filepath) }
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_image(gallery_path, image_name)
|
86
|
+
image = @@image_cache[File.join(gallery_path, image_name)]
|
87
|
+
if image == nil
|
88
|
+
image = MiniMagick::Image.open(File.join(gallery_path, image_name))
|
89
|
+
@@image_cache[File.join(gallery_path, image_name)] = image
|
90
|
+
end
|
91
|
+
image
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_image_date(gallery_path, image_name)
|
95
|
+
image_date = nil
|
96
|
+
begin
|
97
|
+
image = get_image(gallery_path, image_name)
|
98
|
+
exif_date = image.exif['DateTimeOriginal']
|
99
|
+
if exif_date == nil
|
100
|
+
#no exif date, try to get from file name
|
101
|
+
image_date = Time.strptime(image_name, "%Y-%m-%d")
|
102
|
+
else
|
103
|
+
#try to get the image date from exif
|
104
|
+
image_date = Time.strptime(exif_date, "%Y:%m:%d %H:%M:%S")
|
105
|
+
end
|
106
|
+
rescue
|
107
|
+
#get the date from file if possible
|
108
|
+
image_date = File.mtime(File.join(gallery_path, image_name))
|
109
|
+
end
|
110
|
+
image_date
|
111
|
+
end
|
112
|
+
|
113
|
+
def get_previous_url(image_data, gallery_name, image_name)
|
114
|
+
index = image_data.index { |data| data['filename'] == image_name }
|
115
|
+
index = index - 1
|
116
|
+
if index < 0
|
117
|
+
index = image_data.length - 1
|
118
|
+
end
|
119
|
+
image_html_url(gallery_name, image_data[index]['filename'])
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_next_url(image_data, gallery_name, image_name)
|
123
|
+
index = image_data.index { |data| data['filename'] == image_name }
|
124
|
+
index = index + 1
|
125
|
+
if index >= image_data.length
|
126
|
+
index = 0
|
127
|
+
end
|
128
|
+
image_html_url(gallery_name, image_data[index]['filename'])
|
129
|
+
end
|
130
|
+
|
131
|
+
#create thumbnails and fullsize image assets
|
132
|
+
def process_images(image_data, gallery_id, gallery_path, images)
|
133
|
+
#create thumbs
|
134
|
+
sizes = [1024, 500, 250, 100, 20]
|
135
|
+
sizes.each { |size|
|
136
|
+
#output path for current size
|
137
|
+
size_out_path = File.join(@img_path, gallery_id, size.to_s)
|
138
|
+
FileUtils.mkdir_p size_out_path unless File.exists? size_out_path
|
139
|
+
|
140
|
+
#images that have already been processed for the current size
|
141
|
+
done_images = get_images(size_out_path)
|
142
|
+
#all images in the gallery with the ones already done taken away
|
143
|
+
todo_images = images - done_images
|
144
|
+
|
145
|
+
#function to get the source path to use for creating the given size thumbnail
|
146
|
+
#i.e. use the 500px sized images to make the 250px versions
|
147
|
+
source_for_size = -> (size) {
|
148
|
+
index = sizes.index(size)
|
149
|
+
source = gallery_path
|
150
|
+
if index != nil && index != 0
|
151
|
+
source = File.join(@img_path, gallery_id, sizes[index - 1].to_s)
|
152
|
+
end
|
153
|
+
source
|
154
|
+
}
|
155
|
+
|
156
|
+
#do the processing in a batch
|
157
|
+
mog = MiniMagick::Tool::Mogrify.new
|
158
|
+
mog.resize("x#{size}")
|
159
|
+
mog.sampling_factor('4:2:0')
|
160
|
+
mog.interlace('Plane')
|
161
|
+
mog.strip()
|
162
|
+
mog.quality('75')
|
163
|
+
mog.path(size_out_path)
|
164
|
+
source_path = source_for_size.call(size)
|
165
|
+
todo_images.each { |todo| mog << File.join(source_path, todo) }
|
166
|
+
mog.call
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
#create full size html page for a given image
|
171
|
+
def process_image(image_data, gallery_id, gallery_path, image_name)
|
172
|
+
full_size_html_path = File.join(@html_path, gallery_id, image_name + ".html")
|
173
|
+
#create full size html if it doesn't exist
|
174
|
+
if not File.exists? full_size_html_path
|
175
|
+
#get image date
|
176
|
+
image_date = get_image_date(gallery_path, image_name)
|
177
|
+
#create full size html text
|
178
|
+
full_size_html = full_size_html(gallery_id, image_name, image_date,
|
179
|
+
get_previous_url(image_data, gallery_id, image_name),
|
180
|
+
get_next_url(image_data, gallery_id, image_name))
|
181
|
+
File.open(full_size_html_path, 'w') { |file|
|
182
|
+
file.write(full_size_html)
|
183
|
+
}
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_paths
|
188
|
+
@assets_path = File.join(@site.source, "assets")
|
189
|
+
@js_path = File.join(@assets_path, "js")
|
190
|
+
@data_path = File.join(@site.source, "_data")
|
191
|
+
@img_path = File.join(@assets_path, "img")
|
192
|
+
@html_path = File.join(@assets_path, "html")
|
193
|
+
@includes_path = File.join(@site.source, "_includes")
|
194
|
+
end
|
195
|
+
|
196
|
+
def get_galleries
|
197
|
+
galleries = []
|
198
|
+
config_galleries = Jekyll.configuration({})['galleries']
|
199
|
+
if config_galleries != nil
|
200
|
+
config_galleries.each do |gallery|
|
201
|
+
full_path = File.join(@site.source, gallery['path'])
|
202
|
+
if File.directory?(full_path)
|
203
|
+
galleries << SourceGallery.new(full_path, gallery['name'])
|
204
|
+
end
|
205
|
+
end
|
206
|
+
else
|
207
|
+
default_gallery_path = File.join(@site.source, 'gallery')
|
208
|
+
if File.directory?(default_gallery_path)
|
209
|
+
galleries << SourceGallery.new(default_gallery_path, 'gallery')
|
210
|
+
end
|
211
|
+
end
|
212
|
+
galleries
|
213
|
+
end
|
214
|
+
|
215
|
+
def make_output_paths
|
216
|
+
FileUtils.mkdir_p @assets_path unless File.exists? @assets_path
|
217
|
+
FileUtils.mkdir_p @js_path unless File.exists? @js_path
|
218
|
+
FileUtils.mkdir_p @img_path unless File.exists? @img_path
|
219
|
+
FileUtils.mkdir_p @html_path unless File.exists? @html_path
|
220
|
+
FileUtils.mkdir_p @includes_path unless File.exists? @includes_path
|
221
|
+
FileUtils.mkdir_p @data_path unless File.exists? @data_path
|
222
|
+
end
|
223
|
+
|
224
|
+
def augment_image_data(gallery, image_data, images)
|
225
|
+
images.each do |image_name|
|
226
|
+
#append data to image_data array if it's not already there
|
227
|
+
if not image_data.any? { |data| data['filename'] == image_name }
|
228
|
+
#get image date
|
229
|
+
image_date = get_image_date(gallery.path, image_name)
|
230
|
+
image = get_image(gallery.path, image_name)
|
231
|
+
image_data <<
|
232
|
+
{
|
233
|
+
'datetime' => image_date.to_s,
|
234
|
+
'filename' => image_name,
|
235
|
+
'aspectRatio' => image.width.to_f / image.height
|
236
|
+
}
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def generate(site)
|
242
|
+
@site = site
|
243
|
+
get_paths()
|
244
|
+
make_output_paths()
|
245
|
+
galleries = get_galleries()
|
246
|
+
galleries.each do |gallery|
|
247
|
+
|
248
|
+
#make gallery specific html and image output paths
|
249
|
+
html_output_path = File.join(@html_path, gallery.name)
|
250
|
+
FileUtils.mkdir_p html_output_path unless File.exists? html_output_path
|
251
|
+
img_output_path = File.join(@img_path, gallery.name)
|
252
|
+
FileUtils.mkdir_p img_output_path unless File.exists? img_output_path
|
253
|
+
|
254
|
+
#write pig.min.js to js path
|
255
|
+
if not File.exists? File.join(@js_path, 'pig.min.js')
|
256
|
+
File.open(File.join(@js_path, 'pig.min.js'), 'w') { |file| file.write(@@pig_min_js) }
|
257
|
+
end
|
258
|
+
|
259
|
+
#get image data from _data
|
260
|
+
image_data = get_image_data(gallery.name)
|
261
|
+
old_image_data = image_data.clone
|
262
|
+
|
263
|
+
#get images from gallery
|
264
|
+
images = get_images(gallery.path)
|
265
|
+
|
266
|
+
#add any additional images to image_data
|
267
|
+
augment_image_data(gallery, image_data, images)
|
268
|
+
|
269
|
+
#sort image data
|
270
|
+
image_data = image_data.sort_by { |data| data['datetime'] }
|
271
|
+
|
272
|
+
#create thumbs
|
273
|
+
process_images(image_data, gallery.name, gallery.path, images)
|
274
|
+
|
275
|
+
images.each do |image_name|
|
276
|
+
#create html assets for each image
|
277
|
+
process_image(image_data, gallery.name, gallery.path, image_name)
|
278
|
+
end
|
279
|
+
|
280
|
+
if image_data != old_image_data
|
281
|
+
#write image_data
|
282
|
+
File.open(File.join(@data_path, "#{gallery.name}.json"), 'w') { |file|
|
283
|
+
file.write(image_data.to_json)
|
284
|
+
}
|
285
|
+
|
286
|
+
#save this gallery's includable content
|
287
|
+
File.open(File.join(@includes_path, "#{gallery.name}.html"), 'w') { |file|
|
288
|
+
file.write(gallery_html(gallery.name, image_data))
|
289
|
+
}
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-pig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Colin Holzman
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2020-03-04 00:00:00.000000000 Z
|
@@ -36,7 +36,7 @@ homepage: https://github.com/clnhlzmn/jekyll-pig
|
|
36
36
|
licenses:
|
37
37
|
- MIT
|
38
38
|
metadata: {}
|
39
|
-
post_install_message:
|
39
|
+
post_install_message:
|
40
40
|
rdoc_options: []
|
41
41
|
require_paths:
|
42
42
|
- lib
|
@@ -52,9 +52,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
52
|
version: '0'
|
53
53
|
requirements:
|
54
54
|
- ImageMagick or GraphicsMagick
|
55
|
-
|
56
|
-
|
57
|
-
signing_key:
|
55
|
+
rubygems_version: 3.1.2
|
56
|
+
signing_key:
|
58
57
|
specification_version: 4
|
59
58
|
summary: Jekyll image gallery generator
|
60
59
|
test_files: []
|