1/*! 2 * The Grid â Core jQuery Plugin 3 * Copyright © 2015 All Rights Reserved. 4 * @author Themeone [http://theme-one.com/the-grid/] 5 */ 6 7/*global jQuery:false*/ 8/*global tg_global_var:false*/ 9/*global SC:false*/ 10/*global YT:false*/ 11/*global $f:false*/ 12/*global mejs*/ 13/*global TG_Slider:false*/ 14/*global TG_metaData*/ 15/*global TG_excludeItem*/ 16/*global FOOBOX*/ 17/*func = shorthand if function */ 18 19jQuery.noConflict(); 20 21// The Grid default settings 22var The_Grid = { 23 preview : '#tg-grid-preview-inner', 24 wrapper : '.tg-grid-wrapper', 25 slider : '.tg-grid-slider', 26 grid : '.tg-grid-holder', 27 loader : '.tg-grid-preloader', 28 ajax : '.tg-ajax-button', 29 ajaxMsg : '.tg-ajax-scroll-holder', 30 sizer : '.tg-grid-sizer', 31 gutter : '.tg-gutter-sizer', 32 item : '.tg-item', 33 itemImg : '.tg-item-image', 34 gallery : '.tg-item-gallery-holder', 35 tooltip : '.tg-filter-count', 36 filterH : '.tg-filters-holder', 37 filter : '.tg-filter, .tg-filters-holder select', 38 search : '.tg-search', 39 clear : '.tg-search-clear', 40 sorter : '.tg-sorters-holder', 41 sorterBy: '.tg-sorter li, select.tg-sorter', 42 sortASC : '.tg-sorter-order', 43 arrLeft : '.tg-left-arrow', 44 arrRight: '.tg-right-arrow', 45 bullets : '.tg-slider-bullets', 46 pages : '.tg-page-ajax', 47 sortData: { 48 excerpt : 'p', 49 title : function(elem) { 50 return jQuery(elem).data('title'); 51 }, 52 id : function(elem) { 53 return jQuery(elem).data('id'); 54 }, 55 date : function(elem) { 56 return jQuery(elem).data('date'); 57 }, 58 author : function(elem) { 59 return jQuery(elem).data('author'); 60 }, 61 comment : function(elem) { 62 return jQuery(elem).data('comment'); 63 }, 64 popular_post : function(elem) { 65 return jQuery(elem).data('popular-post'); 66 }, 67 total_sales : function(elem) { 68 return jQuery(elem).data('total-sales'); 69 }, 70 regular_price : function(elem) { 71 return jQuery(elem).data('regular-price'); 72 }, 73 sale_price : function(elem) { 74 return jQuery(elem).data('sale-price'); 75 }, 76 featured : function(elem) { 77 return jQuery(elem).data('featured'); 78 }, 79 stock : function(elem) { 80 return jQuery(elem).data('stock'); 81 }, 82 sku : function(elem) { 83 return jQuery(elem).data('sku'); 84 } 85 }, 86 defaults: { 87 //init : function() {}, 88 //relayout : function() {}, 89 style : 'grid', 90 layout : 'vertical', 91 fitrows : false, 92 fullWidth : null, 93 fullHeight : null, 94 rtl : true, 95 filterComb : false, 96 filterLogic: 'AND', 97 filterLoad : '', 98 sortByLoad : '', 99 orderLoad : false, 100 row : 1, 101 ratio : 1, 102 gutters : [[9999,0],[1200,0],[980,0],[768,0],[480,0],[320,0]], 103 cols : [[9999,4],[1200,3],[980,3],[768,2],[480,1],[320,1]], 104 rows : [[9999,240],[1200,240],[980,220],[768,220],[480,200],[320,200]], 105 animation : [{'name':'None'},{'visible':''},{'hidden':''}], 106 transition : 0, 107 itemNav : null, 108 swingSpeed : 500, 109 cycleBy : null, 110 cycle : 5000, 111 startAt : 0, 112 ajaxMethod : null, 113 ajaxDelay : 0, 114 preloader : 0, 115 itemDelay : 0, 116 gallery : false 117 } 118}; 119 120// Extend sortby with custom metadata 121var tg_meta_data = tg_global_var.meta_data; 122var tg_custom_sorter = {}; 123if (tg_meta_data) { 124 for (var i = 0; i < tg_meta_data.length; i++) { 125 var tg_cmk = tg_meta_data[i].key; 126 tg_cmk = (tg_cmk.length && tg_cmk[0] == '_') ? tg_cmk.slice(1) : tg_cmk; 127 var tg_cma = tg_cmk.replace(/\_/g, '-'); 128 (function(tg_cma){ 129 tg_custom_sorter[tg_cmk] = function(elem) { 130 return jQuery(elem).data(tg_cma); 131 }; 132 })(tg_cma); 133 } 134} 135// add new custom sorter to the grid 136The_Grid.sortData = jQuery.extend({}, The_Grid.sortData, tg_custom_sorter); 137 138var tg_debounce_resize = (tg_global_var.debounce) ? 'debouncedresize' : 'resize'; // debounce resize functionnality 139var tg_is_mobile = (tg_global_var.is_mobile); // check is we are on a mobile device 140 141(function($) { 142 143 "use strict"; 144 145 // the grid jquery plugin 146 $.fn.The_Grid = function(options) { 147 148 // Loop foreach grid (multi instance) 149 return this.each(function () { 150 151 // current grid 152 var el = $(this); 153 154 // main grid var 155 var revealItems, 156 buttonFilter, 157 sortByValue, 158 sortByName, 159 rand1, 160 index1, 161 index2, 162 gallery_imgs = [], 163 sortOrder = true, 164 item_nb = true, 165 isInit = false, 166 isAjax = false, 167 page = 1, 168 $frame, 169 gutter, 170 itemW, 171 itemH, 172 colR, 173 colN, 174 colW, 175 colH, 176 offs, 177 realW, 178 func, 179 xhr = null; 180 181 // define main DOM 182 var ID = el.closest(The_Grid.wrapper).attr('id'), 183 $wrapper = ($('[id="'+ID+'"]').length > 1) ? el.closest(The_Grid.wrapper) : $('#'+ID), 184 $preview = $wrapper.closest(The_Grid.preview), 185 $slider = $wrapper.find(The_Grid.slider), 186 $loader = $wrapper.find(The_Grid.loader), 187 $ajax = $wrapper.find(The_Grid.ajax), 188 $ajaxMsg = $wrapper.find(The_Grid.ajaxMsg), 189 $sizer = $wrapper.find(The_Grid.sizer), 190 $gutter = $wrapper.find(The_Grid.gutter), 191 $item = $wrapper.find(The_Grid.item), 192 $filterH = $wrapper.find(The_Grid.filterH), 193 $filter = $wrapper.find(The_Grid.filter), 194 $search = $wrapper.find(The_Grid.search), 195 $clear = $wrapper.find(The_Grid.clear), 196 $sorter = $wrapper.find(The_Grid.sorter), 197 $sorterBy = $wrapper.find(The_Grid.sorterBy), 198 $sortASC = $wrapper.find(The_Grid.sortASC), 199 $arrLeft = $wrapper.find(The_Grid.arrLeft), 200 $arrRight = $wrapper.find(The_Grid.arrRight), 201 $bullets = $wrapper.find(The_Grid.bullets), 202 $pages = $wrapper.find(The_Grid.pages); 203 204 // retireve all data 205 var data = el.data(); 206 207 // get grid settings (check for existing key in case php errors) 208 var settings = { 209 //init : options.init, 210 //relayout : options.relayout, 211 style : (data.style) && data.style, 212 layout : (data.layout) && data.layout, 213 fitrows : (data.fitrows) && data.fitrows, 214 fullWidth : (data.fullwidth) && data.fullwidth, 215 fullHeight : (data.fullheight) && data.fullheight, 216 rtl : (data.rtl) && data.rtl, 217 filterComb : (data.filtercomb) && data.filtercomb, 218 filterLogic : (data.filterlogic) && data.filterlogic, 219 filterLoad : (data.filterload) && data.filterload, 220 sortByLoad : (data.sortbyload) && data.sortbyload, 221 orderLoad : (data.orderload) && data.orderload, 222 row : (data.row) && data.row, 223 ratio : (data.ratio) && data.ratio, 224 gutters : (data.gutters) && data.gutters, 225 cols : (data.cols) && data.cols, 226 rows : (data.rows) && data.rows, 227 animation : (data.animation) && data.animation, 228 transition : (data.transition) && data.transition, 229 itemNav : (data.slider) && data.slider.itemNav, 230 swingSpeed : (data.slider) && data.slider.swingSpeed, 231 cycleBy : (data.slider) && data.slider.cycleBy, 232 cycle : (data.slider) && data.slider.cycle, 233 startAt : (data.slider) && data.slider.startAt, 234 ajaxMethod : (data.ajaxmethod) && data.ajaxmethod, 235 ajaxDelay : (data.ajaxdelay) && data.ajaxdelay, 236 preloader : (data.preloader) && data.preloader, 237 itemDelay : (data.itemdelay) && data.itemdelay, 238 gallery : (data.gallery) && data.gallery, 239 }; 240 241 // check/set settings compare to default grid 242 var options = $.extend({},The_Grid.defaults, settings); 243 // sort cols array desc numeric (for futur column number detection) 244 options.cols.sort(function(a, b){return b[0]-a[0];}); 245 // sort gutters array desc numeric (for futur rows height detection) 246 options.gutters.sort(function(a, b){return b[0]-a[0];}); 247 // sort rows array desc numeric (for futur rows height detection) 248 options.rows.sort(function(a, b){return b[0]-a[0];}); 249 // set correct value for RTL layout 250 options.rtl = (options.rtl) ? false : true; 251 // Ajax pagination get same delay on reveal 252 options.ajaxDelay = ($pages.length > 0) ? options.itemDelay : options.ajaxDelay; 253 // remove all data for security and confidentiality 254 var keys = $.map(data, function(value, key) { return key; }); 255 for (var i = 0; i < keys.length; i++) { 256 el.removeAttr('data-' + keys[i]); 257 } 258 259 // build the grid 260 full_width(); // 1. resize the grid wrapper at first 261 columns(el); // 2. then calculate the columns width based on the wrapper width 262 item_size(); // 3. set the sizes to each item based on the column width 263 item_gallery(); // 4. init item gallery animation 264 count_filter(); // 5. count and update filter number if necessary 265 266 // set the grid size after everything loaded in masonry mode to relayout correctly 267 if (options.style === 'masonry' || options.style === 'justified' || options.preloader || options.layout === 'horizontal') { 268 $item.the_grid_images_loaded({ 269 complete: function() { 270 slider_size(); // 7. calculate slider height if necessary 271 set_grid(); // 8. check grid parameters values 272 init_slider(); // 9. init slider if available 273 func = (options.preloader) && reveal_grid(); 274 // call on filtering, sorting, searching, and resizing after complete 275 func = (options.layout === 'horizontal') && el.TG_Layout('on', 'arrangeComplete', function(e) {onAnimationEnd(e);}); // filter/sort 276 // run the init callback method 277 //func = (typeof options.init == 'function') && options.init.call(el); 278 } 279 }); 280 } else { 281 set_grid(); // 7. check grid parameters values 282 init_slider(); // 8. init slider if available 283 // call on filtering, sorting, searching, and resizing after complete 284 func = (options.layout === 'horizontal') && el.TG_Layout('on', 'arrangeComplete', function(e) {onAnimationEnd(e);}); // filter /sort 285 } 286 287 // all events init 288 isInit = (!options.preloader) && true; 289 func = (isInit) && $wrapper.addClass('tg-grid-loaded'); 290 291 function onAnimationEnd(e) { 292 var length = $item.not('.tg-item-hidden').length; 293 if (e.length === length) { 294 $frame.reload(); 295 } 296 } 297 298 // redefined and remove/clean data 299 function cleanData(target) { 300 for (var y = 0; y < $(target).length; y++) { 301 var $this = $(target).eq(y), key, val, 302 data = $this.get(0).attributes; 303 for (var i = 0; i < data.length; i++) { 304 key = data[i].name; 305 val = data[i].value; 306 if (key.indexOf('data-') === 0 && key !== 'data-row' && key !== 'data-col') { 307 $this.removeAttr(key); 308 $this.data(key.replace('data-',''),val); 309 i--; 310 } 311 } 312 } 313 } 314 315 // detect dropdown select list on touch devices 316 $filter.on('click', function(e) { 317 var $this = $(this); 318 if (!$this.is('select')) { 319 filterBy($this); 320 } else { 321 $filter.one('change', function() { 322 filterBy($this.find('option:selected')); 323 });
324 } 325 // run the layout callback method 326 //func = (typeof options.relayout == 'function') && el.TG_Layout('once', 'layoutComplete', function(e) {options.relayout.call(el);}); 327 }); 328 329 function filterBy($this) { 330 if (!isInit) { 331 return false; 332 } 333 var filterValue; 334 // remove class reveal and clear seach field before filtering 335 $item.removeClass('tg-item-index'); 336 $search.val(''); 337 // check if filter combination or not 338 if (options.filterComb) { 339 filterValue = []; 340 func = ($this.data('filter') === '*') ? $this.nextAll('[data-filter]').removeClass('tg-filter-active') : $this.prevAll('[data-filter="*"]').removeClass('tg-filter-active'); 341 func = ($this.data('filter') === '*') ? $this.closest('select').find('option').prop('selected', false) : $this.closest('select').find('[data-filter="*"]').prop('selected', true); 342 $this.toggleClass('tg-filter-active'); 343 $wrapper.find('.tg-filter-active').each(function(){ 344 if ($(this).data('filter') != '*') { 345 filterValue.push($(this).data('filter')); 346 } 347 }); 348 filterValue = (options.filterLogic === 'AND') ? concatValues(filterValue) : filterValue.join(', '); 349 } else { 350 filterValue = $this.data('filter'); 351 $filter.removeClass('tg-filter-active'); 352 $this.addClass('tg-filter-active'); 353 } 354 func = (!filterValue) && $wrapper.find('[data-filter="*"]').addClass('tg-filter-active'); 355 checkFilters(); 356 // apply filter(s) 357 el.TG_Layout({filter: filterValue}); 358 // pause all videos 359 $.TG_Pause_Players(); 360 } 361 362 function concatValues( obj ) { 363 var value = ''; 364 for ( var prop in obj ) { 365 if(obj.hasOwnProperty(prop)) { 366 value += obj[ prop ]; 367 } 368 } 369 return value; 370 } 371 372 function checkFilters() { 373 $filterH.each(function(index, element) { 374 var nbActive = $(this).find(The_Grid.filter+'.tg-filter-active').length; 375 func = (nbActive === 0) && $(this).find('[data-filter="*"]').addClass('tg-filter-active'); 376 }); 377 } 378 379 if (!tg_is_mobile) { 380 $sorterBy.on('click', function() { 381 sortBy($(this)); 382 }); 383 } else { 384 $sorterBy.on('change', function() { 385 sortBy($(this).find('option:selected')); 386 }); 387 } 388 389 function sortBy(il) { 390 if (!isInit) { 391 return false; 392 } 393 sortByValue = (il.data('value') === 'none') ? '' : il.data('value'); 394 sortByName = il.text(); 395 sortOrder = $sortASC.data('asc'); 396 $item.removeClass('tg-item-index'); 397 $sorter.find('.tg-dropdown-value').text(sortByName); 398 el.TG_Layout({ 399 sortAscending: sortOrder, 400 sortBy: sortByValue 401 }); 402 // run the layout callback method 403 //func = (typeof options.relayout == 'function') && el.TG_Layout('once', 'layoutComplete', function(e) {options.relayout.call(el);}); 404 } 405 406 // TG_Layout sorter functionnality (ASC/DESC only) 407 $sortASC.on('click', function() { 408 if (!isInit) { 409 return false; 410 } 411 var $this = $(this); 412 sortOrder = ($this.data('asc') === true) ? false : true; 413 $this.data('asc',sortOrder).attr('data-asc',sortOrder); 414 $item.removeClass('tg-item-index'); 415 el.TG_Layout({ 416 sortAscending: sortOrder 417 }); 418 // run the layout callback method 419 //func = (typeof options.relayout == 'function') && el.TG_Layout('once', 'layoutComplete', function(e) {options.relayout.call(el);}); 420 }); 421 422 // use value of search field to filter (regex in content) 423 var $quicksearch = $search.keyup( debounce( function() { 424 if (!isInit) { 425 return false; 426 } 427 var qsRegex = new RegExp($quicksearch.val(), 'gi'); 428 $item.removeClass('tg-item-index'); 429 $filter.removeClass('tg-filter-active'); 430 el.TG_Layout({ 431 filter: function() { 432 var $this = $(this); 433 var searchResult = qsRegex ? $this.text().match(qsRegex) : true; 434 var buttonResult = buttonFilter ? $this.is(buttonFilter) : true; 435 $('.tg-filter[data-filter="*"]').addClass('tg-filter-active'); 436 return searchResult && buttonResult; 437 } 438 }); 439 // pause all videos 440 $.TG_Pause_Players(); 441 // run the layout callback method 442 //func = (typeof options.relayout == 'function') && options.relayout.call(el) 443 }, 200)); 444 445 $clear.on('click', function() { 446 $search.val('').trigger('keyup'); 447 // run the layout callback method 448 //func = (typeof options.relayout == 'function') && el.TG_Layout('once', 'layoutComplete', function(e) {options.relayout.call(el);}); 449 }); 450 451 // resize grids 452 $(window).on(tg_debounce_resize, function() { 453 full_width(); // 1. resize the grid wrapper at first 454 columns(); // 2. then calculate the column width based on the wrapper width 455 item_size(); // 3. set size to items based on the column width 456 slider_size(); // 4. calculate slider height if necessary 457 // 5. Relayout the grid 458 func = (isInit && el.closest('body').length > 0) && el.TG_Layout('layout'); 459 // 6. Check animation end for horizontal layout to update slider 460 func = (options.layout === 'horizontal') && el.TG_Layout('once', 'layoutComplete', function(e) {onAnimationEnd(e);}); 461 // run the layout callback method 462 //func = (typeof options.relayout == 'function') && el.TG_Layout('once', 'layoutComplete', function(e) {options.relayout.call(el);}); 463 }); 464 465 // force full width 466 function full_width() { 467 if (options.fullWidth && $preview.length === 0) { 468 $wrapper.css('left',0); 469 var margL = parseInt($wrapper.css('margin-left')); 470 var margR = parseInt($wrapper.css('margin-right')); 471 var offset = $wrapper.offset().left-margL; 472 $wrapper.width($(window).width()-(margL+margR)); 473 $wrapper.css('left',-offset); 474 } 475 } 476 477 // random item gallery animation 478 function item_gallery() { 479 if (options.gallery) { 480 var gallery; 481 update_gallery(); 482 if (!The_Grid.galleryInt && $(The_Grid.gallery).length > 0 ) { 483 The_Grid.galleryInt = setInterval(function () { 484 rand1 = Math.floor(Math.random()*gallery_imgs.length); 485 index1 = (index1 === rand1 && gallery_imgs.length > 0) ? check_index(gallery_imgs,rand1+1) : rand1; 486 gallery = $(The_Grid.gallery).eq(index1); 487 index2 = (gallery_imgs.length > 0) ? check_index(gallery_imgs[index1],(gallery.find('.show').index()-1)+2) : 0; 488 gallery.find(The_Grid.itemImg).removeClass('show'); 489 gallery.find(The_Grid.itemImg).eq(index2).addClass('show'); 490 },3500); 491 } 492 } 493 } 494 495 // check image gallery index for unique random 496 function check_index(array,index) { 497 return (array.length + (index % array.length)) % array.length; 498 } 499 500 // get all galleries 501 function update_gallery() { 502 gallery_imgs = []; 503 var galleries = $(The_Grid.gallery); 504 for (var i = 0; i < galleries.length; i++) { 505 var images = $(galleries[i]).find(The_Grid.itemImg); 506 gallery_imgs[i] = []; 507 for (var x = 0; x < images.length; x++) { 508 gallery_imgs[i][x] = $(images[x]); 509 } 510 } 511 } 512 513 // count number per filter category/tag/term 514 function count_filter() { 515 for (var i = 0; i < $filter.length; i++) { 516 var cat = $filter.eq(i).data('filter'); 517 // if ajax page not count elements removing 518 var not = ($pages.length > 0) ? '.tg-item-hidden' : null; 519 var count = (cat !== '*') ? el.find(cat).not(not).length : $item.not(not).length; 520 $filter.eq(i).find(The_Grid.tooltip).html(count); 521 func = ($filter.eq(i).find('span:first-child').data('count')) && $filter.eq(i).find('span:first-child').data('tooltip',count); 522 func = (count === 0) ? $filter.eq(i).removeClass('tg-show-filter') : $filter.eq(i).addClass('tg-show-filter'); 523 } 524 } 525 526 // count item to load more 527 function count_items() { 528 if ($ajax.length > 0) {
529 item_nb = ($ajax.data('item-tt')) ? $ajax.data('item-tt')-$item.length : 99999; 530 if (item_nb <= 0) { 531 $ajax.addClass('tg-no-more'); 532 $ajax.find('span').html($ajax.data('no-more')); 533 setTimeout(function(){ 534 $ajax.fadeOut(500); 535 },3000); 536 } else { 537 var button_txt = $ajax.data('button'); 538 func = ($ajax.data('remain')) ? $ajax.find('span').html(button_txt+' ('+item_nb+')') : $ajax.find('span').html(button_txt); 539 } 540 } 541 } 542 543 // reveal grid on load 544 function reveal_grid() { 545 var i = 0, 546 interval, 547 data = el.data('TG_Layout'); 548 func = ($pages.length === 0) ? $loader.remove() : $loader.hide(); 549 $wrapper.removeClass('tg-grid-loading'); 550 revealItems = data.filteredItems; 551 if (revealItems.length > 0) { 552 interval = window.tgInterval(function(){ 553 if (el.closest('body').length > 0) { 554 $(revealItems[i].element).removeClass('tg-item-reveal'); 555 func = (options.itemDelay) && el.TG_Layout('reveal', [revealItems[i]]); 556 if (i === revealItems.length-1 || !options.itemDelay) { 557 isInit = true; 558 $item.removeClass('tg-item-reveal'); 559 $wrapper.addClass('tg-grid-loaded'); 560 func = (!options.itemDelay) && el.TG_Layout('reveal', revealItems); 561 interval.clear(); 562 } 563 i++; 564 } 565 },options.itemDelay); 566 } else { 567 isInit = true; 568 $item.removeClass('tg-item-reveal'); 569 $wrapper.addClass('tg-grid-loaded'); 570 } 571 } 572 573 // Calculate column width number for current window width 574 function columns() { 575 var arr = (options.style !== 'justified') ? options.cols : options.rows; 576 var ww = viewport().width; 577 for (var i = 0, l = arr.length; i < l; i++ ) { 578 if (arr[i][0] >= ww) { 579 colN = arr[i][1]; 580 gutter = options.gutters[i][1]; 581 } else { 582 break; 583 } 584 } 585 // set gutters 586 $gutter.width(gutter); 587 if (options.style !== 'justified') { 588 var tw = $wrapper.width(); 589 colW = (tw/colN) - gutter; 590 if (options.layout === 'vertical') { 591 el.width(''); 592 offs = (colN-1)*gutter; 593 colW = (tw-offs)/colN; 594 colW = (colW % 1 !== 0) ? Math.ceil(colW) : colW; 595 realW = colN*colW+offs; 596 el.css('left', -(realW-el.width())/2+'px'); 597 el.width(realW); 598 } 599 if (options.fullHeight && options.layout === 'horizontal') { 600 var adminH = $('#wpadminbar').height(); 601 if ($preview.length === 0) { 602 colH = (($(window).height()-adminH)-(gutter*(options.row-1)))/options.row; 603 } else { 604 colH = ($preview.height())/options.row; 605 } 606 } else { 607 // round for accurate slider height (no need for width!) 608 colH = Math.round(colW/options.ratio); 609 } 610 } else { 611 // justified row height is colH 612 colH = colN; 613 $sizer.height(colH); 614 } 615 // add slider padding if free mode 616 func = (options.itemNav === 'null') && $slider.css('padding', '0 '+gutter/2+'px'); 617 } 618 619 // calculate window viewport (real width to match queries!) 620 function viewport() { 621 if ($preview.length === 0) { 622 var e = window, 623 a = 'inner'; 624 if (!('innerWidth' in window )) { 625 a = 'client'; 626 e = document.documentElement || document.body; 627 } 628 return { width : e[ a+'Width' ]}; 629 } else { 630 return { width : $preview.width()}; 631 } 632 } 633 634 // calculate item size and resize if necessary (unlimited size possibility!) 635 function item_size() { 636 if (options.style !== 'justified') { 637 // set grid sizer 638 $sizer.width(colW); 639 for (var i = 0; i < $item.length; i++) { 640 var coli = $item.eq(i).data('col'), 641 rowi = $item.eq(i).data('row'); 642 rowi = ((options.layout === 'horizontal') && rowi > options.row) ? options.row : rowi; 643 if (colN === 1) { 644 itemW = colW; 645 itemH = colH; 646 } else if (colN < coli) { 647 colR = Math.round(colN/(coli/rowi)); 648 colR = (colR <= 1) ? 1 : colR; 649 itemW = colN*colW+(colN-1)*gutter; 650 itemH = (colR === 1) ? colH : colR*colH+(colR-1)*gutter; 651 } else { 652 itemW = coli*colW+(coli-1)*gutter; 653 itemH = rowi*colH+(rowi-1)*gutter; 654 } 655 $item.eq(i).width(itemW); 656 func = (options.style === 'grid') ? $item.eq(i).height(itemH) : null; 657 } 658 } 659 } 660 661 // calculate slider inner height 662 function slider_size() { 663 if (options.layout === 'horizontal') { 664 var sliderH; 665 if (options.style === 'masonry') { 666 $wrapper.removeClass('tg-grid-loading'); 667 // only when all images are loaded to get right height in masonry mode 668 sliderH = Math.max.apply(null, $item.map(function () { 669 return $(this).height(); 670 }).get()); 671 el.add($slider).height(sliderH); 672 } else { 673 sliderH = (colH)*options.row+gutter*(options.row-1); 674 el.add($slider).height(sliderH); 675 } 676 } 677 } 678 679 // set the grid 680 function set_grid() { 681 var mode, param; 682 var isHorizontal = false; 683 if (options.layout === 'horizontal') { 684 isHorizontal = true; 685 if (options.style === 'grid') { 686 mode = param = 'packery'; 687 } else if (options.style === 'justified'){ 688 mode = param = 'justified'; 689 } else { 690 mode = param = 'horizontal'; 691 } 692 } else if (options.style === 'grid') { 693 mode = param = 'packery'; 694 } else { 695 mode = param = options.style; 696 } 697 var layout = {}; 698 layout[param] = {}; 699 layout.hiddenStyle = {}; 700 layout.visibleStyle = {}; 701 layout.layoutMode = mode; 702 layout.filter = options.filterLoad; 703 if (options.sortByLoad !== 'none') { 704 layout.sortBy = options.sortByLoad; 705 } 706 layout.sortAscending = options.orderLoad; 707 layout.isOriginLeft = options.rtl; 708 layout.itemSelector = The_Grid.item; 709 layout[param].gutter = $gutter[0]; 710 layout[param].rowHeight = $sizer[0]; 711 layout[param].columnWidth = $sizer[0]; 712 layout[param].isHorizontal = isHorizontal; 713 layout[param].isFitRows = options.fitrows; 714 layout[param].image = The_Grid.itemImg; 715 layout[param].row = options.row; 716 layout[param].previewMode = $preview; 717 layout.hiddenStyle.opacity = 0; 718 layout.visibleStyle.opacity = 1; 719 layout.hiddenStyle.transform = options.animation.hidden; 720 layout.visibleStyle.transform = options.animation.visible; 721 layout.transitionDuration = options.transition; 722 layout.getSortData = The_Grid.sortData; 723 el.TG_Layout(layout); 724 // secure data 725 cleanData($item); 726 } 727 728 // init horizontal slider 729 function init_slider() { 730 if (options.layout === 'horizontal') { 731 732 var data = el.data('TG_Layout'), 733 filteredItems = data.filteredItems, 734 index = options.startAt = (options.startAt-1 > filteredItems.length) ? filteredItems.length : options.startAt; 735 736 if (options.itemNav === 'forceCentered' && $bullets.length === 0) {
737 $bullets = $($('<div class="tg-slider-bullets"></div>')).appendTo($wrapper).hide(); 738 } 739 740 $frame = new TG_Slider($slider,{ 741 itemSelector : '.tg-item:not(.tg-item-hidden)', 742 cycleBy : options.cycleBy, 743 cycleInterval : options.cycle, 744 pauseOnHover : 1, 745 itemNav : options.itemNav, 746 startAt : options.startAt-1, 747 smart : 1, 748 horizontal : 1, 749 easing : 'easeOutExpo', 750 speed : 1000, 751 swingSpeed : options.swingSpeed, 752 releaseSwing : 1, 753 mouseDragging : 1, 754 touchDragging : 1, 755 elasticBounds : 1, 756 moveBy : itemW, 757 syncSpeed : 0.8, 758 keyboardNavBy : 'pages', 759 activeClass : 'tg-active-item', 760 disabledClass : 'tg-disabled', 761 draggedClass : 'tg-slider-dragged', 762 pageBuilder : function () { 763 return '<li><span></span></li>'; 764 }, 765 pagesBar : $bullets, 766 prevPage : $arrLeft, 767 nextPage : $arrRight, 768 activatePageOn: 'click' 769 }).init(); 770 // add event and DOM for slider loaded (for custom event) 771 $slider.data('slider', $frame).trigger('tg-slider-init'); 772 773 // active on force centered nav 774 if (options.itemNav === 'forceCentered') { 775 $(filteredItems[index-1].element).addClass('tg-active-item'); 776 $frame.on('load activePage', function(index) { 777 index = this.rel.activePage; 778 data = el.data('TG_Layout'); 779 filteredItems = data.filteredItems; 780 $item.removeClass('tg-active-item'); 781 func = (filteredItems[index]) && $(filteredItems[index].element).addClass('tg-active-item'); 782 }); 783 } 784 785 } 786 } 787 788 // load more ajax pagination 789 $pages.on('click', function(e) { 790 e.preventDefault(); 791 var $this = $(this); 792 page = $this.data('page'); 793 if (!$this.is('.tg-page-current') && (!xhr || (xhr && xhr.readyState == 4)) && !isAjax && isInit) { 794 $sorter.find('.tg-dropdown-value').text(''); 795 $search.val(''); 796 $filter.removeClass('tg-filter-active'); 797 $('.tg-filter[data-filter="*"]').addClass('tg-filter-active'); 798 $pages.removeClass('tg-page-current').addClass('tg-loading'); 799 $this.addClass('tg-page-current'); 800 // prevent showing filtered items when removing them 801 $('.tg-item-hidden').addClass('tg-item-removed'); 802 // destroy all media (prevent issue with ajax) 803 $.TG_media_destroy(el); 804 // properly remove items, relayout and unfilter 805 el.css('min-height',250).TG_Layout('remove', $item).TG_Layout({filter: '*'}); 806 // remove comments from DOM 807 el.contents().each(function() {func = (this.nodeType == 8) ? $(this).remove() : null;}); 808 // add loading animation 809 $loader.show(); 810 // load next page 811 load_posts(el); 812 } 813 }); 814 815 // load more ajax on click 816 $ajax.on('click', function(e) { 817 if (item_nb) { 818 e.preventDefault(); 819 load_posts(el); 820 } 821 }); 822 823 // load more ajax on scroll 824 if (options.ajaxMethod == 'on_scroll') { 825 $(window).on('mousewheel resize scroll', function() { 826 func = (item_nb && $wrapper.length && $wrapper[0].getBoundingClientRect().bottom < $(this).height() && isInit === true) && load_posts(el); 827 }); 828 } 829 830 // load more post on ajax (on click and scroll) 831 function load_posts(el){ 832 833 // check if ajax request not proceeded and finish before running another one 834 if (xhr && (xhr.readyState == 3 || xhr.readyState == 2 || xhr.readyState == 1)) { 835 return false; 836 } 837 838 var ajaxData = { 839 action : 'the_grid_load_more', 840 grid_nonce : tg_global_var.nonce, 841 grid_name : el.data('name'), 842 grid_page : page, 843 grid_data : get_meta_data(), 844 grid_ajax : el.data('ajax'), 845 main_query : tg_global_var.main_query 846 }; 847 848 xhr = $.ajax({ 849 url: tg_global_var.url, 850 type: 'post', 851 datatype : 'json', 852 data: ajaxData, 853 beforeSend : function(){ 854 isAjax = true; 855 page = page + 1;
856 func = ($ajax.data('loading') && !$ajax.hasClass('tg-no-more')) && $ajax.find('span').html($ajax.data('loading')); 857 func = ($($ajaxMsg).length > 0 && $ajax.length === 0) && $($ajaxMsg).addClass('tg-loading'); 858 }, 859 success : function(data){ 860 861 // retrieve ajax response 862 var success = data.success, 863 message = data.message, 864 content = data.content, 865 ajax_data = data.ajax_data; 866 867 // assign new ajax data (check if json) 868 var is_json = true; 869 try { 870 ajax_data = $.parseJSON(ajax_data); 871 } catch(err) { 872 is_json = false; 873 } 874 el.data('ajax', ajax_data); 875 876 // if an error occur during retrieving content 877 if (!success) { 878 $ajax.add($($ajaxMsg)).add($pages).removeClass('tg-loading'); 879 $loader.find('> div').html(message); 880 $ajax.find('span').html(message); 881 $($ajaxMsg).children('div').html(message); 882 page = page - 1; 883 return false; 884 } 885 886 // ajax on scroll msg 887 if (!content) { 888 $ajax.data('item-tt',-1); 889 count_items(); 890 $($ajaxMsg).children('div').html($($ajaxMsg).children('div').data('no-more')); 891 setTimeout(function(){ 892 $($ajaxMsg).fadeOut(400); 893 }, 1000); 894 page = page - 1; 895 return false; 896 } 897 898 // get all items 899 var $items = $(content); 900 901 // prevent showing item if filtered and hidden 902 func = ($pages.length === 0) && $items.addClass('tg-item-index'); 903 904 // Keep only item if unwanted wrapper exist (for grid cache system) 905 if ($items.find(The_Grid.grid).length > 0) { 906 $items = $items.find(The_Grid.item).removeClass('tg-item-reveal'); 907 } 908 909 el.append($items); // 01. append items 910 $item = el.find(The_Grid.item); // 02. redefined $item DOM 911 $items.hide(); // 03. hide to append with delay 912 item_size(); // 04. calculate size 913 $.TG_media_init(); // 05. Active media (visible/sized for mejs) 914 count_filter(); // 06. re-count filter nb 915 update_gallery(); // 07. update gallery dom 916 item_gallery(); // 08. update animated gallery 917 exclude_item(); // 09. only for preview mode 918 919 // Remove comment tags before items (otherwise it will count 2x and multiply delay) 920 $items = $($.grep($items, function(e){ return typeof e.id !== 'undefined';})); 921 var itemNb = $items.length-1; 922 // wait all images load (mandatory for masonry layout) 923 $items.the_grid_images_loaded({ 924 complete: function() { 925 var i = 0, interval; 926 $loader.hide(); 927 func = (data) && $($ajaxMsg).removeClass('tg-loading'); 928 func = (options.layout === 'horizontal') && el.css('min-height',''); 929 func = (options.style === 'masonry' && options.layout === 'horizontal') && slider_size(); 930 interval = window.tgInterval(function(){ 931 // check if grid still exist during appending (prevent errors on destroy or ajax) 932 if (el.closest('body').length > 0) { 933 func = (options.ajaxDelay) && el.TG_Layout('appended',$items.eq(i)); 934 func = (options.layout === 'horizontal') && $frame.reload(); 935 // show ajax pages & reset ajax 936 if (itemNb === i || !options.ajaxDelay) { 937 count_filter(); // 10. re-count filter nb 938 count_items(); // 11. re-count item for ajax button 939 func = (!options.ajaxDelay) && el.TG_Layout('appended',$items); 940 func = (options.layout === 'horizontal') && $frame.reload(); 941 $pages.removeClass('tg-loading'); 942 isAjax = false; 943 interval.clear(); 944 // update 3rd party plugins lightbox 945 func = (typeof FOOBOX !== 'undefined' && $.isFunction(FOOBOX.init)) && FOOBOX.init(); 946 func = ($().fancybox) && $('.tg-item a.fancybox').fancybox(); 947 func = ($().prettyPhoto) && $('.tg-item a[rel^="prettyPhoto"]').prettyPhoto(); 948 // clean data 949 cleanData($item); 950 return false; 951 } 952 i++; 953 } 954 },options.ajaxDelay); 955 } 956 });
957 }, 958 error : function(jqXHR, textStatus, errorThrown) { 959 page = page - 1; 960 console.error(jqXHR); 961 console.error(textStatus + " :: " + errorThrown); 962 } 963 }); 964 } 965 966 // only if in backend mode for preview 967 function get_meta_data(){ 968 if ($preview.length > 0) { 969 return new TG_metaData($('#the_grid_metabox .tomb-row')); 970 } 971 } 972 973 // check hidden item in backend 974 function exclude_item() { 975 if ($preview.length > 0) { 976 TG_excludeItem(); 977 } 978 } 979 980 }); 981 982 }; 983 984 // ====================================================== 985 // Custom script (Themeone) : preload img src and/or bg image 986 // ====================================================== 987 988 var tg_img_arr = []; 989 990 $.fn.the_grid_images_loaded = function() { 991 992 // current element to search in 993 var el = $(this); 994 995 // extend the options to complete: 996 var options = $.extend({ 997 complete: function() {} 998 }, arguments[0] || {}); 999 1000 // init global var 1001 var count = 0, 1002 preload = [], 1003 img_url; 1004 1005 // search all image inside current selector 1006 el.find('*').filter(function() { 1007 img_url = $(this).css('background-image'); 1008 img_url = /^url\((['"]?)(.*)\1\)$/.exec(img_url); 1009 img_url = img_url ? img_url[2] : null; 1010 img_url = (!img_url && $(this).is('img')) ? $(this).attr('src') : img_url; 1011 img_url = (img_url && (img_url.match(/\.(jpg|jpeg|png|bmp|gif|tif|tiff|jif|jfif)/g) 1012 || img_url.indexOf('external.xx.fbcdn') >= 0 1013 || img_url.indexOf('drscdn.500px.org') >= 0)) ? img_url : null; 1014 if (img_url && $.inArray(img_url, tg_img_arr) == -1) { 1015 preload.push(img_url); 1016 tg_img_arr.push(img_url); 1017 } 1018 }); 1019 1020 // load images 1021 var images = []; 1022 1023 for (var i = 0; i < preload.length; i++) { 1024 images[i] = new Image(); 1025 images[i].onload = imgLoaded; 1026 images[i].onerror = imgLoaded; 1027 images[i].onabort = imgLoaded; 1028 images[i].src = preload[i]; 1029 } 1030 1031 // complete if no images 1032 if (!preload.length) { 1033 options.complete.call(el); 1034 return false; 1035 } 1036 1037 // on load count and compare to array 1038 function imgLoaded() { 1039 count++; 1040 if(count >= preload.length){ 1041 options.complete.call(el); 1042 return false; 1043 } 1044 } 1045 1046 }; 1047 1048 // ====================================================== 1049 // Custom script (Themeone) : DropDown list (to prevent overflow issue) 1050 // ====================================================== 1051 1052 $(document).ready(function() { 1053 1054 var $filters, 1055 animation = 'tg-dropdown-holder-animation'; 1056 1057 if (!tg_is_mobile) { 1058 1059 $(document).on('mouseenter', '.tg-dropdown-holder', function(e) { 1060 e.preventDefault(); 1061 e.stopPropagation(); 1062 var $this = $(this), 1063 listTimer = $($this.data('list-DOM')).data('list-timer'); 1064 1065 if (listTimer) { 1066 clearTimeout(listTimer); 1067 $this.data('list-DOM').addClass(animation); 1068 return false; 1069 } 1070 1071 $filters = $this.find('ul'); 1072 1073 var $list = $filters.clone(true).addClass('tg-list-appended').attr('style','').appendTo('body'); 1074 $this.add($list).data('list-DOM', $list); 1075 $list.data('filter-DOM', $this); 1076 1077 var position = getListPos($this); 1078 1079 $filters.hide(); 1080 1081 $list.css({ 1082 'position' : 'absolute', 1083 'z-index' : 99999, 1084 'width' : position.width, 1085 'top' : position.top, 1086 'left' : position.left 1087 }).addClass(animation); 1088 1089 }).on('mouseleave', '.tg-dropdown-holder', function(e) { 1090 removeList($(this)); 1091 }); 1092 1093 $(document).on('mouseenter touchstart', '.tg-list-appended', function(e) { 1094 var $this = $(this); 1095 if ($this.data('list-DOM')) { 1096 clearTimeout($this.data('list-timer')); 1097 $this.data('list-DOM').addClass(animation); 1098 return false; 1099 } 1100 }).on('mouseleave touchend', '.tg-list-appended', function(e) { 1101 removeList($(this)); 1102 }); 1103 1104 $(document).on('click touchstart', '.tg-list-appended li', function(){ 1105 1106 var $this = $(this).closest('ul'), 1107 $filters = $this.data('filter-DOM'); 1108 1109 $filters.find('[data-filter="'+$(this).data('filter')+'"]').trigger('click');
1110 $filters.find('[data-value="'+$(this).data('value')+'"]').trigger('click'); 1111 $this.width($filters.outerWidth()); 1112 $this.css('left',$filters.offset().left); 1113 1114 var position = getListPos($filters); 1115 1116 if (position.top !== $this.position().top) { 1117 $this.css('top',position.top); 1118 } else { 1119 $this.find('li').removeClass('tg-filter-active'); 1120 $filters.find('.tg-filter-active').each(function(i) { 1121 $this.find('li').eq($(this).index()).addClass('tg-filter-active'); 1122 }); 1123 } 1124 1125 }); 1126 1127 } 1128 1129 function removeList($this) { 1130 if ($this.data('list-DOM')) { 1131 var $list = $this.data('list-DOM').removeClass(animation); 1132 var timer = setTimeout(function() { 1133 $list.remove(); 1134 $list = null; 1135 $this.data('list-DOM', $list); 1136 },400); 1137 $($this.data('list-DOM')).data('list-timer', timer); 1138 } 1139 return false; 1140 } 1141 1142 function getListPos(el) { 1143 var offset = el.parent().offset(), 1144 height = el.parent().height(), 1145 body = ($('body').css('position') === 'relative') ? $(window).scrollTop()+$('body')[0].getBoundingClientRect().top : null, 1146 margin = parseInt(el.css('margin-bottom')), 1147 width = el.outerWidth(), 1148 left = offset.left, 1149 top = offset.top+height-body-margin; 1150 1151 var position = []; 1152 position.top = top; 1153 position.left = left; 1154 position.width = width; 1155 return position; 1156 } 1157 1158 }); 1159 1160 // ====================================================== 1161 // Custom script (Themeone) : Tooltip (prevent overflow issue) 1162 // ====================================================== 1163 1164 $.fn.TG_ToolTip = function(options) { 1165 1166 /*var settings = $.extend({ 1167 data : 'tooltip', // Effect Tooltip class name. 1168 zindex : 99999, // z-index css 1169 place : 'top', // Default place. 1170 appendClass : 'tooltip', // Class to append 1171 hoverClass : null, // Hover class 1172 spacing : 0 // Gap between target and Tooltip. 1173 }, options);*/ 1174 1175 var toolTip_Data = 'tooltip-DOM', 1176 toolTip_Timer = 'tooltip-timer'; 1177 1178 $(document).on('mouseenter', $(this).selector, function() { 1179 1180 var $this = $(this); 1181 1182 if (!$this.data(options.data)) { 1183 return false; 1184 } 1185 1186 if ($this.data(toolTip_Data)) { 1187 clearTimeout($this.data(toolTip_Timer)); 1188 $this.data(toolTip_Data).addClass(options.hoverClass.split('.').join('')); 1189 return false; 1190 } 1191 1192 var $tooltip = $('<div class="'+options.appendClass.split('.').join('')+'"></div>').appendTo('body'); 1193 $this.data(toolTip_Data, $tooltip); 1194 1195 var data = $this.data(options.data), 1196 offset = $this.offset(), 1197 body = ($('body').css('position') === 'relative') ? $(window).scrollTop()+$('body')[0].getBoundingClientRect().top : null, 1198 top = offset.top - body, 1199 left = offset.left, 1200 width = $this.outerWidth(true); 1201 1202 $tooltip.html(data).css({ 1203 'position' : 'absolute', 1204 'z-index' : options.zindex, 1205 'width' : width, 1206 'top' : top+options.spacing-$tooltip.outerHeight(true), 1207 'left' : left+width/2 1208 }).addClass(options.hoverClass.split('.').join('')); 1209 1210 }).on('mouseleave', $(this).selector, function() { 1211 1212 var $this = $(this); 1213 1214 if (!$this.data(options.data) || !$this.data(toolTip_Data)) { 1215 return false; 1216 } 1217 1218 var $tooltip = $this.data(toolTip_Data).removeClass(options.hoverClass.split('.').join('')); 1219 var timer = setTimeout(function() { 1220 $tooltip.remove(); 1221 $tooltip = null; 1222 $this.data(toolTip_Data, $tooltip); 1223 },400); 1224 $this.data(toolTip_Timer, timer); 1225 1226 }); 1227 1228 }; 1229 1230 $(document).ready(function() { 1231 $('.tg-filter-name').TG_ToolTip({ 1232 data : 'tooltip', 1233 zindex : 99999, 1234 place : 'top', 1235 appendClass : '.tg-filter-tooltip', 1236 hoverClass : '.tg-tooltip-hover', 1237 spacing : -2 1238 }); 1239 }); 1240 1241 // ====================================================== 1242 // Handle media content (html-audi/html-video/Youtube/Vimeo/SoundCloud/Wistia) in the grid 1243 // ====================================================== 1244 1245 var tg_media_init = 'tg-media-init', 1246 tg_media_hold = '.tg-item', 1247 ie = (function() { // ie version detection 1248 var v = 3, 1249 div = document.createElement('div'), 1250 all = div.getElementsByTagName('i'); 1251 do {div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->';} 1252 while (all[0]); 1253 return v > 4 ? v : document.documentMode; 1254 }()); 1255 1256 if (ie) { 1257 $('body').addClass('is-ie'); 1258 } 1259 1260 // SoundCloud players (API) 1261 $.fn.TG_SoundCloud = function() { 1262 1263 return this.each(function () { 1264 1265 var $this = $(this).closest(tg_media_hold), 1266 src = $(this).attr('src'); 1267 1268 if (!$this.hasClass(tg_media_init) && src !== 'about:blank') { 1269 1270 var player = SC.Widget($(this).attr('id')); 1271 1272 player.bind(SC.Widget.Events.READY, function() { 1273 1274 if ((!player.getCurrentSound && tg_is_mobile) || !tg_is_mobile) { 1275 player.play(); 1276 } 1277 1278 $.TG_Media_Ready($this,player,'STD'); 1279 1280 /*player.bind(SC.Widget.Events.PLAY,function() { 1281 //$.TG_Media_Play($this); 1282 });*/ 1283 1284 player.bind(SC.Widget.Events.PAUSE,function() { 1285 $.TG_Media_Pause($this); 1286 });
1287 1288 player.bind(SC.Widget.Events.FINISH,function() { 1289 $.TG_Media_Pause($this); 1290 }); 1291 1292 }); 1293 1294 } 1295 1296 }); 1297 1298 }; 1299 1300 //object to hold all players on the page 1301 var TG_YT_players = {}; 1302 // Youtube players (API) 1303 $.fn.TG_Youtube = function() { 1304 1305 return this.each(function () { 1306 1307 var $this = $(this).closest(tg_media_hold), 1308 src = $(this).attr('src'); 1309 1310 if (!$this.hasClass(tg_media_init) && src !== 'about:blank') { 1311 1312 var playerID = this.id; 1313 1314 TG_YT_players[playerID] = new YT.Player(playerID, { 1315 events: { 1316 'onReady':function(event){ 1317 if (!tg_is_mobile) { 1318 event.target.playVideo(); 1319 } 1320 $.TG_Media_Ready($this,event.target,'YT'); 1321 }, 1322 'onStateChange': function(event){ 1323 if (event.data === 1) { 1324 $.TG_Media_Play($this); 1325 } 1326 if (event.data === 2 || event.data === 0) { 1327 $.TG_Media_Pause($this); 1328 } 1329 } 1330 } 1331 }); 1332 1333 } 1334 1335 }); 1336 1337 }; 1338 1339 // Vimeo players (API) 1340 $.fn.TG_Vimeo = function() { 1341 1342 return this.each(function () { 1343 1344 var $this = $(this).closest(tg_media_hold), 1345 src = $(this).attr('src'); 1346 1347 // Vimeo not supported with IE <= 9, so remove iframe & play button 1348 if (ie <= 9) { 1349 $(this).remove(); 1350 $this.find('.tg-media-button').remove(); 1351 } 1352 1353 if (!$this.hasClass(tg_media_init) && src !== 'about:blank') { 1354 1355 // reset the src of the iframe because of a cache issue from VIMEO API 1356 $(this).attr('src', $(this).attr('src')); 1357 1358 var player = $f(this); 1359 1360 player.addEvent('ready', function() { 1361 if (!tg_is_mobile) { 1362 player.api('play'); 1363 } 1364 $.TG_Media_Ready($this,player,'VM'); 1365 player.addEvent('play', function(){ 1366 $.TG_Media_Play($this); 1367 }); 1368 player.addEvent('pause', function(){ 1369 $.TG_Media_Pause($this); 1370 }); 1371 player.addEvent('finish', function(){ 1372 $.TG_Media_Pause($this); 1373 }); 1374 }); 1375 1376 /*$(this).attr('src', $(this).attr('src')); 1377 var player = new Vimeo.Player($(this)); 1378 1379 player.play(); 1380 $.TG_Media_Ready($this,player,'STD'); 1381 player.on('play', function(){ 1382 $.TG_Media_Play($this); 1383 }); 1384 player.on('pause', function(){ 1385 $.TG_Media_Pause($this); 1386 }); 1387 player.on('finish', function(){ 1388 $.TG_Media_Pause($this); 1389 });*/ 1390 1391 } 1392 1393 }); 1394 }; 1395 1396 // Wistia players (API) 1397 $.fn.TG_Wistia = function() { 1398 1399 return this.each(function () { 1400 1401 var $this = $(this).closest(tg_media_hold), 1402 src = $(this).attr('src'); 1403 1404 if (!$this.hasClass(tg_media_init) && src !== 'about:blank') { 1405 1406 $(this).load(function() { 1407 1408 var player = $(this)[0].wistiaApi, 1409 is_init = false, 1410 seeking = false, 1411 heightchange = false; 1412 1413 1414 $.TG_Media_Ready($this,player,'STD'); 1415 1416 // prevent issue with Visual Composer on Front-End mode 1417 if (player) { 1418 1419 player.play(); 1420 1421 player.bind('seek', function () { 1422 seeking = true; 1423 }); 1424 1425 player.bind('heightchange', function () { 1426 heightchange = true; 1427 }); 1428 1429 player.bind('play', function () { 1430 // because of play trigger by seek... 1431 if (seeking === false && heightchange === false && is_init) { 1432 $.TG_Media_Play($this); 1433 } 1434 seeking = heightchange = false; 1435 }); 1436 1437 player.bind('pause', function () { 1438 // because of pause trigger by seek... 1439 if (seeking === false && heightchange === false) { 1440 $.TG_Media_Pause($this); 1441 } 1442 heightchange = is_init = true; 1443 }); 1444 1445 player.bind('finish', function () { 1446 $.TG_Media_Pause($this); 1447 }); 1448 1449 } 1450 1451 }); 1452 1453 } 1454 1455 }); 1456 }; 1457 1458 // HTML5 video/audio players 1459 $.fn.TG_HTML_Player = function() { 1460 1461 return this.each(function () { 1462 1463 var $this = $(this).closest(tg_media_hold); 1464 1465 if (!$this.hasClass(tg_media_init)) { 1466 1467 var player = $(this)[0]; 1468 1469 if (player.addEventListener) { 1470 $.TG_Media_Ready($this,player,'STD'); 1471 player.addEventListener('play', function(){ 1472 $.TG_Media_Play($this); 1473 });
1474 player.addEventListener('pause', function(){ 1475 $.TG_Media_Pause($this); 1476 }); 1477 player.addEventListener('ended', function(){ 1478 $.TG_Media_Pause($this); 1479 }); 1480 } 1481 } 1482 1483 }); 1484 1485 }; 1486 1487 // Set player on ready 1488 $.TG_Media_Ready = function(el,player,method) { 1489 el.data('pause-method',method) 1490 .data('media-player',player) 1491 .addClass(tg_media_init); 1492 }; 1493 1494 // handle Play on player 1495 $.TG_Media_Play = function(el) { 1496 if (!el.hasClass('tg-force-play')) { 1497 $.TG_Pause_Players(); 1498 } 1499 el.addClass('tg-is-playing'); 1500 $(tg_media_hold).removeClass('tg-force-play'); 1501 }; 1502 1503 // handle Pause on player 1504 $.TG_Media_Pause = function(el) { 1505 el.removeClass('tg-is-playing tg-force-play'); 1506 }; 1507 1508 // detect fullscreen player mode (prevent to add undesired css transform) 1509 $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange',function(e){ 1510 var el = $(e.target); 1511 $('.tg-item-media').removeClass('tg-item-media-fullscreen'); 1512 if (el && el.hasClass('tg-item-media')) { 1513 el.addClass('tg-item-media-fullscreen'); 1514 } 1515 }); 1516 1517 // on first play build iframe and init script 1518 $(document).on('click', '.tg-item:not(.tg-media-init) .tg-item-button-play', function(e) { 1519 1520 e.preventDefault(); 1521 1522 var $this = $(this).closest('.tg-item'), 1523 $media = $this.find('iframe'); 1524 1525 $media.attr('src', $media.data('src')); 1526 $.TG_Pause_Players(); 1527 $.TG_media_init(); 1528 $this.addClass('tg-force-play'); 1529 1530 }); 1531 1532 // Play button 1533 $(document).on('click', '.tg-item.tg-media-init .tg-item-button-play', function(e) { 1534 1535 e.preventDefault(); 1536 1537 var $this = $(this).closest('.tg-item'), 1538 method = $this.data('pause-method'), 1539 player = $this.data('media-player'); 1540 1541 // pause and return if media is playing 1542 if ($this.is('.tg-force-play, .tg-is-playing')){ 1543 $.TG_Pause_Players(); 1544 return false; 1545 } 1546 1547 // check if player & init, and play 1548 if (player && $this.hasClass(tg_media_init)) { 1549 $this.find('.tg-item-media').show(); 1550 $.TG_Pause_Players(); 1551 $(tg_media_hold).removeClass('tg-force-play tg-play-error'); 1552 $this.addClass('tg-force-play'); 1553 switch(method) { 1554 case 'STD': 1555 // prevent auto play SoundCloud on mobile (force manual play to work) 1556 if ((!player.getCurrentSound && tg_is_mobile) || !tg_is_mobile) { 1557 player.play(); 1558 } 1559 break; 1560 case 'YT': 1561 player.playVideo(); 1562 break; 1563 case 'VM': 1564 player.api('play'); 1565 break; 1566 } 1567 } 1568 1569 }); 1570 1571 // Pause all kind of video/audio media 1572 $.TG_Pause_Players = function() { 1573 1574 $('.tg-item.tg-is-playing, .tg-item.tg-force-play').each(function() { 1575 var $this = $(this), 1576 method = $this.data('pause-method'), 1577 player = $this.data('media-player'); 1578 if (player && $this.hasClass(tg_media_init)) { 1579 switch(method) { 1580 case 'STD': 1581 player.pause(); 1582 break; 1583 case 'YT': 1584 player.pauseVideo(); 1585 break; 1586 case 'VM': 1587 player.api('pause'); 1588 break; 1589 } 1590 $this.closest(tg_media_hold).removeClass('tg-is-playing tg-force-play'); 1591 } 1592 }); 1593 }; 1594 1595 // API scripts (Youtube, Vimeo, Soundclound) 1596 $.TG_media_init = function() { 1597 1598 var tag, 1599 API, 1600 url, 1601 type, 1602 script, 1603 scripts = [ 1604 {'ID':'youtube', 'url':'//www.youtube.com/iframe_api'}, 1605 {'ID':'vimeo', 'url':'//f.vimeocdn.com/js/froogaloop2.min.js'}, 1606 {'ID':'soundcloud', 'url':'//w.soundcloud.com/player/api.js'}, 1607 {'ID':'wistia', 'url':'//fast.wistia.com/assets/external/E-v1.js'} 1608 ]; 1609 1610 // load Youtube subscribe button script 1611 if ($('.g-ytsubscribe').length) { 1612 tag = document.createElement('script'); 1613 tag.src = 'https://apis.google.com/js/platform.js'; 1614 tag.id = 'tg-youtube-subscribe-api'; 1615 script = document.getElementsByTagName('script')[0]; 1616 script.parentNode.insertBefore(tag, script); 1617 } 1618 1619 if ($('.tg-item-media').length === 0) { 1620 return false; 1621 } 1622 1623 API = { 1624 youtube: function () { 1625 // because of futur ajax events 1626 if (typeof YT == 'undefined' || YT.loaded === 0) { 1627 window.onYouTubeIframeAPIReady = function() { 1628 $('[data-api="1"].tg-item-youtube').TG_Youtube(); 1629 }; 1630 } else { 1631 $('[data-api="1"].tg-item-youtube').TG_Youtube(); 1632 } 1633 }, 1634 vimeo: function() { 1635 $('[data-api="1"].tg-item-vimeo').TG_Vimeo(); 1636 }, 1637 soundcloud: function() { 1638 $('[data-api="1"].tg-item-soundcloud').TG_SoundCloud(); 1639 }, 1640 wistia: function() { 1641 $('[data-api="1"].tg-item-wistia').TG_Wistia(); 1642 } 1643 }; 1644 1645 /* jshint loopfunc:true */ 1646 // autoload API scripts (only when necessary) 1647 for (var i = 0; i < scripts.length; i++) { 1648 type = scripts[i].ID; 1649 if ($('[data-api="1"].tg-item-'+type).length > 0) { 1650 url = scripts[i].url; 1651 if ($('#tg-'+type+'-api').length === 0) { 1652 tag = document.createElement('script'); 1653 tag.src = scripts[i].url; 1654 tag.id = 'tg-'+type+'-api'; 1655 script = document.getElementsByTagName('script')[0]; 1656 script.parentNode.insertBefore(tag, script); 1657 (function(tag,type){ 1658 tag.onload = function() { 1659 API[type](); 1660 }; 1661 })(tag,type); 1662 } else { 1663 API[type](); 1664 } 1665 } 1666 } 1667 1668 // HTML5 Player events 1669 $(document).ready(function() { 1670 $('.tg-item .tg-item-audio-player').attr('width','100%'); 1671 $('.tg-item-video-player,.tg-item-audio-player').TG_HTML_Player(); 1672 if (tg_global_var.mediaelement) { 1673 $('.tg-item-video-player:not(.tg-mediaelement-init), .tg-item-audio-player:not(.tg-mediaelement-init)').mediaelementplayer({ 1674 audioVolume: 'vertical', 1675 videoVolume: 'vertical', 1676 features: ['playpause', 'current', 'progress', 'fullscreen', 'volume', 'duration'], 1677 startVolume: 0.8 1678 }); 1679 $('.tg-item-video-player, .tg-item-audio-player').addClass('tg-mediaelement-init'); 1680 } 1681 }); 1682 1683 }; 1684 1685 // destroy all video/audio players 1686 $.TG_media_destroy = function(el) { 1687 1688 var vimeo = (el) ? el : $('.tg-item'); 1689 // destroy Vimeo, needed for IE 1690 vimeo.find('.tg-item-vimeo').each(function() { 1691 var $this = $(this), 1692 player = $this.closest(tg_media_hold).data('media-player'); 1693 if (player) { 1694 player.api('pause'); 1695 $this.attr('src','about:blank'); 1696 } 1697 }); 1698 1699 el = (el) ? el.find('.tg-item video, .tg-item audio') : $('.tg-item video, .tg-item audio'); 1700 // destroy media player 1701 el.each(function() { 1702 1703 var $media = $(this), 1704 player = $media.data('mediaelementplayer'); 1705 1706 $media.closest(tg_media_hold).removeClass('tg-force-play tg-is-playing'); 1707 1708 if ($media.length) { 1709 if (player) { 1710 player = $media.data('mediaelementplayer'); 1711 player.pause(); 1712 player.setSrc('about:blank'); 1713 $media.children('source').prop('src', ''); 1714 player.remove(); 1715 } else { 1716 $media[0].pause(); 1717 $media[0].src = 'about:blank'; 1718 $media.children('source').prop('src', ''); 1719 $media.remove().length = 0; 1720 } 1721 } 1722 1723 }); 1724 1725 // delete all instances of mediaelement.js 1726 if (tg_global_var.mediaelement) { 1727 mejs.players = []; 1728 } 1729 1730 }; 1731 1732 // ====================================================== 1733 // Themeone Lightbox (image/video) 1734 // ====================================================== 1735 1736 $.TO_Lightbox = function() { 1737
1738 var TO_LB_Markup = '<div class="tolb-holder">'+ 1739 '<div class="tolb-loader"></div>'+ 1740 '<div class="tolb-inner">'+ 1741 '<figure>'+ 1742 '<div class="tolb-close tg-icon-close"></div>'+ 1743 '<div class="tolb-content"></div>'+ 1744 '<figcaption>'+ 1745 '<div class="tolb-title"></div>'+ 1746 '<div class="tolb-counter"></div>'+ 1747 '</figcaption>'+ 1748 '</figure>'+ 1749 '</div>'+ 1750 '<div class="tolb-prev"><i class="tg-icon-arrow-prev-thin"></i></div>'+ 1751 '<div class="tolb-next"><i class="tg-icon-arrow-next-thin"></i></div>'+ 1752 '</div>', 1753 func, 1754 player, 1755 media_id, 1756 media_lb, 1757 media_src, 1758 media_alt, 1759 media_html, 1760 media_type, 1761 media_poster, 1762 media_length, 1763 media_arr = [], 1764 media_data = '[data-tolb-src]:not(.tolb-disabled)', 1765 holder = '.tolb-holder', 1766 inner = '.tolb-inner', 1767 content = '.tolb-content', 1768 video = '.tolb-video', 1769 image = '.tolb-img', 1770 title = '.tolb-title', 1771 counter = '.tolb-counter', 1772 next = '.tolb-next', 1773 prev = '.tolb-prev', 1774 close = '.tolb-close', 1775 index = 'tolb-index', 1776 open = 'tolb-open', 1777 ready = 'tolb-ready', 1778 loading = 'tolb-loading', 1779 iframe = 'tolb-iframe', 1780 autoplay = tg_global_var.lightbox_autoplay; 1781 1782 function checkLightbox() { 1783 var $media_data = $(media_data).filter(':visible'); 1784 media_length = $media_data.length; 1785 for (i = 0; i < media_length; i++) { 1786 var el = $media_data.eq(i); 1787 media_arr[i] = {}; 1788 media_arr[i].type = el.data('tolb-type'); 1789 media_arr[i].src = el.data('tolb-src'); 1790 media_arr[i].alt = el.data('tolb-alt'); 1791 media_arr[i].poster = el.data('tolb-poster'); 1792 el.data(index,i); 1793 } 1794 if (media_length > 1) { 1795 $(next+','+prev).show(); 1796 } else { 1797 $(next+','+prev).hide(); 1798 } 1799 } 1800 1801 function getMedia(el) { 1802 $(holder).addClass(open+' '+loading); 1803 media_id = el.data(index); 1804 media_type = media_arr[media_id].type; 1805 media_src = media_arr[media_id].src; 1806 media_alt = media_arr[media_id].alt; 1807 updateIndex(); 1808 switch(media_type) { 1809 case 'image': 1810 media_html = $('<img class="tolb-img" src="'+media_src+'" alt="'+media_alt+'"></img>'); 1811 media_lb = new Image(); 1812 media_lb.onload = load_image; 1813 media_lb.onerror = load_image; 1814 media_lb.src = media_src; 1815 break; 1816 case 'youtube': 1817 media_src = '//www.youtube.com/embed/'+media_src+'?html5=1&controls=1&autohide=1&rel=0&showinfo=0&autoplay='+autoplay; 1818 media_html = $('<iframe class="tolb-video" src="'+media_src+'" allowfullscreen></iframe>'); 1819 load_iframe(); 1820 break; 1821 case 'vimeo': 1822 media_src = '//player.vimeo.com/video/'+media_src+'?title=0&byline=0&portrait=0&autoplay='+autoplay; 1823 media_html = $('<iframe class="tolb-video" src="'+media_src+'" allowfullscreen></iframe>'); 1824 load_iframe(); 1825 break; 1826 case 'wistia': 1827 media_src = '//fast.wistia.net/embed/iframe/'+media_src+'?title=0&byline=0&portrait=0&autoPlay='+autoplay; 1828 media_html = $('<iframe class="tolb-video" src="'+media_src+'" allowfullscreen></iframe>'); 1829 load_iframe(); 1830 break; 1831 case 'video': 1832 var source = ''; 1833 for(var i=0; i<media_src.length ;i++){ 1834 source += '<source src="'+media_src[i][0].source+'" type="video/'+media_src[i][0].type+'" width="100%" height="100%"></source>'; 1835 } 1836 media_poster = media_arr[media_id].poster; 1837 media_poster = (media_poster) ? ' poster="'+media_poster+'"' : ''; 1838 var attribute = (autoplay) ? ' autoplay' : ''; 1839 media_html = $('<video class="tolb-video" controls'+media_poster+attribute+'>'+source+'</video>'); 1840 load_video(); 1841 break; 1842 } 1843 } 1844 1845 function unloadMedia() { 1846 var iframe = $(holder).find('iframe').not(media_html); 1847 if (iframe.length > 0) { 1848 iframe.attr('src','about:blank').one('load',function(){ 1849 appendMedia(); 1850 }); 1851 } else { 1852 appendMedia(); 1853 } 1854 } 1855 1856 function appendMedia() { 1857 $(holder).addClass(ready);
1858 func = (media_type !== 'iframe') ? $(content).html('') : $(content).find('*').not(media_html).remove(); 1859 func = (media_type !== 'image') ? $(holder).addClass(iframe) : $(holder).removeClass(iframe); 1860 func = (media_type !== 'iframe') && $(content).append(media_html); 1861 maxHeight(); 1862 updateCaption(); 1863 media_html.show(); 1864 $(holder).removeClass(loading); 1865 } 1866 1867 function load_image() { 1868 unloadMedia(); 1869 } 1870 1871 function load_video() { 1872 if (!tg_is_mobile) { 1873 media_html.one('loadeddata',function() { 1874 func = (player) && player.setSrc('about:blank'); 1875 if (tg_global_var.mediaelement) { 1876 mediaelement(); 1877 } else { 1878 unloadMedia(); 1879 } 1880 }); 1881 media_html[0].addEventListener('error', function(){ 1882 updateCaption(); 1883 $(holder).removeClass(loading); 1884 }); 1885 } else { 1886 func = (player) && player.setSrc('about:blank'); 1887 unloadMedia(); 1888 } 1889 } 1890 1891 function load_iframe() { 1892 media_type = 'iframe'; 1893 $(content).append(media_html.hide()); 1894 media_html.one('load',function (){ 1895 unloadMedia(); 1896 }); 1897 } 1898 1899 function mediaelement() { 1900 media_html.mediaelementplayer({ 1901 features: ['playpause', 'stop', 'loop', 'current', 'progress', 'duration', 'volume', 'sourcechooser', 'fullscreen'], 1902 videoVolume: 'horizontal', 1903 startVolume: 0.8, 1904 success: function(media, domObject) { 1905 player = media; 1906 media_html = $(domObject).closest('.mejs-container'); 1907 unloadMedia(); 1908 player.addEventListener('ended', function(){ 1909 media_html.find('.mejs-poster').show(); 1910 }); 1911 } 1912 }); 1913 } 1914 1915 function maxHeight() { 1916 $(image).css('max-height',$(window).height()-80-$('#wpadminbar').height()); 1917 } 1918 1919 function updateCaption() { 1920 $(title).text(media_alt); 1921 $(counter).text(media_id+1+'/'+media_length); 1922 } 1923 1924 function updateIndex() { 1925 $(prev).data(index,checkIndex(media_id-1)); 1926 $(next).data(index,checkIndex(media_id+1)); 1927 } 1928 1929 function checkIndex(media_id) { 1930 return (media_length + (media_id % media_length)) % media_length; 1931 } 1932 1933 function close_lightbox() { 1934 $(holder).removeClass(open+' '+loading+' '+ready); 1935 setTimeout(function(){ 1936 if ($(holder).find('iframe').length > 0) { 1937 $(holder).find('iframe').attr('src','about:blank').one('load', function(){ 1938 $(content).html(''); 1939 }); 1940 } else { 1941 $(content).html(''); 1942 } 1943 }, 300); 1944 } 1945 1946 $(window).on('resize', function(){ 1947 maxHeight(); 1948 }); 1949 1950 $(document).on('click', media_data, function(e) { 1951 e.preventDefault(); 1952 $.TG_Pause_Players(); 1953 $(video+','+image).remove(); 1954 checkLightbox(); 1955 getMedia($(this)); 1956 return false; 1957 }); 1958 1959 $(document).on('click touchend',next+','+prev, function() { 1960 getMedia($(this)); 1961 return false; 1962 }); 1963 1964 $(document).on('keydown', throttle(function(e) { 1965 if ($(holder).hasClass(open)) { 1966 if (e.keyCode == 37) { 1967 $(prev).trigger('click'); 1968 } else if(e.keyCode == 39) { 1969 $(next).trigger('click'); 1970 } else if(e.keyCode == 27) { 1971 close_lightbox(); 1972 } 1973 } 1974 },300)); 1975 1976 $(document).on('click touchend',inner+','+close, function(e) { 1977 e.stopPropagation(); 1978 if ($(e.target).is(inner) || $(e.target).is(close)) { 1979 close_lightbox(); 1980 } 1981 return false; 1982 }); 1983 1984 $('body').append($(TO_LB_Markup)); 1985 1986 }; 1987 1988 // auto click lightbox (prevent duplicate content) 1989 $(document).on('click', '[data-tolb-id]', function(e) { 1990 e.preventDefault(); 1991 var id = $(this).data('tolb-id'); 1992 if (id) { 1993 $('#'+id).trigger('click'); 1994 } 1995 }); 1996 1997 // ====================================================== 1998 // Custom panZoom/Apple TV Effects 1999 // ====================================================== 2000 2001 function TG_PanZoom(){ 2002 2003 var el,offset,h,w,x,y, 2004 edge = window.navigator.userAgent.indexOf('Edge/'), 2005 supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints, 2006 image = 'div:not(.tg-item-gallery-holder) > .tg-item-image, .tg-item-media-poster, .tg-item-audio-poster, .tg-item-gallery-holder', 2007 sensitivity = 0.4, 2008 lastMove = 0; 2009 2010 if (!supportsTouch && !$('body').hasClass('is-ie') && edge < 0) { 2011 2012 $(document).on('mousemove', '.tg-panZ', function(e){
2013 el = $(this); 2014 w = el.width(); 2015 h = el.height(); 2016 offset = el.closest('.tg-item').offset(); 2017 var now = Date.now(); 2018 if (now > lastMove + 80) { 2019 lastMove = now; 2020 window.requestAnimationFrame(function(){ 2021 x = -(e.pageX - offset.left-w/2)*0.08*sensitivity; 2022 y = -(e.pageY - offset.top-h/2)*0.08*sensitivity; 2023 $(e.target).closest('.tg-item').find(image).css({ 2024 '-webkit-transform': 'matrix(1.08, 0, 0, 1.08,'+x+','+y+')', 2025 '-moz-transform': 'matrix(1.08, 0, 0, 1.08,'+x+','+y+')' 2026 }); 2027 }); 2028 } 2029 }).on('mouseleave', '.tg-panZ', function(e){ 2030 setTimeout(function(){ 2031 $(e.target).closest('.tg-item').find(image).css({ 2032 '-webkit-transform':'', 2033 '-moz-transform':'' 2034 }); 2035 }, 80); 2036 }); 2037 2038 } 2039 2040 } 2041 // Init PanZoom effect 2042 TG_PanZoom(); 2043 2044 2045 // Apple Tv effect 2046 function TG_atv(){ 2047 2048 var d = document, 2049 lastMove = 0, 2050 htm = d.getElementsByTagName('html')[0], 2051 bd = d.getElementsByTagName('body')[0], 2052 supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints, 2053 eventThrottle = $('body').hasClass('is-ie') ? 1 : 80; 2054 2055 if (!supportsTouch) { 2056 $(document).on('mousemove', '.tg-atv-anim', function(e){ 2057 var holder = $(this), 2058 now = Date.now(); 2059 if (now > lastMove + eventThrottle) { 2060 lastMove = now; 2061 window.requestAnimationFrame(function(){ 2062 processMovement(e,holder); 2063 }); 2064 } 2065 }).on('mouseenter', '.tg-atv-anim', function(e){ 2066 processEnter($(this)); 2067 }).on('mouseleave', '.tg-atv-anim', function(e){ 2068 processExit($(this)); 2069 }); 2070 } 2071 2072 function processMovement(e, layers){ 2073 2074 var bdst = bd.scrollTop || htm.scrollTop, 2075 bdsl = bd.scrollLeft, 2076 pageX = e.pageX, 2077 pageY = e.pageY, 2078 offsets = layers[0].getBoundingClientRect(), 2079 w = layers[0].clientWidth || layers[0].offsetWidth || layers[0].scrollWidth, 2080 h = layers[0].clientHeight || layers[0].offsetHeight || layers[0].scrollHeight, 2081 wMultiple = 320/w, 2082 offsetX = 0.52 - (pageX - offsets.left - bdsl)/w, 2083 offsetY = 0.52 - (pageY - offsets.top - bdst)/h, 2084 dy = (pageY - offsets.top - bdst) - h / 2, 2085 dx = (pageX - offsets.left - bdsl) - w / 2, 2086 yRotate = (offsetX - dx)*(0.07 * wMultiple), 2087 xRotate = (dy - offsetY)*(0.1 * wMultiple), 2088 ratio = (h > w) ? h/w*2 : 1, 2089 perspective = w*3*ratio, 2090 imgCSS = 'perspective('+ perspective +'px) rotateX(' + xRotate + 'deg) rotateY(' + yRotate + 'deg)
2090scale3d(1.03,1.03,1.03)'; 2091 2092 layers.css('transform',imgCSS + ' ' + 'translateX(' + (offsetX * 2) * ((1 * 2.5) / wMultiple) + 'px) translateY(' + (offsetY * 1) * ((1 * 2.5) / wMultiple) + 'px)'); 2093 2094 } 2095 2096 function processEnter(elem){ 2097 elem.addClass('over'); 2098 } 2099 2100 function processExit(elem){ 2101 elem.removeClass('over'); 2102 setTimeout(function(){ 2103 var w = elem[0].clientWidth || elem[0].offsetWidth || elem[0].scrollWidth; 2104 elem.css('transform','perspective('+ w*3 +'px) rotateX(0deg) rotateY(0deg) translateZ(0)'); 2105 }, 80); 2106 } 2107 2108 } 2109 // Init Apple TV parallax effect 2110 TG_atv(); 2111 2112 // ====================================================== 2113 // Social share links 2114 // ====================================================== 2115 2116 $(document).on('click', '.tg-social-share:not(.tg-social-disabled)', function(e){ 2117 2118 e.preventDefault(); 2119 2120 var href = $(this)[0].href, 2121 left = Math.round(window.screenX + (window.outerWidth - 626) / 2), 2122 top = Math.round(window.screenY + (window.outerHeight - 436) / 2); 2123 2124 if (href) { 2125 window.open(href, 'tg_share', 'status=0,resizable=1,location=1,toolbar=0,width=626,height=436,top='+top+',left='+left); 2126 } 2127 2128 return false; 2129 2130 }); 2131 2132 // ====================================================== 2133 // Init The Grid Plugin 2134 // ====================================================== 2135 2136 $.TG_media_init(); 2137 // Initializing 2138 $(document).ready(function() { 2139 // because of @keyframe and @font-face issue in Firefox 2140 $('.tg-grid-preloader-styles, .tg-grid-styles').removeAttr('scoped'); 2141 $('.tg-grid-holder').The_Grid(); 2142 $.TO_Lightbox(); 2143 }); 2144 2145 2146 // ====================================================== 2147 // Helpers 2148 // ====================================================== 2149 2150 // debounced resize 2151 var $event = $.event, 2152 $special, 2153 func, 2154 resizeTimeout; 2155 2156 $special = $event.special.debouncedresize = { 2157 setup: function() { 2158 $(this).on( "resize", $special.handler ); 2159 }, 2160 teardown: function() { 2161 $(this).off( "resize", $special.handler ); 2162 }, 2163 handler: function( event, execAsap ) { 2164 // Save the context 2165 var context = this, 2166 args = arguments, 2167 dispatch = function() { 2168 // set correct event type 2169 event.type = "debouncedresize"; 2170 $event.dispatch.apply( context, args ); 2171 }; 2172 2173 if ( resizeTimeout ) { 2174 clearTimeout( resizeTimeout ); 2175 } 2176 2177 func = execAsap ? dispatch() : resizeTimeout = setTimeout( dispatch, $special.threshold ); 2178 }, 2179 threshold: 100 2180 }; 2181 2182})(jQuery); 2183 2184// throttle function to reduce calculations 2185function throttle(func, milliseconds) { 2186 var lastCall = 0; 2187 return function () { 2188 var now = Date.now(); 2189 if (lastCall + milliseconds < now) { 2190 lastCall = now; 2191 return func.apply(this, arguments); 2192 } 2193 }; 2194} 2195 2196// debounce so filtering doesn't happen every millisecond 2197function debounce(fn, threshold) { 2198 2199 "use strict"; 2200 2201 var timeout; 2202 2203 return function debounced() { 2204 if (timeout) { 2205 clearTimeout(timeout); 2206 } 2207 function delayed() { 2208 fn(); 2209 timeout = null; 2210 } 2211 setTimeout(delayed, threshold || 100); 2212 }; 2213} 2214 2215//RAF polyfill (http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/) 2216(function() { 2217 var lastTime = 0; 2218 var vendors = ['webkit', 'moz']; 2219 for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 2220 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; 2221 window.cancelAnimationFrame = 2222 window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; 2223 } 2224 2225 if (!window.requestAnimationFrame) 2226 window.requestAnimationFrame = function(callback, element) { 2227 var currTime = new Date().getTime(); 2228 var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 2229 var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 2230 timeToCall); 2231 lastTime = currTime + timeToCall; 2232 return id; 2233 }; 2234 2235 if (!window.cancelAnimationFrame) 2236 window.cancelAnimationFrame = function(id) { 2237 clearTimeout(id); 2238 }; 2239}()); 2240 2241// RAF interval for smooth animations 2242window.tgInterval = function(a, b) { 2243 var c = Date.now, 2244 d = window.requestAnimationFrame, 2245 e = c(), 2246 f, g = function() { 2247 c() - e < b || (e += b, a()); 2248 f || d(g); 2249 }; 2250 d(g); 2251 return { 2252 clear: function() { 2253 f = 1; 2254 } 2255 }; 2256};
2257 2258/* jshint ignore:start */ 2259if (tg_global_var.mediaelement_ex) { 2260// mediaelement extended for loop and source button (The Grid lightbox only) 2261// Loop: http://mediaelementjs.com/examples/?name=loop 2262// source chooser: https://github.com/johndyer/mediaelement/blob/master/src/js/mep-feature-sourcechooser.js 2263!function(e){e.extend(mejs.MepDefaults,{sourcechooserText:"Source Chooser"}),e.extend(MediaElementPlayer.prototype,{buildsourcechooser:function(o,t,s,c){var r=this;o.sourcechooserButton=e('<div class="mejs-button mejs-sourcechooser-button"><button type="button" aria-controls="'+r.id+'" title="'+r.options.sourcechooserText+'" aria-label="'+r.options.sourcechooserText+'"></button><div class="mejs-sourcechooser-selector"><ul></ul></div></div>').appendTo(t).delegate("input[type=checkbox]","click",function(){var o=this.value;e(this).closest(".mejs-sourcechooser-selector").find("input").removeAttr("checked"),e(this).closest(".mejs-sourcechooser-selector").find("label").removeClass("active"),e(this).next("label").addClass("active"),c.currentSrc!=o&&(currentTime=c.currentTime,paused=c.paused,c.setSrc(o),c.load(),c.addEventListener("loadedmetadata",function(){this.currentTime=currentTime},!0),c.addEventListener("canplay",function(){paused||this.play()},!0))});for(var n in c.children){var i=c.children[n];"SOURCE"!==i.nodeName||"probably"!=c.canPlayType(i.type)&&"maybe"!=c.canPlayType(i.type)||o.addSourceButton(i.src,i.title,i.type,c.src==i.src)}},addSourceButton:function(o,t,s,c){var r=this;(""===t||void 0==t)&&(t=o),s=s.split("/")[1],r.sourcechooserButton.find("ul").append(e('<li><input type="checkbox" name="'+r.id+'_sourcechooser" id="'+r.id+"_sourcechooser_"+s+'" value="'+o+'" '+(c?'checked="checked"':"")+' /><label for="'+r.id+"_sourcechooser_"+s+'">'+s+"</label></li>")),r.adjustSourcechooserBox()},adjustSourcechooserBox:function(){var e=this;e.sourcechooserButton.find(".mejs-sourcechooser-selector").height(e.sourcechooserButton.find(".mejs-sourcechooser-selector ul").outerHeight(!0))}})}(mejs.$),function(e){e.extend(MediaElementPlayer.prototype,{buildloop:function(o,t){var s=this,c=e('<div class="mejs-button mejs-loop-button '+(o.options.loop?"mejs-loop-on":"mejs-loop-off")+'"><button type="button" aria-controls="'+s.id+'" title="Toggle Loop" aria-label="Toggle Loop"></button></div>').appendTo(t).click(function(){o.options.loop=!o.options.loop,o.options.loop?c.removeClass("mejs-loop-off").addClass("mejs-loop-on"):c.removeClass("mejs-loop-on").addClass("mejs-loop-off")})}})}(mejs.$); 2264 2265} 2266/* jshint ignore:end */
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.