imgViewer-rails 0.9.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bdad703484d766bbc86075a32b2796d527b663b2
4
+ data.tar.gz: 6f4730482aeb1b8bd31dfab4df43bd09707cd5e6
5
+ SHA512:
6
+ metadata.gz: 3fe599a3bc0c28d1f3cc078b323dc2f41d53dad2f662ef9fe89c4467512e2e9420427a6ba3383123e1e31756262142dca57591957bc551c82055e46c551e2693
7
+ data.tar.gz: 44e37b6671e66222d07395ed63d923ebffc26887bf76671019e56b60262be5ea7081257682fc3f012e3e2a1b5dd810043f84d725179db81e0d3fbb033365ae1f
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017 Wayne Mogg (https://github.com/waynegm)
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,30 @@
1
+ imgViewer-Rails [![Gem Version][version-badge]][rubygems]
2
+ ===================
3
+
4
+ [imgViewer](https://github.com/waynegm/imgViewer), jQuery plugin to zoom and pan images rails wrap.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'imgViewer-rails'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ ## How to use
17
+
18
+ Add to your JavaScript manifest file (application.js):
19
+
20
+ ```js
21
+ //= require hammer
22
+ //= require jquery.hammer
23
+ //= require jquery.mousewheel
24
+ //= require imgViewer
25
+ ```
26
+
27
+ Visit [official doc](https://github.com/waynegm/imgViewer#documentation)
28
+
29
+ [version-badge]: https://badge.fury.io/rb/imgViewer-rails.svg
30
+ [rubygems]: https://rubygems.org/gems/imgViewer-rails
@@ -0,0 +1,12 @@
1
+ require 'imgViewer-rails/version'
2
+ require 'hammerjs-rails'
3
+ require 'jquery_mousewheel_rails'
4
+
5
+ module Jquery
6
+ module ImgViewer
7
+ module Rails
8
+ class Engine < ::Rails::Engine
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module Jquery
2
+ module ImgViewer
3
+ VERSION = '0.9.1'.freeze
4
+ end
5
+ end
@@ -0,0 +1,519 @@
1
+ /*! jQuery imgViewer - v0.9.1 - 2016-12-31
2
+ * https://github.com/waynegm/imgViewer
3
+ * Copyright (c) 2016 Wayne Mogg; Licensed MIT */
4
+ /*
5
+ * imgViewer plugin starts here
6
+ */
7
+ ;(function($) {
8
+ $.widget("wgm.imgViewer", {
9
+ options: {
10
+ zoomStep: 0.1,
11
+ zoom: 1,
12
+ zoomMax: 0,
13
+ zoomable: true,
14
+ dragable: true,
15
+ onClick: null,
16
+ onUpdate: null
17
+ },
18
+
19
+ _create: function() {
20
+ var self = this;
21
+ if (!this.element.is("img")) {
22
+ $.error('imgviewer plugin can only be applied to img elements');
23
+ }
24
+ // the original img element
25
+ self.img = self.element[0];
26
+ var $img = $(self.img);
27
+ /*
28
+ * a copy of the original image to be positioned over it and manipulated to
29
+ * provide zoom and pan
30
+ */
31
+ self.zimg = $("<img/>", {"src": self.img.src}).appendTo("body").wrap("<div class='viewport'/>");
32
+ var $zimg = $(self.zimg);
33
+ // the container or viewport for the image view
34
+ self.view = $(self.zimg).parent();
35
+ var $view = $(self.view);
36
+ // the pixel coordinate of the original image at the center of the viewport
37
+ self.vCenter = {};
38
+ // a flag used to decide if a mouse click is part of a drag or a proper click
39
+ self.drag = false;
40
+ self.pinch = false;
41
+ // a flag used to check the target image has loaded
42
+ self.ready = false;
43
+ $img.one("load",function() {
44
+ // get and some geometry information about the image
45
+ self.ready = true;
46
+ var width = $img.width(),
47
+ height = $img.height(),
48
+ offset = $img.offset();
49
+ // cache the image padding information
50
+ self.offsetPadding = {
51
+ top: parseInt($img.css('padding-top'),10),
52
+ left: parseInt($img.css('padding-left'),10),
53
+ right: parseInt($img.css('padding-right'),10),
54
+ bottom: parseInt($img.css('padding-bottom'),10)
55
+ };
56
+ /*
57
+ * cache the image margin/border size information
58
+ * because of IE8 limitations left and right borders are assumed to be the same width
59
+ * and likewise top and bottom borders
60
+ */
61
+ self.offsetBorder = {
62
+ x: Math.round(($img.outerWidth()-$img.innerWidth())/2),
63
+ y: Math.round(($img.outerHeight()-$img.innerHeight())/2)
64
+ };
65
+ /*
66
+ * define the css style for the view container using absolute positioning to
67
+ * put it directly over the original image
68
+ */
69
+ var vTop = offset.top + self.offsetBorder.y + self.offsetPadding.top,
70
+ vLeft = offset.left + self.offsetBorder.x + self.offsetPadding.left;
71
+
72
+ $view.css({
73
+ position: "absolute",
74
+ overflow: "hidden",
75
+ top: vTop+"px",
76
+ left: vLeft+"px",
77
+ width: width+"px",
78
+ height: height+"px"
79
+ });
80
+ // the zoom and pan image is position relative to the view container
81
+ $zimg.css({
82
+ position: "relative",
83
+ top: 0+"px",
84
+ left: 0+"px",
85
+ width: width+"px",
86
+ height: height+"px",
87
+ "-webkit-tap-highlight-color": "transparent"
88
+ });
89
+ // the initial view is centered at the orignal image
90
+ self.vCenter = {
91
+ x: width/2,
92
+ y: height/2
93
+ };
94
+ self.update();
95
+ }).each(function() {
96
+ if (this.complete) { $(this).load(); }
97
+ });
98
+ /*
99
+ * Render loop code during dragging and scaling using requestAnimationFrame
100
+ */
101
+ self.render = false;
102
+ /*
103
+ * Event handlers
104
+ */
105
+ $zimg.hammer();
106
+
107
+ if (self.options.zoomable) {
108
+ self._bind_zoom_events();
109
+ }
110
+ if (self.options.dragable) {
111
+ self._bind_drag_events();
112
+ }
113
+ $zimg.on("tap", function(ev) {
114
+ ev.preventDefault();
115
+ if (!self.dragging) {
116
+ ev.pageX = ev.gesture.center.x + window.scrollX;
117
+ ev.pageY = ev.gesture.center.y + window.scrollY;
118
+ self._trigger("onClick", ev, self);
119
+ }
120
+ });
121
+ /*
122
+ * Window resize handler
123
+ */
124
+
125
+ $(window).resize(function() {
126
+ /*
127
+ * the aim is to keep the view centered on the same location in the original image
128
+ */
129
+ if (self.ready) {
130
+ self.vCenter.x *=$img.width()/$view.width();
131
+ self.vCenter.y *= $img.height()/$view.height();
132
+ self.update();
133
+ }
134
+ });
135
+ },
136
+ /*
137
+ * Bind events
138
+ */
139
+ _bind_zoom_events: function() {
140
+ var self = this;
141
+ var $zimg = $(self.zimg);
142
+
143
+ function startRenderLoop() {
144
+ if (!self.render) {
145
+ self.render = true;
146
+ doRender();
147
+ }
148
+ }
149
+ function stopRenderLoop() {
150
+ self.render = false;
151
+ }
152
+ function doRender() {
153
+ if (self.render) {
154
+ window.requestAnimationFrame(doRender);
155
+ self.update();
156
+ }
157
+ }
158
+
159
+ $zimg.on("mousewheel", function(ev) {
160
+ ev.preventDefault();
161
+ var delta = ev.deltaY ;
162
+ self.options.zoom -= delta * self.options.zoomStep;
163
+ self.update();
164
+ });
165
+
166
+ $zimg.data("hammer").recognizers[1].options.enable = true;
167
+
168
+ $zimg.on("pinchstart", function() {
169
+ });
170
+
171
+ $zimg.on("pinch", function(ev) {
172
+ ev.preventDefault();
173
+ if (!self.pinch) {
174
+ self.pinchstart = { x: ev.gesture.center.x + window.scrollX, y: ev.gesture.center.y + window.scrollY};
175
+ self.pinchstartrelpos = self.cursorToImg(self.pinchstart.x, self.pinchstart.y);
176
+ self.pinchstart_scale = self.options.zoom;
177
+ startRenderLoop();
178
+ self.pinch = true;
179
+ } else {
180
+ self.options.zoom = ev.gesture.scale * self.pinchstart_scale;
181
+ var npos = self.imgToCursor( self.pinchstartrelpos.x, self.pinchstartrelpos.y);
182
+ self.vCenter.x = self.vCenter.x + (npos.x - self.pinchstart.x)/self.options.zoom;
183
+ self.vCenter.y = self.vCenter.y + (npos.y - self.pinchstart.y)/self.options.zoom;
184
+ }
185
+ });
186
+
187
+ $zimg.on("pinchend", function(ev) {
188
+ ev.preventDefault();
189
+ if (self.pinch) {
190
+ stopRenderLoop();
191
+ self.update();
192
+ self.pinch = false;
193
+ }
194
+ });
195
+ },
196
+
197
+ _bind_drag_events: function() {
198
+ var self = this;
199
+ var $zimg = $(self.zimg);
200
+ function startRenderLoop() {
201
+ if (!self.render) {
202
+ self.render = true;
203
+ doRender();
204
+ }
205
+ }
206
+ function stopRenderLoop() {
207
+ self.render = false;
208
+ }
209
+ function doRender() {
210
+ if (self.render) {
211
+ window.requestAnimationFrame(doRender);
212
+ self.update();
213
+ }
214
+ }
215
+ $zimg.on("pan", function(ev) {
216
+ ev.preventDefault();
217
+ if (!self.drag) {
218
+ self.drag = true;
219
+ self.dragXorg = self.vCenter.x;
220
+ self.dragYorg = self.vCenter.y;
221
+ startRenderLoop();
222
+ } else {
223
+ self.vCenter.x = self.dragXorg - ev.gesture.deltaX/self.options.zoom;
224
+ self.vCenter.y = self.dragYorg - ev.gesture.deltaY/self.options.zoom;
225
+ }
226
+ });
227
+
228
+ $zimg.on( "panend", function(ev) {
229
+ ev.preventDefault();
230
+ if (self.drag) {
231
+ self.drag = false;
232
+ stopRenderLoop();
233
+ self.update();
234
+ }
235
+ });
236
+ },
237
+ /*
238
+ * Unbind events
239
+ */
240
+ _unbind_zoom_events: function() {
241
+ var self = this;
242
+ var $zimg = $(self.zimg);
243
+ $zimg.data("hammer").recognizers[1].options.enable = false;
244
+ $zimg.off("mousewheel");
245
+ $zimg.off("pinchstart");
246
+ $zimg.off("pinch");
247
+ $zimg.off("pinchend");
248
+ },
249
+
250
+ _unbind_drag_events: function() {
251
+ var self = this;
252
+ var $zimg = $(self.zimg);
253
+ $zimg.off("pan");
254
+ $zimg.off("panend");
255
+ },
256
+
257
+ /*
258
+ * Remove the plugin
259
+ */
260
+ destroy: function() {
261
+ var $zimg = $(this.zimg);
262
+ $zimg.unbind("click");
263
+ $(window).unbind("resize");
264
+ $zimg.remove();
265
+ $(this.view).remove();
266
+ $.Widget.prototype.destroy.call(this);
267
+ },
268
+
269
+ _setOption: function(key, value) {
270
+ switch(key) {
271
+ case 'zoom':
272
+ if (parseFloat(value) < 1 || isNaN(parseFloat(value))) {
273
+ return;
274
+ }
275
+ break;
276
+ case 'zoomStep':
277
+ if (parseFloat(value) <= 0 || isNaN(parseFloat(value))) {
278
+ return;
279
+ }
280
+ break;
281
+ case 'zoomMax':
282
+ if (parseFloat(value) < 0 || isNaN(parseFloat(value))) {
283
+ return;
284
+ }
285
+ break;
286
+ }
287
+ var version = $.ui.version.split('.');
288
+ if (version[0] > 1 || version[1] > 8) {
289
+ this._super(key, value);
290
+ } else {
291
+ $.Widget.prototype._setOption.apply(this, arguments);
292
+ }
293
+ switch(key) {
294
+ case 'zoom':
295
+ if (this.ready) {
296
+ this.update();
297
+ }
298
+ break;
299
+ case 'zoomable':
300
+ if (this.options.zoomable) {
301
+ this._bind_zoom_events();
302
+ } else {
303
+ this._unbind_zoom_events();
304
+ }
305
+ break;
306
+ case 'dragable':
307
+ if (this.options.dragable) {
308
+ this._bind_drag_events();
309
+ } else {
310
+ this._unbind_drag_events();
311
+ }
312
+ break;
313
+ }
314
+ },
315
+
316
+ addElem: function(elem) {
317
+ $(this.view).append(elem);
318
+ },
319
+ /*
320
+ * Test if a relative image coordinate is visible in the current view
321
+ */
322
+ isVisible: function(relx, rely) {
323
+ var view = this.getView();
324
+ if (view) {
325
+ return (relx >= view.left && relx <= view.right && rely >= view.top && rely <= view.bottom);
326
+ } else {
327
+ return false;
328
+ }
329
+ },
330
+ /*
331
+ * Get relative image coordinates of current view
332
+ */
333
+ getView: function() {
334
+ if (this.ready) {
335
+ var $img = $(this.img),
336
+ width = $img.width(),
337
+ height = $img.height(),
338
+ zoom = this.options.zoom;
339
+ return {
340
+ top: this.vCenter.y/height - 0.5/zoom,
341
+ left: this.vCenter.x/width - 0.5/zoom,
342
+ bottom: this.vCenter.y/height + 0.5/zoom,
343
+ right: this.vCenter.x/width + 0.5/zoom
344
+ };
345
+ } else {
346
+ return null;
347
+ }
348
+ },
349
+ /*
350
+ * Pan the view to be centred at the given relative image location
351
+ */
352
+ panTo: function(relx, rely) {
353
+ if ( this.ready && relx >= 0 && relx <= 1 && rely >= 0 && rely <=1 ) {
354
+ var $img = $(this.img),
355
+ width = $img.width(),
356
+ height = $img.height();
357
+ this.vCenter.x = relx * width;
358
+ this.vCenter.y = rely * height;
359
+ this.update();
360
+ return { x: this.vCenter.x/width, y: this.vCenter.y/height };
361
+ } else {
362
+ return null;
363
+ }
364
+ },
365
+ /*
366
+ * Convert a relative image location to a viewport pixel location
367
+ */
368
+ imgToView: function(relx, rely) {
369
+ if ( this.ready && relx >= 0 && relx <= 1 && rely >= 0 && rely <=1 ) {
370
+ var $img = $(this.img),
371
+ width = $img.width(),
372
+ height = $img.height();
373
+
374
+ var zLeft = width/2 - this.vCenter.x * this.options.zoom;
375
+ var zTop = height/2 - this.vCenter.y * this.options.zoom;
376
+ var vx = relx * width * this.options.zoom + zLeft;
377
+ var vy = rely * height * this.options.zoom + zTop;
378
+ return { x: Math.round(vx), y: Math.round(vy) };
379
+ } else {
380
+
381
+ return null;
382
+ }
383
+ },
384
+ /*
385
+ * Convert a relative image location to a page pixel location
386
+ */
387
+ imgToCursor: function(relx, rely) {
388
+ var pos = this.imgToView(relx, rely);
389
+ if (pos) {
390
+ var offset = $(this.img).offset();
391
+ pos.x += offset.left + this.offsetBorder.x + this.offsetPadding.left;
392
+ pos.y += offset.top + this.offsetBorder.y + this.offsetPadding.top;
393
+ return pos;
394
+ } else {
395
+ return null;
396
+ }
397
+ },
398
+ /*
399
+ * Convert a viewport pixel location to a relative image coordinate
400
+ */
401
+ viewToImg: function(vx, vy) {
402
+ if (this.ready) {
403
+ var $img = $(this.img),
404
+ width = $img.width(),
405
+ height = $img.height();
406
+ var zLeft = width/2 - this.vCenter.x * this.options.zoom;
407
+ var zTop = height/2 - this.vCenter.y * this.options.zoom;
408
+ var relx= (vx - zLeft)/(width * this.options.zoom);
409
+ var rely = (vy - zTop)/(height * this.options.zoom);
410
+ if (relx>=0 && relx<=1 && rely>=0 && rely<=1) {
411
+ return {x: relx, y: rely};
412
+ } else {
413
+ return null;
414
+ }
415
+ } else {
416
+ return null;
417
+ }
418
+ },
419
+
420
+ /*
421
+ * Convert a page pixel location to a relative image coordinate
422
+ */
423
+ cursorToImg: function(cx, cy) {
424
+ if (this.ready) {
425
+ var $img = $(this.img),
426
+ width = $img.width(),
427
+ height = $img.height(),
428
+ offset = $img.offset();
429
+ var zLeft = width/2 - this.vCenter.x * this.options.zoom;
430
+ var zTop = height/2 - this.vCenter.y * this.options.zoom;
431
+ var relx = (cx - offset.left - this.offsetBorder.x - this.offsetPadding.left- zLeft)/(width * this.options.zoom);
432
+ var rely = (cy - offset.top - this.offsetBorder.y - this.offsetPadding.top - zTop)/(height * this.options.zoom);
433
+ if (relx>=0 && relx<=1 && rely>=0 && rely<=1) {
434
+ return {x: relx, y: rely};
435
+ } else {
436
+ return null;
437
+ }
438
+ } else {
439
+ return null;
440
+ }
441
+ },
442
+ /*
443
+ * Adjust the display of the image
444
+ */
445
+ update: function() {
446
+ if (this.ready) {
447
+ var zTop, zLeft, zWidth, zHeight,
448
+ $img = $(this.img),
449
+ width = $img.width(),
450
+ height = $img.height(),
451
+ offset = $img.offset(),
452
+ zoom = this.options.zoom,
453
+ zoomMax = this.options.zoomMax,
454
+ half_width = width/2,
455
+ half_height = height/2;
456
+
457
+ if (zoomMax !==0) {
458
+ zoom = Math.min(zoom, zoomMax);
459
+ this.options.zoom = zoom;
460
+ }
461
+ if (zoom <= 1) {
462
+ zTop = 0;
463
+ zLeft = 0;
464
+ zWidth = width;
465
+ zHeight = height;
466
+ this.vCenter = {
467
+ x: half_width,
468
+ y: half_height
469
+ };
470
+ this.options.zoom = 1;
471
+ zoom = 1;
472
+ } else {
473
+ zTop = Math.round(half_height - this.vCenter.y * zoom);
474
+ zLeft = Math.round(half_width - this.vCenter.x * zoom);
475
+ zWidth = Math.round(width * zoom);
476
+ zHeight = Math.round(height * zoom);
477
+ /*
478
+ * adjust the view center so the image edges snap to the edge of the view
479
+ */
480
+ if (zLeft > 0) {
481
+ this.vCenter.x = half_width/zoom;
482
+ zLeft = 0;
483
+ } else if (zLeft+zWidth < width) {
484
+ this.vCenter.x = width - half_width/zoom ;
485
+ zLeft = width - zWidth;
486
+ }
487
+ if (zTop > 0) {
488
+ this.vCenter.y = half_height/zoom;
489
+ zTop = 0;
490
+ } else if (zTop + zHeight < height) {
491
+ this.vCenter.y = height - half_height/zoom;
492
+ zTop = height - zHeight;
493
+ }
494
+ }
495
+ var vTop = Math.round(offset.top + this.offsetBorder.y + this.offsetPadding.top),
496
+ vLeft = Math.round(offset.left + this.offsetBorder.x + this.offsetPadding.left);
497
+ $(this.view).css({
498
+ top: vTop+"px",
499
+ left: vLeft+"px",
500
+ width: width+"px",
501
+ height: height+"px"
502
+ });
503
+ $(this.zimg).css({
504
+ width: width+"px",
505
+ height: height+"px"
506
+ });
507
+
508
+ var xt = -(this.vCenter.x - half_width)*zoom;
509
+ var yt = -(this.vCenter.y - half_height)*zoom;
510
+ $(this.zimg).css({transform: "translate(" + xt + "px," + yt + "px) scale(" + zoom + "," + zoom + ")" });
511
+ /*
512
+ * define the onUpdate option to do something after the image is redisplayed
513
+ * probably shouldn't pass out the this object - need to think of something better
514
+ */
515
+ this._trigger("onUpdate", null, this);
516
+ }
517
+ }
518
+ });
519
+ })(jQuery);
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: imgViewer-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.1
5
+ platform: ruby
6
+ authors:
7
+ - Wayne Mogg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hammerjs-rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.8
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.8
27
+ - !ruby/object:Gem::Dependency
28
+ name: jquery_mousewheel_rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.1.12
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.1.12
41
+ description: jQuery plugin to zoom and pan images.
42
+ email:
43
+ - waynegm@gmail.com
44
+ - eric@managebac.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - LICENSE
50
+ - README.md
51
+ - lib/imgViewer-rails.rb
52
+ - lib/imgViewer-rails/version.rb
53
+ - vendor/assets/javascripts/imgViewer.js
54
+ homepage: https://github.com/eduvo/imgViewer-rails
55
+ licenses:
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.6.14
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: jQuery plugin to zoom and pan images, even those with a size that is a percentage
78
+ of their container.
79
+ test_files: []