workarea-jquery_zoom 1.0.0
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 +7 -0
- data/.editorconfig +20 -0
- data/.eslintrc.json +35 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +54 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +1 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +6 -0
- data/LICENSE.md +3 -0
- data/README.md +100 -0
- data/Rakefile +109 -0
- data/app/assets/javascripts/jquery_zoom/jquery.zoom.js +610 -0
- data/bin/rails +20 -0
- data/config/initializers/appends.rb +7 -0
- data/config/initializers/workarea.rb +3 -0
- data/config/routes.rb +2 -0
- data/lib/tasks/jquery_zoom_tasks.rake +4 -0
- data/lib/workarea/jquery_zoom.rb +11 -0
- data/lib/workarea/jquery_zoom/engine.rb +9 -0
- data/lib/workarea/jquery_zoom/version.rb +5 -0
- data/package.json +9 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +4 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +38 -0
- data/test/dummy/bin/update +29 -0
- data/test/dummy/bin/yarn +11 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +28 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +54 -0
- data/test/dummy/config/environments/production.rb +91 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +14 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +56 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/secrets.yml +32 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/package.json +5 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +10 -0
- data/workarea-jquery_zoom.gemspec +22 -0
- data/yarn.lock +3290 -0
- metadata +147 -0
@@ -0,0 +1,610 @@
|
|
1
|
+
/**
|
2
|
+
* @author Jeremie Ges <jges@weblinc.com>
|
3
|
+
*/
|
4
|
+
(function($) {
|
5
|
+
function Zoom() {
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Cache DOM properties
|
9
|
+
* @type {Object}
|
10
|
+
*/
|
11
|
+
this.$dom = {
|
12
|
+
container: null,
|
13
|
+
image: null,
|
14
|
+
thumbnail: null
|
15
|
+
},
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Keep track of things
|
19
|
+
* @type {Object}
|
20
|
+
*/
|
21
|
+
this.flags = {
|
22
|
+
|
23
|
+
/**
|
24
|
+
* The current scale
|
25
|
+
* @type {Number}
|
26
|
+
*/
|
27
|
+
currentScale: 1,
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Check if the zoom image is loaded
|
31
|
+
* @type {Boolean}
|
32
|
+
*/
|
33
|
+
imageLoaded: false,
|
34
|
+
|
35
|
+
/**
|
36
|
+
* We use "transform: translate()" to "move" the
|
37
|
+
* zoom image (for smooth animations). When X or Y
|
38
|
+
* change, we update this property.
|
39
|
+
* @type {Object}
|
40
|
+
*/
|
41
|
+
imageTranslate: {
|
42
|
+
x: 0,
|
43
|
+
y: 0
|
44
|
+
},
|
45
|
+
|
46
|
+
/**
|
47
|
+
* When the user starts to pinch, we keep track of the
|
48
|
+
* coordinates and "freeze" them until the pinch stops.
|
49
|
+
* Therefore the scale up / down is smoother.
|
50
|
+
* @type {Object}
|
51
|
+
*/
|
52
|
+
pinchCoordinates: {
|
53
|
+
x: 0,
|
54
|
+
y: 0
|
55
|
+
},
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Flag to know if we have to scale down or scale up
|
59
|
+
* @type {Number}
|
60
|
+
*/
|
61
|
+
pinchScale: 0,
|
62
|
+
|
63
|
+
/**
|
64
|
+
* The Hammer js created instance (to be able to destroy it)
|
65
|
+
* @type {Object}
|
66
|
+
*/
|
67
|
+
hammer: null
|
68
|
+
},
|
69
|
+
|
70
|
+
this.options = {},
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Main entry of the widget
|
74
|
+
* @param {jQueryElement} container The scope
|
75
|
+
* @param {Object} options The options given by the user
|
76
|
+
*/
|
77
|
+
this.init = function(container, options) {
|
78
|
+
this.$dom.container = $(container);
|
79
|
+
this.options = _.extend($.fn.zoom.defaults, options);
|
80
|
+
this.setup();
|
81
|
+
this.events();
|
82
|
+
},
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Setup prerequisites before to listen
|
86
|
+
* the events
|
87
|
+
*/
|
88
|
+
this.setup = function() {
|
89
|
+
this.setupImage();
|
90
|
+
this.setupThumbnail();
|
91
|
+
this.setupLoadImage();
|
92
|
+
},
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Create a blank image where the zoom image
|
96
|
+
* will be stored
|
97
|
+
*/
|
98
|
+
this.setupImage = function() {
|
99
|
+
this.$dom.image = $('<img/>');
|
100
|
+
},
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Alias the $dom property thumbnail
|
104
|
+
* to the right image
|
105
|
+
*/
|
106
|
+
this.setupThumbnail = function() {
|
107
|
+
this.$dom.thumbnail = this.$dom.container.find('img').first();
|
108
|
+
},
|
109
|
+
|
110
|
+
/**
|
111
|
+
* Will load the image directly if
|
112
|
+
* needed.
|
113
|
+
*/
|
114
|
+
this.setupLoadImage = function() {
|
115
|
+
if (this.options.lazyLoad) {
|
116
|
+
return;
|
117
|
+
}
|
118
|
+
|
119
|
+
this.loadImage();
|
120
|
+
},
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Start to listen the events.
|
124
|
+
*/
|
125
|
+
this.events = function() {
|
126
|
+
this.$dom.image.on('load', this.onLoadImage.bind(this));
|
127
|
+
|
128
|
+
this.getInstanceHammer(this.$dom.container.get(0))
|
129
|
+
.on('doubletap', this.onDoubleTapContainer.bind(this))
|
130
|
+
.on('pan', this.onPanContainer.bind(this))
|
131
|
+
.on('pinchstart', this.onPinchStartContainer.bind(this))
|
132
|
+
.on('pinch', this.onPinchContainer.bind(this));
|
133
|
+
|
134
|
+
this.$dom.container.on('zoom.destroy', this.onDestroy.bind(this));
|
135
|
+
|
136
|
+
if (this.options.lazyLoad) {
|
137
|
+
this.$dom.container.on('click', this.onClickContainer.bind(this));
|
138
|
+
}
|
139
|
+
},
|
140
|
+
|
141
|
+
/**
|
142
|
+
* When the zoom image is loaded
|
143
|
+
*/
|
144
|
+
this.onLoadImage = function() {
|
145
|
+
this.$dom.image
|
146
|
+
.css({
|
147
|
+
opacity: 1,
|
148
|
+
position: 'absolute',
|
149
|
+
top: 0,
|
150
|
+
left: 0,
|
151
|
+
width: this.$dom.container.width(),
|
152
|
+
height: this.$dom.container.outerHeight(),
|
153
|
+
border: 'none',
|
154
|
+
maxWidth: 'none',
|
155
|
+
maxHeight: 'none',
|
156
|
+
transformOrigin: '0 0',
|
157
|
+
transform: 'translate(0, 0) scale(1)',
|
158
|
+
transition: 'all 1s'
|
159
|
+
})
|
160
|
+
.attr('role', 'presentation')
|
161
|
+
.appendTo(this.$dom.container);
|
162
|
+
|
163
|
+
this.$dom.container.css('overflow', 'hidden');
|
164
|
+
|
165
|
+
this.flags.imageLoaded = true;
|
166
|
+
},
|
167
|
+
|
168
|
+
/**
|
169
|
+
* This callback is only called if the lazyLoad option is set to true.
|
170
|
+
* Click on the container will trigger the load.
|
171
|
+
*/
|
172
|
+
this.onClickContainer = function() {
|
173
|
+
this.loadImage();
|
174
|
+
this.$dom.container.off('click');
|
175
|
+
},
|
176
|
+
|
177
|
+
/**
|
178
|
+
* When the user start to pan on the container
|
179
|
+
*/
|
180
|
+
this.onPanContainer = function(e) {
|
181
|
+
|
182
|
+
var x = this.flags.imageTranslate.x,
|
183
|
+
y = this.flags.imageTranslate.y,
|
184
|
+
newX = x - (e.deltaX / 3),
|
185
|
+
newY = y - (e.deltaY / 3);
|
186
|
+
|
187
|
+
e.preventDefault();
|
188
|
+
|
189
|
+
if (!this.flags.imageLoaded) {
|
190
|
+
return;
|
191
|
+
}
|
192
|
+
|
193
|
+
if (newX > 0) {
|
194
|
+
newX = 0;
|
195
|
+
}
|
196
|
+
|
197
|
+
if (newY > 0) {
|
198
|
+
newY = 0;
|
199
|
+
}
|
200
|
+
|
201
|
+
if (newX < this.getPanLimits().x) {
|
202
|
+
newX = this.getPanLimits().x;
|
203
|
+
}
|
204
|
+
|
205
|
+
if (newY < this.getPanLimits().y) {
|
206
|
+
newY = this.getPanLimits().y;
|
207
|
+
}
|
208
|
+
|
209
|
+
this.$dom.image.css({
|
210
|
+
transition: 'all 0s'
|
211
|
+
});
|
212
|
+
|
213
|
+
this.updateImage(newX, newY);
|
214
|
+
},
|
215
|
+
|
216
|
+
/**
|
217
|
+
* When the user starts to pinch the container
|
218
|
+
* we want to keep track of the point clicked
|
219
|
+
* (coordinates) to scale up / down gracefully.
|
220
|
+
* @param {Event} e The pinch event
|
221
|
+
*/
|
222
|
+
this.onPinchStartContainer = function(e) {
|
223
|
+
e.preventDefault();
|
224
|
+
|
225
|
+
if (!this.flags.imageLoaded) {
|
226
|
+
return;
|
227
|
+
}
|
228
|
+
|
229
|
+
this.$dom.image.css({
|
230
|
+
transition: 'all 1s'
|
231
|
+
});
|
232
|
+
|
233
|
+
this.flags.pinchCoordinates = e.center;
|
234
|
+
},
|
235
|
+
|
236
|
+
/**
|
237
|
+
* Guess if we have to scale up / down
|
238
|
+
* the zoom image on pinch
|
239
|
+
* @param {Event} e The pinch event
|
240
|
+
*/
|
241
|
+
this.onPinchContainer = function(e) {
|
242
|
+
var scale = e.scale;
|
243
|
+
|
244
|
+
e.preventDefault();
|
245
|
+
|
246
|
+
if (!this.flags.imageLoaded) {
|
247
|
+
return;
|
248
|
+
}
|
249
|
+
|
250
|
+
if (scale < this.flags.pinchScale) {
|
251
|
+
this.onScaleDown();
|
252
|
+
} else {
|
253
|
+
this.onScaleUp();
|
254
|
+
}
|
255
|
+
|
256
|
+
this.flags.pinchScale = scale;
|
257
|
+
},
|
258
|
+
|
259
|
+
/**
|
260
|
+
* Scale down the zoom image around the point
|
261
|
+
* clicked by the user at the start of the pinch
|
262
|
+
*/
|
263
|
+
this.onScaleDown = function() {
|
264
|
+
|
265
|
+
var scale = this.flags.currentScale,
|
266
|
+
containerOffset = this.$dom.container.offset(),
|
267
|
+
mousePositionOnImageX,
|
268
|
+
mousePositionOnImageY,
|
269
|
+
offsetX,
|
270
|
+
offsetY,
|
271
|
+
x,
|
272
|
+
y;
|
273
|
+
|
274
|
+
if (!this.flags.imageLoaded) {
|
275
|
+
return;
|
276
|
+
}
|
277
|
+
|
278
|
+
if (scale <= 1) {
|
279
|
+
return;
|
280
|
+
}
|
281
|
+
|
282
|
+
scale = scale - this.options.deltaScale;
|
283
|
+
|
284
|
+
mousePositionOnImageX = this.flags.pinchCoordinates.x - containerOffset.left;
|
285
|
+
mousePositionOnImageY = this.flags.pinchCoordinates.y - containerOffset.top;
|
286
|
+
|
287
|
+
offsetX = mousePositionOnImageX * this.options.deltaScale;
|
288
|
+
offsetY = mousePositionOnImageY * this.options.deltaScale;
|
289
|
+
|
290
|
+
x = this.flags.imageTranslate.x < 0 ? this.flags.imageTranslate.x : 0;
|
291
|
+
y = this.flags.imageTranslate.y < 0 ? this.flags.imageTranslate.y : 0;
|
292
|
+
|
293
|
+
offsetX = offsetX + x;
|
294
|
+
offsetY = offsetY + y;
|
295
|
+
|
296
|
+
if (scale <= 1) {
|
297
|
+
scale = 1;
|
298
|
+
offsetX = 0;
|
299
|
+
offsetY = 0;
|
300
|
+
}
|
301
|
+
|
302
|
+
this.updateImage(offsetX, offsetY, scale);
|
303
|
+
},
|
304
|
+
|
305
|
+
/**
|
306
|
+
* Scale up the zoom image around the point
|
307
|
+
* clicked by the user at the start of the pinch
|
308
|
+
*/
|
309
|
+
this.onScaleUp = function() {
|
310
|
+
|
311
|
+
var scale = this.flags.currentScale + this.options.deltaScale,
|
312
|
+
containerOffset = this.$dom.container.offset(),
|
313
|
+
offsetX,
|
314
|
+
offsetY,
|
315
|
+
mousePositionOnImageX,
|
316
|
+
mousePositionOnImageY;
|
317
|
+
|
318
|
+
if (!this.flags.imageLoaded) {
|
319
|
+
return;
|
320
|
+
}
|
321
|
+
|
322
|
+
if (scale > this.getScaleLimitImage()) {
|
323
|
+
return;
|
324
|
+
}
|
325
|
+
|
326
|
+
mousePositionOnImageX = (this.flags.pinchCoordinates.x - containerOffset.left);
|
327
|
+
mousePositionOnImageY = (this.flags.pinchCoordinates.y - containerOffset.top);
|
328
|
+
|
329
|
+
offsetX = -(mousePositionOnImageX * this.options.deltaScale);
|
330
|
+
offsetY = -(mousePositionOnImageY * this.options.deltaScale);
|
331
|
+
|
332
|
+
offsetX = offsetX < 0 ? offsetX + this.flags.imageTranslate.x : 0;
|
333
|
+
offsetY = offsetY < 0 ? offsetY + this.flags.imageTranslate.y : 0;
|
334
|
+
|
335
|
+
this.updateImage(offsetX, offsetY, scale);
|
336
|
+
},
|
337
|
+
|
338
|
+
/**
|
339
|
+
* When the user double tap on the container,
|
340
|
+
* depending the current scale we zoom the image
|
341
|
+
* to its maximum or minimum
|
342
|
+
*/
|
343
|
+
this.onDoubleTapContainer = function(e) {
|
344
|
+
|
345
|
+
var coordinates = e.center;
|
346
|
+
|
347
|
+
e.preventDefault();
|
348
|
+
|
349
|
+
if (!this.flags.imageLoaded) {
|
350
|
+
return;
|
351
|
+
}
|
352
|
+
|
353
|
+
this.$dom.image.css({
|
354
|
+
transition: 'all 1s'
|
355
|
+
});
|
356
|
+
|
357
|
+
if (this.flags.currentScale === 1) {
|
358
|
+
this.zoomMaximum(coordinates);
|
359
|
+
} else {
|
360
|
+
this.zoomMinimum();
|
361
|
+
}
|
362
|
+
},
|
363
|
+
|
364
|
+
/**
|
365
|
+
* Will scale up to the maximum scale allowed taking in account
|
366
|
+
* the focal point clicked by the user.
|
367
|
+
* @param {Object} coordinates - X / Y of the point clicked
|
368
|
+
*/
|
369
|
+
this.zoomMaximum = function(coordinates) {
|
370
|
+
var maximumScale = this.getScaleLimitImage(),
|
371
|
+
containerOffset = this.$dom.container.offset(),
|
372
|
+
offsetX = -(coordinates.x * (maximumScale - this.flags.currentScale)),
|
373
|
+
offsetY = -(coordinates.y * (maximumScale - this.flags.currentScale));
|
374
|
+
|
375
|
+
this.updateImage(offsetX, offsetY, maximumScale);
|
376
|
+
},
|
377
|
+
|
378
|
+
/**
|
379
|
+
* Will scale down to scale 1
|
380
|
+
*/
|
381
|
+
this.zoomMinimum = function() {
|
382
|
+
var x = 0,
|
383
|
+
y = 0,
|
384
|
+
minimumScale = 1;
|
385
|
+
|
386
|
+
this.updateImage(x, y, minimumScale);
|
387
|
+
},
|
388
|
+
|
389
|
+
/**
|
390
|
+
* Show the zoom image
|
391
|
+
*/
|
392
|
+
this.showImage = function() {
|
393
|
+
this.$dom.image.css('opacity', 1);
|
394
|
+
},
|
395
|
+
|
396
|
+
/**
|
397
|
+
* Hide the zoom image
|
398
|
+
*/
|
399
|
+
this.hideImage = function() {
|
400
|
+
this.$dom.image.css('opacity', 0);
|
401
|
+
},
|
402
|
+
|
403
|
+
/**
|
404
|
+
* Lazy load the image on demand.
|
405
|
+
*/
|
406
|
+
this.loadImage = function() {
|
407
|
+
if (this.flags.imageLoaded) {
|
408
|
+
return;
|
409
|
+
}
|
410
|
+
|
411
|
+
this.$dom.image.attr('src', this.getUrlImage());
|
412
|
+
},
|
413
|
+
|
414
|
+
/**
|
415
|
+
* Apply x, y, scale to the zoom image
|
416
|
+
* @param {Number} x Translate to x
|
417
|
+
* @param {Number} y Translate to y
|
418
|
+
* @param {scale} scale The scale to apply
|
419
|
+
*/
|
420
|
+
this.updateImage = function(x, y, scale) {
|
421
|
+
scale = scale || this.flags.currentScale;
|
422
|
+
|
423
|
+
// Let's be nice with the browser and give him
|
424
|
+
// rounded values.
|
425
|
+
x = Math.round(x);
|
426
|
+
y = Math.round(y);
|
427
|
+
|
428
|
+
this.$dom.image.css({
|
429
|
+
transform: this.getCssRuleTranslate(x, y) + ' ' + this.getCssRuleScale(scale)
|
430
|
+
});
|
431
|
+
|
432
|
+
// Keep track of transformations
|
433
|
+
this.flags.imageTranslate.y = y;
|
434
|
+
this.flags.imageTranslate.x = x;
|
435
|
+
this.flags.currentScale = scale;
|
436
|
+
}
|
437
|
+
|
438
|
+
/**
|
439
|
+
* Get the url of the zoom image to use.
|
440
|
+
* @return {String} Url (relative or absolute)
|
441
|
+
*/
|
442
|
+
this.getUrlImage = function() {
|
443
|
+
var url = this.options.url;
|
444
|
+
|
445
|
+
if (!_.isEmpty(url)) {
|
446
|
+
return url;
|
447
|
+
}
|
448
|
+
|
449
|
+
// Let's find by the attribute
|
450
|
+
return this.$dom.container.data('zoom-src');
|
451
|
+
},
|
452
|
+
|
453
|
+
/**
|
454
|
+
* When the zoom image is scaling up, we need to know
|
455
|
+
* the limit of scaling to keep the perfect quality ratio.
|
456
|
+
* @return {Float} The scale up limit
|
457
|
+
*/
|
458
|
+
this.getScaleLimitImage = function() {
|
459
|
+
var image = this.getNaturalDimensionsImage(),
|
460
|
+
scaleWidth,
|
461
|
+
scaleHeight,
|
462
|
+
limit;
|
463
|
+
|
464
|
+
scaleWidth = image.width / this.$dom.container.width();
|
465
|
+
scaleHeight = image.height / this.$dom.container.outerHeight();
|
466
|
+
|
467
|
+
limit = _.min([scaleWidth, scaleHeight]);
|
468
|
+
|
469
|
+
return _.round(limit, 2);
|
470
|
+
},
|
471
|
+
|
472
|
+
/**
|
473
|
+
* When the zoom image is panning (up / down / left / right),
|
474
|
+
* we need to know what are the limits for X and Y to avoid
|
475
|
+
* to pan outside of the container.
|
476
|
+
* @return {Object} The X / Y coordinates limits
|
477
|
+
*/
|
478
|
+
this.getPanLimits = function() {
|
479
|
+
var xLimit = (this.$dom.image.width() * this.flags.currentScale) - this.$dom.container.width(),
|
480
|
+
yLimit = (this.$dom.image.height() * this.flags.currentScale) - this.$dom.container.outerHeight();
|
481
|
+
|
482
|
+
return {
|
483
|
+
x: -xLimit,
|
484
|
+
y: -yLimit
|
485
|
+
}
|
486
|
+
},
|
487
|
+
|
488
|
+
/**
|
489
|
+
* Get the real width / height of the thumbnail
|
490
|
+
* @return {Object} The width / height
|
491
|
+
*/
|
492
|
+
this.getNaturalDimensionsThumbnail = function() {
|
493
|
+
return {
|
494
|
+
width: this.$dom.thumbnail.prop('naturalWidth'),
|
495
|
+
height: this.$dom.thumbnail.prop('naturalHeight')
|
496
|
+
}
|
497
|
+
},
|
498
|
+
|
499
|
+
/**
|
500
|
+
* Get the real width / height of the zoom image
|
501
|
+
* @return {Object} The width / height
|
502
|
+
*/
|
503
|
+
this.getNaturalDimensionsImage = function() {
|
504
|
+
return {
|
505
|
+
width: this.$dom.image.prop('naturalWidth'),
|
506
|
+
height: this.$dom.image.prop('naturalHeight')
|
507
|
+
}
|
508
|
+
},
|
509
|
+
|
510
|
+
/**
|
511
|
+
* Abstraction to clean up the code.
|
512
|
+
* @param {Mixed} x The X coordinates
|
513
|
+
* @param {Mixed} y The Y coordinates
|
514
|
+
* @return {String} The css translate rule for the transform property
|
515
|
+
*/
|
516
|
+
this.getCssRuleTranslate = function(x, y) {
|
517
|
+
return 'translate(' + x + 'px,' + y + 'px)';
|
518
|
+
},
|
519
|
+
|
520
|
+
/**
|
521
|
+
* Abstraction to clean up the code.
|
522
|
+
* @param {Mixed} scale The scale
|
523
|
+
* @return {String} The css scale rule for the transform property
|
524
|
+
*/
|
525
|
+
this.getCssRuleScale = function(scale) {
|
526
|
+
return 'scale(' + scale + ')';
|
527
|
+
},
|
528
|
+
|
529
|
+
/**
|
530
|
+
* Create an hammer instance for the
|
531
|
+
* element given with the right recognizers:
|
532
|
+
* Double Tap / Pinch / Pan
|
533
|
+
* @param {HTMLelement} element - Initialize the events to this element
|
534
|
+
*
|
535
|
+
* @example
|
536
|
+
* var element = document.getElementById('element');
|
537
|
+
* this.getInstanceHammer(element);
|
538
|
+
*/
|
539
|
+
this.getInstanceHammer = function(element) {
|
540
|
+
var manager = new Hammer.Manager(element),
|
541
|
+
doubleTap = new Hammer.Tap({event: 'doubletap', taps: 2}),
|
542
|
+
pinch = new Hammer.Pinch(),
|
543
|
+
pan = new Hammer.Pan({threshold: 0});
|
544
|
+
|
545
|
+
manager.add([doubleTap, pinch, pan]);
|
546
|
+
|
547
|
+
this.flags.hammer = manager;
|
548
|
+
|
549
|
+
return manager;
|
550
|
+
},
|
551
|
+
|
552
|
+
/**
|
553
|
+
* Destroy the widget
|
554
|
+
*/
|
555
|
+
this.onDestroy = function() {
|
556
|
+
|
557
|
+
// Shutdown events
|
558
|
+
this.$dom.image.off('load');
|
559
|
+
this.flags.hammer.off('doubletap pan pinchstart pinch');
|
560
|
+
this.$dom.container.off('zoom.destroy');
|
561
|
+
this.$dom.container.off('click');
|
562
|
+
|
563
|
+
// Remove added DOM
|
564
|
+
this.$dom.image.remove();
|
565
|
+
}
|
566
|
+
}
|
567
|
+
|
568
|
+
/**
|
569
|
+
* Public jQuery API
|
570
|
+
*/
|
571
|
+
|
572
|
+
$.fn.zoom = function(options) {
|
573
|
+
|
574
|
+
var options = options || {};
|
575
|
+
|
576
|
+
return this.each(function() {
|
577
|
+
new Zoom().init(this, options);
|
578
|
+
});
|
579
|
+
};
|
580
|
+
|
581
|
+
$.fn.zoom.defaults = {
|
582
|
+
|
583
|
+
/**
|
584
|
+
* Do you want to lazy load the zoom image?
|
585
|
+
* We will load the zoom image when the user clicks
|
586
|
+
* one time on the container.
|
587
|
+
* @type {Boolean}
|
588
|
+
*/
|
589
|
+
lazyLoad: true,
|
590
|
+
|
591
|
+
/**
|
592
|
+
* What is the increment scale you want to use
|
593
|
+
* when scale up / down.
|
594
|
+
*
|
595
|
+
* @example
|
596
|
+
* 1 -> 1.05 -> 1.10 -> ..
|
597
|
+
*
|
598
|
+
* @type {Number}
|
599
|
+
*/
|
600
|
+
deltaScale: 0.05,
|
601
|
+
|
602
|
+
/**
|
603
|
+
* The url of the zoom image, if not defined, the plugin
|
604
|
+
* will fetch the attribute "data-zoom-src" given.
|
605
|
+
* @type {Mixed}
|
606
|
+
*/
|
607
|
+
url: null
|
608
|
+
};
|
609
|
+
|
610
|
+
}(window.jQuery));
|