zoomimage.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. /**
  2. *
  3. * Zoomimage
  4. * Author: Stefan Petre www.eyecon.ro
  5. *
  6. */
  7. (function($){
  8. EYE.extend({
  9. zoomimage: {
  10. libs: {},
  11. types: /\.jpg|\.jpeg|\.png|\.gif|\.bmp/g,
  12. current: null,
  13. moved: false,
  14. pointer: {x:0,y:0},
  15. diff: {x:0, y:0},
  16. trackKey: false,
  17. //default options (many options are controled via CSS)
  18. defaults: {
  19. opacity: 0.3, //caption opacity
  20. border: 0, // border arround the image
  21. shadow: 6, // shadow size
  22. duration: 300, // animation duration
  23. prevent: 14, // pixels to move the mouse before the image is dragged
  24. controls: true, // display controls
  25. caption: true, // display caption
  26. hideSource: false,
  27. centered: false,
  28. className: false,
  29. onLoad: function(){return false},
  30. beforeZoomIn: function(){return false},
  31. onZoomIn: function(){return false},
  32. beforeZoomOut: function(){return false},
  33. onZoomOut: function(){return false},
  34. onFocus: function(){return false},
  35. controlsTrigger: 'focus',
  36. easing: 'linear',
  37. preload: 'click'
  38. },
  39. // the template for the image's box
  40. template: [
  41. '<div class="zoomimage">',
  42. '<div class="zoomimage_s">',
  43. '<div class="zoomimage_st">',
  44. '<div class="zoomimage_stl"></div>',
  45. '<div class="zoomimage_stc"></div>',
  46. '<div class="zoomimage_str"></div>',
  47. '</div>',
  48. '<div class="zoomimage_sc">',
  49. '<div class="zoomimage_scl"></div>',
  50. '<div class="zoomimage_scc"></div>',
  51. '<div class="zoomimage_scr"></div>',
  52. '</div>',
  53. '<div class="zoomimage_sb">',
  54. '<div class="zoomimage_sbl"></div>',
  55. '<div class="zoomimage_sbc"></div>',
  56. '<div class="zoomimage_sbr"></div>',
  57. '</div>',
  58. '</div>',
  59. '<img src="" />',
  60. '<div class="zoomimage_controls">',
  61. '<a href="#" class="zoomimage_prev"></a>',
  62. '<a href="#" class="zoomimage_next"></a>',
  63. '</div>',
  64. '<div class="zoomimage_caption"></div>',
  65. '<div class="zoomimage_loading"></div>',
  66. '</div>'
  67. ],
  68. // handle click on the trigger
  69. click: function(e) {
  70. var el = this;
  71. el.blur();
  72. // if the image was not preloaded yet then wait
  73. if (el.zoomimageCfg.loading === true) {
  74. return false;
  75. }
  76. //zoom it in if not zoomed already
  77. if (el.zoomimageCfg.zoomed == false) {
  78. EYE.zoomimage.zoomIn(el);
  79. //else zoom it out
  80. } else {
  81. EYE.zoomimage.zoomOut(el, false);
  82. }
  83. return false;
  84. },
  85. // zoom in the image
  86. zoomIn: function(el) {
  87. //if the image was not loaded yet then wait
  88. if (el.zoomimageCfg.loaded === false) {
  89. //if the image is not preloading then start preloading
  90. if (el.zoomimageCfg.loading != true) {
  91. el.zoomimageCfg.loading = true;
  92. EYE.zoomimage.preload(el);
  93. }
  94. return;
  95. }
  96. //if the image is zoomed in then just focus it
  97. if (el.zoomimageCfg.zoomed == true) {
  98. EYE.zoomimage.focus(el);
  99. return;
  100. }
  101. el.zoomimageCfg.beforeZoomIn.apply(el,[el.zoomimageCfg.box]);
  102. var elPos = EYE.getPosition(el, true);
  103. var elHeight = el.offsetHeight;
  104. var elWidth = el.offsetWidth;
  105. var pos = EYE.getScroll();
  106. var borderAndShadow = el.zoomimageCfg.border + el.zoomimageCfg.shadow;
  107. var width = el.zoomimageCfg.width + borderAndShadow * 2;
  108. var height = el.zoomimageCfg.height + borderAndShadow * 2;
  109. var screenRatio = pos.iw/pos.ih;
  110. var imageRatio = el.zoomimageCfg.width/el.zoomimageCfg.height;
  111. // if the image is bigger then the viewport then resize the image to fit
  112. if (screenRatio > imageRatio) {
  113. if (height > pos.ih) {
  114. height = pos.ih;
  115. width = parseInt(height * imageRatio,10);
  116. }
  117. } else if (width > pos.iw) {
  118. width = pos.iw;
  119. height = parseInt(width / imageRatio, 10);
  120. }
  121. //if the image should be centered then do that, else center to trigger's position but do not leave the viewport
  122. var top = el.zoomimageCfg.centered ?
  123. pos.t + parseInt((pos.ih - height)/2, 10)
  124. :
  125. Math.min(
  126. Math.max(
  127. pos.t,
  128. elPos.y + (elHeight - height)/2 - borderAndShadow
  129. ),
  130. pos.t + pos.ih - height
  131. );
  132. var left = el.zoomimageCfg.centered ?
  133. pos.l + parseInt((pos.iw - width)/2, 10)
  134. :
  135. Math.min(
  136. Math.max(
  137. pos.l,
  138. elPos.x + (elWidth - width)/2 - borderAndShadow
  139. ),
  140. pos.l + pos.iw - width
  141. );
  142. var imgWidth = width - borderAndShadow * 2;
  143. var imgHeight = height - borderAndShadow * 2;
  144. if(el.zoomimageCfg.hideSource === true) {
  145. el.style.visibility = 'hidden';
  146. }
  147. //move the image's box and animated it
  148. $('#' + el.zoomimageCfg.box)
  149. .css({
  150. top: elPos.y + 'px',
  151. left: elPos.x + 'px',
  152. width: elWidth + 'px',
  153. height: elHeight + 'px'
  154. })
  155. .find('>div')
  156. .hide()
  157. .end()
  158. .find('img')
  159. .attr('src', el.zoomimageCfg.src)
  160. .css({
  161. top: 0,
  162. left: 0,
  163. width: '100%',
  164. height: '100%',
  165. display: 'block',
  166. borderWidth: '0px'
  167. })
  168. .end()
  169. .animate({
  170. width: imgWidth,
  171. height: imgHeight,
  172. top: top + borderAndShadow,
  173. left: left + borderAndShadow
  174. },
  175. el.zoomimageCfg.duration,
  176. el.zoomimageCfg.easing,
  177. function(){
  178. $(this)
  179. .css({
  180. top: top + 'px',
  181. left: left + 'px',
  182. width: width + 'px',
  183. height: height + 'px'
  184. })
  185. .find('img')
  186. .css({
  187. top: el.zoomimageCfg.shadow + 'px',
  188. left: el.zoomimageCfg.shadow + 'px',
  189. width: imgWidth + 'px',
  190. height: imgHeight + 'px',
  191. borderWidth: el.zoomimageCfg.border + 'px'
  192. })
  193. .end()
  194. .find('>div:first')
  195. .find('div.zoomimage_sc')
  196. .css('height', height - el.zoomimageCfg.shadow*2 + 'px')
  197. .end()
  198. .show();
  199. el.zoomimageCfg.zoomed = true;
  200. EYE.zoomimage.focus(el);
  201. el.zoomimageCfg.onZoomIn.apply(el,[el.zoomimageCfg.box]);
  202. });
  203. },
  204. //focus image and show gallery controls if it is part of a gallery
  205. showControls: function(el) {
  206. if(el == undefined)
  207. return;
  208. if (el.zoomimageCfg == undefined) {
  209. el = $('#' + $(el).attr('zoomimage')).get(0);
  210. }
  211. var height,
  212. imgWidth,
  213. borderAndShadow = el.zoomimageCfg.border + el.zoomimageCfg.shadow;
  214. $('#' + el.zoomimageCfg.box)
  215. .find('img')
  216. .each(function(){
  217. imgWidth = parseInt($.curCSS(this, 'width'),10);
  218. })
  219. .end()
  220. .get(0).zoomimageControls = true;
  221. // if it has caption then display it
  222. if(el.zoomimageCfg.caption) {
  223. $('#' + el.zoomimageCfg.box)
  224. .find('>div:eq(2)')
  225. .stop()
  226. .css({
  227. bottom: borderAndShadow + 'px',
  228. left: borderAndShadow + 'px',
  229. width: imgWidth + 'px'
  230. })
  231. .show()
  232. .each(function() {
  233. this.style.height = 'auto';
  234. height = this.offsetHeight;
  235. this.style.height = '0';
  236. })
  237. .animate({height: height}, el.zoomimageCfg.duration);
  238. }
  239. //if it has controls then show them
  240. if(el.zoomimageCfg.controls) {
  241. // show controls only if it is part of a gallery
  242. if (EYE.zoomimage.libs[el.zoomimageCfg.lib] > 1) {
  243. $('#' + el.zoomimageCfg.box)
  244. .find('>div:eq(1)')
  245. .show()
  246. .each(function(){
  247. if (!el.zoomimageCfg.controlsHeight) {
  248. el.zoomimageCfg.controlsHeight = this.offsetHeight;
  249. }
  250. this.style.height = '0';
  251. })
  252. .css({
  253. top: borderAndShadow + 'px',
  254. left: borderAndShadow + 'px',
  255. width: imgWidth + 'px'
  256. })
  257. .animate({height: el.zoomimageCfg.controlsHeight}, el.zoomimageCfg.duration);
  258. }
  259. }
  260. },
  261. //zoom out the image and go to the next/previous if any
  262. zoomOut: function(el, goToNext) {
  263. var boxEl, elPos, borderAndShadow, elSize;
  264. // if the action was started by the trigger
  265. if (el.zoomimageCfg) {
  266. if (el.zoomimageCfg.zoomed === false) {
  267. return;
  268. }
  269. el.zoomimageCfg.beforeZoomOut.apply(el,[el.zoomimageCfg.box]);
  270. boxEl = document.getElementById(el.zoomimageCfg.box);
  271. // else try to find a link that has the same href as the image src
  272. } else {
  273. boxEl = el;
  274. el = $('a[href=' + $('img',boxEl).attr('src') + ']').get(0);
  275. }
  276. // the trigger was found so scale to image to trigger's size
  277. if (el) {
  278. elPos = EYE.getPosition(el, true);
  279. el.zoomimageCfg.zoomed = false;
  280. borderAndShadow = el.zoomimageCfg.border + el.zoomimageCfg.shadow;
  281. elSize = {
  282. width: el.offsetWidth,
  283. height: el.offsetHeight
  284. };
  285. // the trigger was not found so scale the image to its center
  286. } else {
  287. borderAndShadow = EYE.zoomimage.defaults.border + EYE.zoomimage.defaults.shadow;
  288. elSize = {
  289. width: 0,
  290. height: 0
  291. };
  292. elPos = EYE.getPosition(boxEl, true);
  293. elPos.y += parseInt(boxEl.offsetHeight/2, 10);
  294. elPos.x += parseInt(boxEl.offsetWidth/2, 10);
  295. }
  296. $(boxEl)
  297. .css({
  298. top: boxEl.offsetTop + borderAndShadow + 'px',
  299. left: boxEl.offsetLeft + borderAndShadow + 'px',
  300. width: boxEl.offsetWidth - borderAndShadow*2 + 'px',
  301. height: boxEl.offsetHeight - borderAndShadow*2 + 'px'
  302. })
  303. .find('>div')
  304. .stop()
  305. .hide()
  306. .end()
  307. .find('img')
  308. .css({
  309. top: 0,
  310. left: 0,
  311. width: '100%',
  312. height: '100%',
  313. borderWidth: '0px'
  314. })
  315. .end()
  316. .animate(
  317. {
  318. top: elPos.y + 'px',
  319. left: elPos.x + 'px',
  320. width: elSize.width + 'px',
  321. height: elSize.height + 'px'
  322. },
  323. // if the trigger was not found the use the default duration
  324. el ? el.zoomimageCfg.duration : EYE.zoomimage.defaults.duration,
  325. el.zoomimageCfg.easing,
  326. function() {
  327. //hide image and remove focus
  328. EYE.zoomimage.blur();
  329. $(this).hide();
  330. // if the trigger was found then aply callback and try to focus the next one zoomed
  331. if (el) {
  332. if(el.zoomimageCfg.hideSource === true) {
  333. el.style.visibility = 'visible';
  334. }
  335. el.zoomimageCfg.onZoomOut.apply(el,[el.zoomimageCfg.box]);
  336. if (!goToNext) {
  337. EYE.zoomimage.focus($('div.zoomimage:visible:last').not(':animated').get(0));
  338. }
  339. //the trigger was not found so remove the image since no trigger is present in the page
  340. } else {
  341. $(boxEl).stop().remove();
  342. }
  343. }
  344. );
  345. },
  346. mouseOver: function(e) {
  347. var triggerEl = document.getElementById($(this).attr('zoomimage'));
  348. if (triggerEl.zoomimageCfg.zoomed === true && this.zoomimageControls == false) {
  349. EYE.zoomimage.showControls(triggerEl);
  350. }
  351. return false;
  352. },
  353. mouseOut: function(e) {
  354. if ( !EYE.isChildOf(this, e.relatedTarget, this) ) {
  355. $(this)
  356. .find('>div:not(:first)')
  357. .stop()
  358. .hide();
  359. this.zoomimageControls = false;
  360. }
  361. return false;
  362. },
  363. // prepare for possible drag
  364. mouseDown: function(e) {
  365. // find the trigger
  366. var triggerEl = document.getElementById($(this).attr('zoomimage'));
  367. //if the trigger was found then prepare informations for drag
  368. if (triggerEl) {
  369. $.extend(EYE.zoomimage,{
  370. current: this,
  371. prevent: triggerEl.zoomimageCfg.prevent,
  372. moved: false,
  373. diff: {
  374. x: e.pageX - this.offsetLeft,
  375. y: e.pageY - this.offsetTop
  376. },
  377. pointer: {
  378. x: e.pageX ,
  379. y: e.pageY
  380. }
  381. });
  382. $(document)
  383. .bind('mousemove', EYE.zoomimage.mouseMove)
  384. .bind('mouseup', EYE.zoomimage.mouseUp);
  385. // if the trigger was not found then it is an orphan and zoom it out
  386. } else {
  387. $(this).zoomimageClear();
  388. }
  389. return false;
  390. },
  391. //do the drag if prevent distance was overtake
  392. mouseMove: function(e) {
  393. var diffX = Math.abs(EYE.zoomimage.pointer.x - e.pageX);
  394. var diffY = Math.abs(EYE.zoomimage.pointer.y - e.pageY);
  395. //the prevent distance was not reached yet so we check if it is reached already
  396. if (EYE.zoomimage.moved === false) {
  397. if ( diffX > EYE.zoomimage.prevent|| diffY > EYE.zoomimage.prevent) {
  398. EYE.zoomimage.moved = true;
  399. $(EYE.zoomimage.current).addClass('zoomimage_move');
  400. if (!$(EYE.zoomimage.current).is('.zoomimage_focused')) {
  401. EYE.zoomimage.focus(EYE.zoomimage.current);
  402. }
  403. }
  404. // the prevent distance was overtake so the element can be moved
  405. } else {
  406. EYE.zoomimage.current.style.top = e.pageY - EYE.zoomimage.diff.y + 'px';
  407. EYE.zoomimage.current.style.left = e.pageX - EYE.zoomimage.diff.x + 'px';
  408. }
  409. return false;
  410. },
  411. //the drag stops
  412. mouseUp: function (e) {
  413. $(EYE.zoomimage.current).removeClass('zoomimage_move');
  414. EYE.zoomimage.current = null;
  415. $(document)
  416. .unbind('mousemove', EYE.zoomimage.mouseMove)
  417. .unbind('mouseup', EYE.zoomimage.mouseUp);
  418. return false;
  419. },
  420. // click on image
  421. imageClick: function(e) {
  422. $(document)
  423. .unbind('mousemove', EYE.zoomimage.mouseMove)
  424. .unbind('mouseup', EYE.zoomimage.mouseUp);
  425. var el = document.getElementById($(this).attr('zoomimage'));
  426. // if the trigger was found
  427. if (el) {
  428. //if the image was not moved but was focused
  429. if (EYE.zoomimage.moved === false && $(this).is('.zoomimage_focused')) {
  430. // if the event target is a link then it was a click on one of the controls and go to the next image
  431. if ($(e.target).is('a')) {
  432. EYE.zoomimage.zoomNext(el, e.target.className == 'zoomimage_next' ? 1 : -1);
  433. var goToNext = true;
  434. // else just zoom it out
  435. } else {
  436. EYE.zoomimage.zoomOut(el, goToNext||false);
  437. }
  438. // just focus the image
  439. } else if(!$(this).is('.zoomimage_focused')) {
  440. EYE.zoomimage.focus(this);
  441. }
  442. //the trigger was not found so the image is orphan and zoom it out
  443. } else {
  444. $(this).zoomimageClear();
  445. }
  446. return false;
  447. },
  448. //zoom out any opened image and clear orphan images
  449. clear: function() {
  450. var subject = this;
  451. if (subject.size() == 0) {
  452. subject = $('div.zoomimage');
  453. }
  454. return subject.each(function(){
  455. var triggerEl = document.getElementById($(this).attr('zoomimage'));
  456. if (triggerEl) {
  457. EYE.zoomimage.zoomOut(triggerEl, false);
  458. } else {
  459. EYE.zoomimage.zoomOut(this, false);
  460. }
  461. });
  462. },
  463. // zoom the next image in gallery
  464. zoomNext: function(el, dir) {
  465. if(el.zoomimageCfg.zoomed === false) {
  466. return;
  467. }
  468. EYE.zoomimage.zoomOut(el, true);
  469. var nextImg = el.zoomimageCfg.iteration + dir;
  470. var lib = $(el).attr('zoomimage');
  471. var maxImg = EYE.zoomimage.libs[lib];
  472. if (nextImg < 0) {
  473. nextImg = maxImg - 1;
  474. } else if (nextImg >= maxImg) {
  475. nextImg = 0;
  476. }
  477. EYE.zoomimage.zoomIn($('a[zoomimage="' + lib + '"]').get(nextImg));
  478. },
  479. //hande any key pressed
  480. keyPressed: function(e) {
  481. var el = $('div.zoomimage_focused');
  482. if (el.size() == 1) {
  483. var pressedKey = e.charCode || e.keyCode || -1;
  484. el = $('#' + $(el).attr('zoomimage')).get(0);
  485. var lib = $(el).attr('zoomimage');
  486. switch (pressedKey)
  487. {
  488. //end
  489. case 35:
  490. // go to the last image in the gallery
  491. if (EYE.zoomimage.libs[lib] > 1 && EYE.zoomimage.libs[lib] - 1 != el.zoomimageCfg.iteration) {
  492. EYE.zoomimage.zoomNext(el, EYE.zoomimage.libs[lib] - el.zoomimageCfg.iteration - 1);
  493. return false;
  494. }
  495. break;
  496. //home
  497. case 36:
  498. // go to the first image in the gallery
  499. if (EYE.zoomimage.libs[lib] > 1 && el.zoomimageCfg.iteration != 0) {
  500. EYE.zoomimage.zoomNext(el, - el.zoomimageCfg.iteration);
  501. return false;
  502. }
  503. break;
  504. //down;
  505. case 40:
  506. //left
  507. case 37:
  508. //backspace
  509. case 8:
  510. //page up
  511. case 33:
  512. //p
  513. case 80:
  514. case 112:
  515. // go to the previous image in the gallery
  516. if (EYE.zoomimage.libs[lib] > 1) {
  517. EYE.zoomimage.zoomNext(el, -1);
  518. return false;
  519. }
  520. break;
  521. //up
  522. case 38:
  523. //right
  524. case 39:
  525. //page down
  526. case 34:
  527. //space
  528. case 32:
  529. //n
  530. case 110:
  531. case 78:
  532. // go to the next image in the gallery
  533. if (EYE.zoomimage.libs[lib] > 1) {
  534. EYE.zoomimage.zoomNext(el, 1);
  535. return false;
  536. }
  537. break;
  538. //escape
  539. case 27:
  540. // well zoome out the curent image
  541. EYE.zoomimage.zoomOut(el, false);
  542. return false;
  543. break;
  544. }
  545. }
  546. },
  547. // focus on image
  548. focus: function(el) {
  549. if(el == undefined)
  550. return;
  551. if (el.zoomimageCfg == undefined) {
  552. el = $('#' + $(el).attr('zoomimage')).get(0);
  553. } else {
  554. var showControls = true;
  555. }
  556. // if another image is focused then remove focus
  557. EYE.zoomimage.blur(el);
  558. $('#' + el.zoomimageCfg.box)
  559. .not('.zoomimage_focused')
  560. .addClass('zoomimage_focused');
  561. el.zoomimageCfg.onFocus.apply(el,[el.zoomimageCfg.box]);
  562. if (el.zoomimageCfg.controlsTrigger == 'focus' || showControls) {
  563. EYE.zoomimage.showControls(el);
  564. }
  565. },
  566. //blur image
  567. blur: function(el) {
  568. $('div.zoomimage_focused')
  569. .not('#' + (el == undefined ? 'fakezoomimage' : el.zoomimageCfg.box))
  570. .removeClass('zoomimage_focused')
  571. .each(function(){
  572. this.zoomimageControls = false;
  573. })
  574. .find('>div:not(:first)')
  575. .stop()
  576. .hide();
  577. },
  578. preload: function(el) {
  579. // place the loading aimation on top
  580. var boxEl = $('#' + el.zoomimageCfg.box).show();
  581. boxEl.find('>div, img').hide();
  582. var elPos = EYE.getPosition(el, true);
  583. boxEl
  584. .find('>div:last')
  585. .show()
  586. .end()
  587. .css({
  588. top: elPos.y + 'px',
  589. left: elPos.x + 'px',
  590. width: el.offsetWidth + 'px',
  591. height: el.offsetHeight + 'px'
  592. });
  593. // preload the image
  594. var preld= new Image();
  595. preld.src = el.href;
  596. //if the image was laoded already
  597. if (preld.complete) {
  598. EYE.zoomimage.markPreloaded(preld, el);
  599. // else place a callback
  600. } else {
  601. preld.onload = function() {
  602. EYE.zoomimage.markPreloaded(preld, el);
  603. };
  604. }
  605. },
  606. markPreloaded: function(preld, el) {
  607. //mark image as loaded and remember the size and source
  608. $.extend(el.zoomimageCfg,{
  609. loaded: true,
  610. width: preld.width,
  611. height: preld.height,
  612. src: preld.src
  613. });
  614. // hide loading animation
  615. $('#' + el.zoomimageCfg.box)
  616. .find('div.zoomimage_loading')
  617. .hide();
  618. //if the image waits to be enlarged then zoom in
  619. if (el.zoomimageCfg.loading) {
  620. el.zoomimageCfg.loading = false;
  621. EYE.zoomimage.zoomIn(el);
  622. }
  623. el.zoomimageCfg.onLoad.apply(el,[el.zoomimageCfg.box]);
  624. },
  625. //constructor
  626. init: function(opt) {
  627. //generate a library key
  628. var libKey = parseInt(Math.random()*2000,10);
  629. //store the number of images in the library
  630. EYE.zoomimage.libs[libKey] = 0;
  631. opt = $.extend({lib:libKey}, EYE.zoomimage.defaults, opt||{});
  632. return this.each(function(){
  633. var jQEl = $(this);
  634. var el = this;
  635. //consider only the links pointing to an image
  636. if (el.href && el.href.toLowerCase().match(EYE.zoomimage.types) != null) {
  637. //store library options
  638. el.zoomimageCfg = $.extend({}, opt, {
  639. zoomed: false,
  640. loading: false,
  641. loaded: false,
  642. animated: false,
  643. src: el.href,
  644. iteration: EYE.zoomimage.libs[libKey],
  645. box: 'zoomimage_' + parseInt(Math.random() * 2000, 10) + ''
  646. });
  647. //increment the number of images in the library
  648. EYE.zoomimage.libs[libKey]++;
  649. jQEl
  650. .bind('click', EYE.zoomimage.click)
  651. .attr('zoomimage', libKey)
  652. .attr('zoomimageBox', el.zoomimageCfg.box);
  653. var currId = jQEl.attr('id');
  654. if (!currId) {
  655. currId = el.zoomimageCfg.box + '_trigger';
  656. jQEl.attr('id', currId);
  657. }
  658. var titleAttr = $(el).attr('title');
  659. if (titleAttr == '' || titleAttr == false) {
  660. el.zoomimageCfg.caption = false;
  661. }
  662. // generate the HTML for the image's box
  663. $(EYE.zoomimage.template.join(''))
  664. .attr('id', el.zoomimageCfg.box)
  665. .attr('zoomimage', currId)
  666. .addClass(el.zoomimageCfg.className)
  667. .appendTo(document.body)
  668. .bind('mousedown', EYE.zoomimage.mouseDown)
  669. .bind('click', EYE.zoomimage.imageClick)
  670. .each(function(){
  671. this.zoomimageControls = false;
  672. if (el.zoomimageCfg.controlsTrigger != 'focus') {
  673. $(this)
  674. .bind('mouseover', EYE.zoomimage.mouseOver)
  675. .bind('mouseout', EYE.zoomimage.mouseOut);
  676. }
  677. })
  678. .find('>div')
  679. .not(':first')
  680. .css('opacity', el.zoomimageCfg.opacity)
  681. .end()
  682. .filter('div:eq(2)')
  683. .html('<p>' + titleAttr + '</p>');
  684. if (el.zoomimageCfg.preload == 'load') {
  685. EYE.zoomimage.preload(el);
  686. }
  687. if (EYE.zoomimage.trackKey === false) {
  688. EYE.zoomimage.trackKey = true;
  689. $(document).bind('keydown', EYE.zoomimage.keyPressed);
  690. }
  691. }
  692. });
  693. }
  694. }
  695. });
  696. $.fn.extend({
  697. /**
  698. * Open all images found in 'href' attribute from each element specified in the selection. The images are grouped in galleries. The images are preloaded before any user interation.
  699. * @name zoomimage
  700. * @description Open all images found in 'href' attribute from each element specified in the selection. The images are grouped in galleries
  701. * @param Hash options A hash of parameters. All parameters are optional.
  702. * @option float opacity The opacity for the caption and controls. Default: 0.3
  703. * @option int border Image's border. Default: 0
  704. * @option int duration Animation duration. Default 300
  705. * @option int prevent Pixes to move the mouse before the images is dragged (prevents accidental dragging). Default: 14
  706. * @option boolean controls Whatever if the controls are displayed (if the image is not part of an libriry then the controls are not displayed)
  707. * @option boolean caption Whatever if the caption is displayed (the caption text is the text from 'title' atribute. Default: true
  708. * @option boolean centered Whatever if the image should be centered in the viewport or to the trigger. Default: false
  709. * @option string easing Animation easing. Default: linear
  710. * @option boolean hideSource Whatever to hide source when the image is opened. Default: false
  711. * @option string className CSS class to add to image's box. Default: false
  712. * @option string controlsTrigger 'focus' to show caption and controls when the box is focused or 'mouseover' to show controls and caption on mouse over. Default: 'focus'
  713. * @option string preload 'click' to preload the image when the trigger is clicked or 'load' to preload the image on document load. Default: 'click'
  714. * @option function onLoad Callback function triggered when the image was loaded
  715. * @option function beforeZoomIn Callback function triggered before the image is zoomed in
  716. * @option function onZoomIn Callback function triggered when the image is zooms in
  717. * @option function beforeZoomOut Callback function triggered before the image is zoomed out
  718. * @option function onZoomOut Callback function triggered when the image is zooms out
  719. * @option function onFocus Callback function triggered when the image is focused
  720. */
  721. zoomimage: EYE.zoomimage.init,
  722. /**
  723. * Zooms out all opened images and removes orphans (when the trigger was not found)
  724. * To clear specific images use for slector 'div.zooimage[whatever]', else all the images are processed
  725. */
  726. zoomimageClear: EYE.zoomimage.clear
  727. });
  728. })(jQuery);