1; (function($, window, document, undefined) { 2 var calls = 0; 3 var defaults = { 4 container : window, // window or jquery object or jquery selector, or element 5 imageSelector : '.chocolat-image', 6 className : '', 7 imageSize : 'default', // 'default', 'contain', 'cover' or 'native' 8 initialZoomState : null, 9 fullScreen : false, 10 loop : false, 11 linkImages : true, 12 duration : 300, 13 setTitle : '', 14 separator2 : '/', 15 setIndex : 0, 16 firstImage : 0, 17 lastImage : false, 18 currentImage : false, 19 initialized : false, 20 timer : false, 21 timerDebounce : false, 22 images : [], 23 }; 24 25 function Chocolat(element, settings) { 26 var that = this; 27 28 this.settings = settings; 29 this._defaults = defaults; 30 this.elems = {}; 31 this.element = element; 32
33 this._cssClasses = [ 34 'chocolat-open', 35 'chocolat-mobile', 36 'chocolat-in-container', 37 'chocolat-cover', 38 'chocolat-zoomable', 39 'chocolat-zoomed' 40 ]; 41 42 if (!this.settings.setTitle && element.data('chocolat-title')) { 43 this.settings.setTitle = element.data('chocolat-title'); 44 } 45 46 47 this.element.find(this.settings.imageSelector).each(function () { 48 that.settings.images.push({ 49 title : $(this).attr('title'), 50 src : $(this).attr('href'), 51 height : false, 52 width : false 53 }); 54 }); 55 56 this.element.find(this.settings.imageSelector).each(function (i) { 57 $(this).off('click.chocolat').on('click.chocolat', function(e){ 58 that.init(i); 59 e.preventDefault(); 60 }); 61 }); 62 63 return this; 64 } 65 $.extend(Chocolat.prototype, { 66 67 init : function(i) { 68 if (!this.settings.initialized) { 69 this.setDomContainer(); 70 this.markup(); 71 this.events(); 72 this.settings.lastImage = this.settings.images.length - 1; 73 this.settings.initialized = true; 74 } 75 76 return this.load(i); 77 }, 78 79 preload : function(i) { 80 var def = $.Deferred(); 81 82 if (typeof this.settings.images[i] === 'undefined') { 83 return; 84 } 85 var imgLoader = new Image(); 86 imgLoader.onload = function() { def.resolve(imgLoader); }; 87 imgLoader.src = this.settings.images[i].src; 88 89 return def; 90 }, 91 92 load : function(i) { 93 var that = this; 94 if (this.settings.fullScreen) { 95 this.openFullScreen(); 96 } 97 98 if (this.settings.currentImage === i) { 99 return; 100 } 101 102 this.elems.overlay.fadeIn(800); 103 this.settings.timer = setTimeout(function(){ 104 if (typeof that.elems != 'undefined') { 105 $.proxy(that.elems.loader.fadeIn(), that); 106 } 107 }, 800); 108 109 var deferred = this.preload(i) 110 .then(function (imgLoader) { 111 return that.place(i, imgLoader); 112 }) 113 .then(function (imgLoader) { 114 return that.appear(i); 115 }) 116 .then(function (imgLoader) { 117 that.zoomable(); 118 }); 119 120 var nextIndex = i + 1; 121 if (typeof this.settings.images[nextIndex] != 'undefined') { 122 this.preload(nextIndex); 123 } 124 125 return deferred; 126 127 }, 128 129 place : function(i, imgLoader) { 130 var that = this; 131 var fitting; 132 133 this.settings.currentImage = i; 134 this.description(); 135 this.pagination(); 136 this.arrows(); 137 138 this.storeImgSize(imgLoader, i); 139 fitting = this.fit(i, that.settings.container); 140 141 return this.center( 142 fitting.width, 143 fitting.height, 144 fitting.left, 145 fitting.top, 146 0 147 ); 148 }, 149 150 center : function(width, height, left, top, duration) { 151 152 return this.elems.content 153 .css('overflow', 'visible') 154 .animate({ 155 'width' :width, 156 'height' :height, 157 'left' :left, 158 'top' :top 159 }, duration) 160 .promise(); 161 }, 162 163 appear : function(i) { 164 var that = this; 165 clearTimeout(this.settings.timer); 166 167 this.elems.loader.stop().fadeOut(300, function() { 168 that.elems.img 169 .attr('src', that.settings.images[i].src); 170 }); 171 }, 172 173 fit : function(i, container) { 174 var height; 175 var width; 176 177 var imgHeight = this.settings.images[i].height; 178 var imgWidth = this.settings.images[i].width; 179 var holderHeight = $(container).height(); 180 var holderWidth = $(container).width(); 181 var holderOutMarginH = this.getOutMarginH(); 182 var holderOutMarginW = this.getOutMarginW(); 183 184 var holderGlobalWidth = holderWidth-holderOutMarginW; 185 var holderGlobalHeight = holderHeight-holderOutMarginH; 186 var holderGlobalRatio = (holderGlobalHeight / holderGlobalWidth);
187 var holderRatio = (holderHeight / holderWidth); 188 var imgRatio = (imgHeight / imgWidth); 189 190 if (this.settings.imageSize == 'cover') { 191 if (imgRatio < holderRatio) { 192 height = holderHeight; 193 width = height / imgRatio; 194 } 195 else { 196 width = holderWidth; 197 height = width * imgRatio; 198 } 199 } 200 else if (this.settings.imageSize == 'native') { 201 height = imgHeight; 202 width = imgWidth; 203 } 204 else { 205 if (imgRatio > holderGlobalRatio) { 206 height = holderGlobalHeight; 207 width = height / imgRatio; 208 } 209 else { 210 width = holderGlobalWidth; 211 height = width * imgRatio; 212 } 213 if (this.settings.imageSize === 'default' && (width >= imgWidth || height >= imgHeight)) { 214 width = imgWidth; 215 height = imgHeight; 216 } 217 } 218 219 return { 220 'height' : height, 221 'width' : width, 222 'top' : (holderHeight - height)/2, 223 'left' : (holderWidth - width)/2 224 }; 225 }, 226 227 change : function(signe) { 228 this.zoomOut(0); 229 this.zoomable(); 230 231 var requestedImage = this.settings.currentImage + parseInt(signe); 232 if (requestedImage > this.settings.lastImage) { 233 if (this.settings.loop) { 234 return this.load(0); 235 } 236 } 237 else if (requestedImage < 0) { 238 if (this.settings.loop) { 239 return this.load(this.settings.lastImage); 240 } 241 } 242 else { 243 return this.load(requestedImage); 244 } 245 }, 246 247 arrows: function() { 248 if (this.settings.loop) { 249 $([this.elems.left[0],this.elems.right[0]]) 250 .addClass('active'); 251 } 252 else if (this.settings.linkImages) { 253 // right 254 if (this.settings.currentImage == this.settings.lastImage) { 255 this.elems.right.removeClass('active'); 256 } 257 else { 258 this.elems.right.addClass('active'); 259 } 260 // left 261 if (this.settings.currentImage === 0) { 262 this.elems.left.removeClass('active'); 263 } 264 else { 265 this.elems.left.addClass('active'); 266 } 267 } 268 else { 269 $([this.elems.left[0],this.elems.right[0]]) 270 .removeClass('active'); 271 } 272 }, 273 274 description : function() { 275 var that = this; 276 this.elems.description 277 .html(that.settings.images[that.settings.currentImage].title); 278 }, 279 280 pagination : function() { 281 var that = this; 282 var last = this.settings.lastImage + 1; 283 var position = this.settings.currentImage + 1; 284 285 this.elems.pagination 286 .html(position + ' ' + that.settings.separator2 + last); 287 }, 288 289 storeImgSize : function(img, i) { 290 if (typeof img === 'undefined') { 291 return; 292 } 293 if (!this.settings.images[i].height || !this.settings.images[i].width) { 294 this.settings.images[i].height = img.height; 295 this.settings.images[i].width = img.width; 296 } 297 }, 298 299 close : function() { 300 301 if (this.settings.fullscreenOpen) { 302 this.exitFullScreen(); 303 return; 304 } 305 306 var els = [ 307 this.elems.overlay[0], 308 this.elems.loader[0], 309 this.elems.wrapper[0] 310 ]; 311 var that = this; 312 var def = $.when($(els).fadeOut(200)).done(function () { 313 that.elems.domContainer.removeClass(that._cssClasse
313s.join(' ')); 314 }); 315 this.settings.currentImage = false; 316 this.settings.initialized = false; 317 318 return def; 319 }, 320 321 destroy : function() { 322 this.element.removeData(); 323 this.element.find(this.settings.imageSelector).off('click.chocolat'); 324 325 if (!this.settings.initialized) { 326 return; 327 } 328 if (this.settings.fullscreenOpen) { 329 this.exitFullScreen(); 330 } 331 this.settings.currentImage = false; 332 this.settings.initialized = false; 333 this.elems.domContainer.removeClass(this._cssClasses.join(' ')); 334 this.elems.wrapper.remove(); 335 }, 336 337 getOutMarginW : function() { 338 var left = this.elems.left.outerWidth(true); 339 var right = this.elems.right.outerWidth(true); 340 return left + right; 341 }, 342 343 getOutMarginH : function() { 344 return this.elems.top.outerHeight(true) + this.elems.bottom.outerHeight(true); 345 }, 346 347 markup : function() { 348 this.elems.domContainer.addClass('chocolat-open ' + this.settings.className); 349 if (this.settings.imageSize == 'cover') { 350 this.elems.domContainer.addClass('chocolat-cover'); 351 } 352 if (this.settings.container !== window) { 353 this.elems.domContainer.addClass('chocolat-in-container'); 354 } 355 356 this.elems.wrapper = $('<div/>', { 357 'class' : 'chocolat-wrapper', 358 'id' : 'chocolat-content-' + this.settings.setIndex 359 }).appendTo(this.elems.domContainer); 360 361 this.elems.overlay = $('<div/>', { 362 'class' : 'chocolat-overlay' 363 }).appendTo(this.elems.wrapper); 364 365 this.elems.loader = $('<div/>', { 366 'class' : 'chocolat-loader' 367 }).appendTo(this.elems.wrapper); 368 369 this.elems.content = $('<div/>', { 370 'class' : 'chocolat-content', 371 }).appendTo(this.elems.wrapper); 372 373 this.elems.img = $('<img/>', { 374 'class' : 'chocolat-img', 375 'src' : '' 376 }).appendTo(this.elems.content); 377 378 this.elems.top = $('<div/>', { 379 'class' : 'chocolat-top'
380 }).appendTo(this.elems.wrapper); 381 382 this.elems.left = $('<div/>', { 383 'class' : 'chocolat-left' 384 }).appendTo(this.elems.wrapper); 385 386 this.elems.right = $('<div/>', { 387 'class' : 'chocolat-right' 388 }).appendTo(this.elems.wrapper); 389 390 this.elems.bottom = $('<div/>', { 391 'class' : 'chocolat-bottom' 392 }).appendTo(this.elems.wrapper); 393 394 this.elems.fullscreen = $('<span/>', { 395 'class' : 'chocolat-fullscreen' 396 }).appendTo(this.elems.bottom); 397 398 this.elems.description = $('<span/>', { 399 'class' : 'chocolat-description' 400 }).appendTo(this.elems.bottom); 401 402 this.elems.pagination = $('<span/>', { 403 'class' : 'chocolat-pagination' 404 }).appendTo(this.elems.bottom); 405 406 this.elems.setTitle = $('<span/>', { 407 'class' : 'chocolat-set-title', 408 'html' : this.settings.setTitle 409 }).appendTo(this.elems.bottom); 410 411 this.elems.close = $('<span/>', { 412 'class' : 'chocolat-close' 413 }).appendTo(this.elems.top); 414 }, 415 416 openFullScreen : function() { 417 var wrapper = this.elems.wrapper[0]; 418 419 if (wrapper.requestFullscreen) { 420 this.settings.fullscreenOpen = true; 421 wrapper.requestFullscreen(); 422 } 423 else if (wrapper.mozRequestFullScreen) { 424 this.settings.fullscreenOpen = true; 425 wrapper.mozRequestFullScreen(); 426 } 427 else if (wrapper.webkitRequestFullscreen) { 428 this.settings.fullscreenOpen = true; 429 wrapper.webkitRequestFullscreen(); 430 } 431 else if (wrapper.msRequestFullscreen) { 432 wrapper.msRequestFullscreen(); 433 this.settings.fullscreenOpen = true; 434 } 435 else { 436 this.settings.fullscreenOpen = false; 437 } 438 }, 439 440 exitFullScreen : function() { 441 if (document.exitFullscreen) { 442 document.exitFullscreen(); 443 this.settings.fullscreenOpen = false; 444 } 445 else if (document.mozCancelFullScreen) { 446 document.mozCancelFullScreen(); 447 this.settings.fullscreenOpen = false; 448 } 449 else if (document.webkitExitFullscreen) { 450 document.webkitExitFullscreen(); 451 this.settings.fullscreenOpen = false; 452 } 453 else { 454 this.settings.fullscreenOpen = true; 455 } 456 }, 457 458 events : function() { 459 var that = this; 460 461 $(document).off('keydown.chocolat').on('keydown.chocolat', function(e) { 462 if (that.settings.initialized) { 463 if (e.keyCode == 37) { 464 that.change(-1); 465 } 466 else if (e.keyCode == 39) { 467 that.change(1); 468 } 469 else if (e.keyCode == 27) { 470 that.close(); 471 } 472 } 473 }); 474 // this.elems.wrapper.find('.chocolat-img') 475 // .off('click.chocolat') 476 // .on('click.chocolat', function(e) { 477 // var currentImage = that.settings.images[that.settings.currentImage]; 478 // if(currentImage.width > $(that.elems.wrapper).width() || currentImage.height > $(that.elems.wrapper).height() ){ 479 // that.toggleZoom(e); 480 // } 481 // }); 482 483 this.elems.wrapper.find('.chocolat-right') 484 .off('click.chocolat') 485 .on('click.chocolat', function() { 486 that.change(+1); 487 }); 488 489 this.elems.wrapper.find('.chocolat-left') 490 .off('click.chocolat') 491 .on('click.chocolat', function() { 492 return that.change(-1); 493 }); 494 495 $([this.elems.overlay[0], this.elems.close[0]]) 496 .off('click.chocolat') 497 .on('click.chocolat', function() { 498 return that.close(); 499 }); 500 501 this.elems.fullscreen 502 .off('click.chocolat') 503 .on('click.chocolat', function() { 504 if (that.settings.fullscreenOpen) { 505 that.exitFullScreen(); 506 return; 507 } 508 509 that.openFullScreen(); 510 }); 511 512 if (that.settings.backgroundClose) { 513 this.elems.overlay 514 .off('click.chocolat') 515 .on('click.chocolat', function() { 516 return that.close(); 517 }); 518 } 519 this.elems.wrapper.find('.chocolat-img') 520 .off('click.chocolat') 521 .on('click.chocolat', function(e) { 522 if (that.settings.initialZoomState === null && that.elems.domContainer.hasClass('chocolat-zoomable')) { 523 return that.zoomIn(e); 524 } 525 else { 526 return that.zoomOut(e); 527 } 528 529 }); 530 531 this.elems.wrapper.mousemove(function( e ) { 532 if (that.settings.initialZoomState === null) { 533 return; 534 } 535 if (that.elems.img.is(':animated')) { 536 return; 537 } 538 539 var pos = $(this).offset(); 540 var height = $(this).height(); 541 var width = $(this).width(); 542 543 var currentImage = that.settings.images[that.settings.currentImage];
544 var imgWidth = currentImage.width; 545 var imgHeight = currentImage.height; 546 547 var coord = [e.pageX - width/2 - pos.left, e.pageY - height/2 - pos.top]; 548 549 var mvtX = 0; 550 if (imgWidth > width) { 551 mvtX = coord[0] / (width / 2); 552 mvtX = ((imgWidth - width + 0)/ 2) * mvtX; 553 } 554 555 var mvtY = 0; 556 if (imgHeight > height) { 557 mvtY = coord[1] / (height / 2); 558 mvtY = ((imgHeight - height + 0) / 2) * mvtY; 559 } 560 561 var animation = { 562 'margin-left': - mvtX + 'px', 563 'margin-top': - mvtY + 'px' 564 }; 565 if (typeof e.duration !== 'undefined') { 566 $(that.elems.img).stop(false, true).animate(animation, e.duration); 567 } 568 else { 569 $(that.elems.img).stop(false, true).css(animation); 570 } 571 572 }); 573 $(window).on('resize', function() { 574 if (!that.settings.initialized) { 575 return; 576 } 577 that.debounce(50, function() { 578 fitting = that.fit(that.settings.currentImage, that.settings.container); 579 that.center(fitting.width, fitting.height, fitting.left, fitting.top, 0); 580 that.zoomable(); 581 }); 582 }); 583 }, 584 585 zoomable : function () { 586 var currentImage = this.settings.images[this.settings.currentImage]; 587 var wrapperWidth = this.elems.wrapper.width(); 588 var wrapperHeight = this.elems.wrapper.height(); 589 590 var isImageZoomable = currentImage.width > wrapperWidth || currentImage.height > wrapperHeight; 591 var isImageStretched = this.elems.img.width() > currentImage.width || this.elems.img.height() > currentImage.height; 592 593 594 if (isImageZoomable && !isImageStretched) { 595 this.elems.domContainer.addClass('chocolat-zoomable'); 596 } 597 else { 598 this.elems.domContainer.removeClass('chocolat-zoomable'); 599 } 600 }, 601 602 zoomIn : function (e) { 603 this.settings.initialZoomState = this.settings.imageSize; 604 this.settings.imageSize = 'native'; 605 606 var event = $.Event('mousemove'); 607 event.pageX = e.pageX; 608 event.pageY = e.pageY; 609 event.duration = this.settings.duration; 610 this.elems.wrapper.trigger(event); 611 612 this.elems.domContainer.addClass('chocolat-zoomed'); 613 fitting = this.fit(this.settings.currentImage, this.settings.container); 614 return this.center(fitting.width, fitting.height, fitting.left, fitting.top, this.settings.duration); 615 }, 616 617 zoomOut : function (e, duration) { 618 if (this.settings.initialZoomState === null) { 619 return; 620 } 621 duration = duration || this.settings.duration; 622 623 this.settings.imageSize = this.settings.initialZoomState; 624 this.settings.initialZoomState = null; 625 this.elems.img.animate({'margin': 0}, duration); 626 627 this.elems.domContainer.removeClass('chocolat-zoomed'); 628 fitting = this.fit(this.settings.currentImage, this.settings.container); 629 return this.center(fitting.width, fitting.height, fitting.left, fitting.top, duration); 630 }, 631 632 setDomContainer : function() { 633 // if container == window 634 // domContainer = body 635 if ( this.settings.container === window) { 636 this.elems.domContainer = $('body'); 637 } 638 else { 639 this.elems.domContainer = $(this.settings.container); 640 } 641 }, 642 643 debounce: function(duration, callback) { 644 clearTimeout(this.settings.timerDebounce); 645 this.settings.timerDebounce = setTimeout(function() { 646 callback(); 647 }, duration); 648 }, 649 650 api: function() { 651 var that = this; 652 return { 653 open : function(i){ 654 i = parseInt(i) || 0; 655 return that.init(i); 656 }, 657 658 close : function(){ 659 return that.close(); 660 }, 661 662 next : function(){ 663 return that.change(1); 664 }, 665 666 prev : function(){ 667 return that.change(-1); 668 }, 669 670 goto : function(i){ // open alias 671 return that.open(i); 672 }, 673 current : function(){ 674 return that.settings.currentImage; 675 }, 676 677 place : function(){ 678 return that.place(that.settings.currentImage, that.settings.duration); 679 }, 680 681 destroy : function(){ 682 return that.destroy(); 683 }, 684 685 set : function(property, value){ 686 that.settings[property] = value; 687 return value; 688 }, 689 690 get : function(property){ 691 return that.settings[property]; 692 }, 693 694 getElem : function(name){ 695 return that.elems[name]; 696 }, 697 }; 698 } 699 }); 700 701 $.fn.Chocolat = function (options) { 702 return this.each(function() { 703 704 calls++; 705 706 var settings = $.extend(true, {}, defaults, options, {setIndex:calls} ); 707 708 if (!$.data(this, 'chocolat')) { 709 $.data(this, 'chocolat', 710 new Chocolat($(this), settings) 711 ); 712 } 713 }); 714 }; 715})( jQuery, window, document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.