1/* 2* scotchPanels - v1.0.3 - 2014-09-25 3* https://github.com/scotch-io/scotch-panels 4* Copyright (c) 2014 Nicholas Cerminara <[email protected]> 5*/ 6// Start with Semicolon to block 7;(function($) { 8 9 // Enable Strict Mode 10 'use strict'; 11 12 // Create Panels Array 13 var panels = []; 14 15 // Has done CSS3 browser support check? 16 var browserSupportTest = false; 17 var has3d = false; 18 var hasTransitions = false; 19 20 // Plugin Default Settings 21 var defaults = { 22 23 // General Config 24 containerSelector: 'body', 25 type: 'html', // html, iframe, video, image 26 27 // Styles 28 direction: 'top', // top, left, right, bottom 29 duration: 300, // ms 30 transition: 'ease', // linear, ease, ease-in, ease-out, ease-in-out, cubic-bezier(P1x,P1y,P2x,P2y) 31 32 // Browser Support 33 easingPluginTransition: 'easeInCirc', 34 useCSS: true, // Consider not using if have Fixed Elements 35 useEasingPlugin: false, // http://gsgd.co.uk/sandbox/jquery/easing/ only for browser support 36 37 // Image Options 38 imageURL: false, 39 40 // Iframe Options 41 iframeURL: false, 42 43 // Video Options 44 autoPlayVideo: true, 45 youtubeID: false, 46 youTubeTheme: 'light', 47 48 // TranslateX Options 49 distanceX: '70%', 50 51 // TranslateY Options 52 forceMinHeight: false, 53 minHeight: '200px', 54 55 // Triggers 56 closeAfter: 0, // ms 57 startOpened: false, 58 startOpenedDelay: 0, // ms 59 60 // Event Helpers 61 clickSelector: false, 62 enableEscapeKey: true, 63 hoverSelector: false, 64 touchSelector: false, 65 66 // Callbacks 67 beforePanelOpen: function() {}, 68 afterPanelOpen: function() {}, 69 beforePanelClose: function() {}, 70 afterPanelClose: function() {} 71 }; 72 73 74 $.fn.scotchPanel = function(options) { 75 76 // Check to see if Default Options are Set 77 if (typeof options === 'undefined') { 78 options = {}; 79 } 80 81 // Check to see if an element is even selected 82 if (this.length === 0) return this; 83 84 // Support selecting Panels 85 if (this.length > 1) { 86 87 // Loop through all selected scotch panels 88 this.each(function() { 89 // Add panel to array 90 panels.push($(this).scotchPanel(options)); 91 }); 92 93 // Public Functions Functionality for all at once 94 panels.open = function() { 95 for (var i = 0; i < panels.length; i++) { 96 panels[i].open(); 97 } 98 }; 99 panels.close = function() { 100 for (var i = 0; i < panels.length; i++) { 101 panels[i].close(); 102 } 103 }; 104 panels.toggle = function() { 105 for (var i = 0; i < panels.length; i++) { 106 panels[i].toggle(); 107 } 108 }; 109 110 // Return the Scotch Panels 111 return panels; 112 } 113 114 // Create Current Scotch Panel Object 115 var panel = {}; 116 panel = this; 117 118 119 /*========================================= 120 = PRIVATE FUNCTIONS = 121 =========================================*/ 122 // Prep everything 123 var init = function() { 124 125 // Do CSS3 Check! 126 if (!browserSupportTest) { 127 browserSupportTest = true; 128 has3d = browserSupport.transition(); 129 hasTransitions = browserSupport.translate3d(); 130 } 131 132 // Check for HTML5 data attributes instead 133 for (var key in defaults) { 134 if (defaults.hasOwnProperty(key)) { 135 if (panel.attr('data-'+key.toLowerCase())) { 136 options[key] = panel.data(key.toLowerCase()); 137 } 138 } 139 } 140 141 // Merge Custom Plugin Settings with Default 142 panel.settings = $.extend({}, defaults, options); 143 144 // Start DOM and CSS Modifications 145 setup(); 146 }; 147 148 149 // DOM / CSS Changes / Make Things Happen 150 var setup = function() { 151 152 // Wrap the panel! 153 var container = $(panel.settings.containerSelector); 154 if (!container.hasClass('scotchified')) { 155 container.wrapInner('<div class="scotch-panel-wrapper"><div class="scotch-panel-canvas"></div></div>').addClass('scotchified'); 156 } 157 158 // Scotch Panel Wrapper CSS 159 $('.scotch-panel-wrapper').css({ 160 'position': 'relative', 161 'overflow': 'hidden', 162 'width': '100%' 163 }); 164 // Scotch Panel Canvas CSS 165 $('.scotch-panel-canvas').css({ 166 'position': 'relative', 167 'height': '100%', 168 'width': '100%' 169 }); 170 // Do 3D Stuff separate 171 if (panel.settings.useCSS) { 172 $('.scotch-panel-canvas').css({
173 '-moz-transform': 'translate3d(0, 0, 0)', 174 '-ms-transform': 'translate3d(0, 0, 0)', 175 '-o-transform': 'translate3d(0, 0, 0)', 176 '-webkit-transform': 'translate3d(0, 0, 0)', 177 'transform': 'translate3d(0, 0, 0)', 178 '-moz-backface-visibility': 'hidden', 179 '-ms-backface-visibility': 'hidden', 180 '-o-backface-visibility': 'hidden', 181 '-webkit-backface-visibility': 'hidden', 182 'backface-visibility': 'hidden' 183 }); 184 } 185 186 // Figure out which off canvas style is used (left, top, right) 187 if (panel.settings.direction == 'top') { 188 panel.height = panel.height(); 189 panel.addClass('scotch-panel-top'); 190 191 panel.css({ 192 'bottom': '100%', 193 'left': '0', 194 'width': '100%', 195 'position': 'absolute', 196 'z-index': '888888', 197 'overflow': 'hidden' 198 }); 199 } 200 if (panel.settings.direction == 'bottom') { 201 panel.height = panel.height(); 202 panel.addClass('scotch-panel-bottom'); 203 204 panel.css({ 205 'top': '100%', 206 'left': '0', 207 'width': '100%', 208 'position': 'absolute', 209 'z-index': '888888', 210 'overflow': 'hidden' 211 }); 212 } 213 if (panel.settings.direction == 'left') { 214 panel.addClass('scotch-panel-left'); 215 216 panel.css({ 217 'top': '0', 218 'left': '-' + panel.settings.distanceX, 219 'width': panel.settings.distanceX, 220 'height': '100%', 221 'position': 'absolute', 222 'z-index': '888888', 223 'overflow': 'hidden' 224 }); 225 } 226 if (panel.settings.direction == 'right') { 227 panel.addClass('scotch-panel-right'); 228 229 panel.css({ 230 'top': '0', 231 'right': '-' + panel.settings.distanceX, 232 'width': panel.settings.distanceX, 233 'height': '100%', 234 'position': 'absolute', 235 'z-index': '888888', 236 'overflow': 'hidden' 237 }); 238 } 239 panel.css({ 240 '-moz-backface-visibility': 'hidden', 241 '-ms-backface-visibility': 'hidden', 242 '-o-backface-visibility': 'hidden', 243 '-webkit-backface-visibility': 'hidden', 244 'backface-visibility': 'hidden' 245 }); 246 247 // Photo Logic 248 if (panel.settings.type == 'image' && panel.settings.imageURL) { 249 panel.css({ 250 '-o-background-size': 'cover', 251 '-ms-background-size': 'cover', 252 '-moz-background-size': 'cover', 253 '-webkit-background-size': 'cover', 254 'background-size': 'cover', 255 'background-position': '50% 0', 256 'background-repeat': 'no-repeat', 257 'background-image': 'url('+panel.settings.imageURL+')' 258 }); 259 260 // Update Panel Height if top or bottom 261 if (panel.settings.direction == 'top' || panel.settings.direction == 'bottom') { 262 panel.css('min-height', panel.settings.minHeight); 263 panel.height = $(panel).height(); 264 } 265 } 266 267 // Iframe Logic 268 if (panel.settings.type == 'iframe' && panel.settings.iframeURL) { 269 panel.iframeIsLoaded = false; 270 panel.append('<iframe frameborder="0" style="width: 100%; height: 100%; display: block; position: relative; min-height: '+panel.settings.minHeight+'" allowfullscreen></iframe>'); 271 272 // Update Panel Height if top or bottom 273 if (panel.settings.direction == 'top' || panel.settings.direction == 'bottom') { 274 panel.height = $(panel).height(); 275 } 276 } 277 278 // YouTube Logic 279 if (panel.settings.type == 'video' && panel.settings.youtubeID) { 280 panel.append('<div id="video-id-'+panel.settings.youtubeID+'" style="min-height: '+panel.settings.minHeight+'; display: block !important;"><iframe src="//www.youtube.com/embed/'+panel.settings.youtubeID+'?enablejsapi=1&theme='+panel.settings.youTubeTheme+'" frameborder="0" style="width: 100%; height: 100%; display: block; position: absolute; left: 0; top: 0;" allowfullscreen></iframe></div>'); 281 282 // Update Panel Height if top or bottom 283 if (panel.settings.direction == 'top' || panel.settings.direction == 'bottom') { 284 panel.height = $(panel).height(); 285 } 286 } 287 288 // Apply CSS3 Transitions if modern browser 289 if (has3d && hasTransitions) { 290 applyTransition(panel.settings.transition, panel.settings.duration); 291 } 292 293 // Open on Start? 294 if (panel.settings.startOpened) { 295 setTimeout(function(){ 296 panel.open(); 297 }, panel.settings.startOpenedDelay); 298 } 299 300 // Close after X milliseconds? 301 if (panel.settings.closeAfter != 0) { 302 setTimeout(function(){ 303 panel.close(); 304 }, panel.settings.closeAfter); 305 } 306 }; 307 308 309 // Browser Support Object 310 var browserSupport = { 311 transition: function() { 312 // IE 7 + 8 Sucks 313 if (!window.getComputedStyle) { 314 return false;
315 } 316 317 var b = document.body || document.documentElement, 318 s = b.style, 319 p = 'transition'; 320 321 if (typeof s[p] == 'string') { return true; } 322 323 // Tests for vendor specific prop 324 var v = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms']; 325 p = p.charAt(0).toUpperCase() + p.substr(1); 326 327 for (var i=0; i<v.length; i++) { 328 if (typeof s[v[i] + p] == 'string') { return true; } 329 } 330 331 return false; 332 }, 333 translate3d: function() { 334 // IE 7 + 8 Sucks 335 if (!window.getComputedStyle) { 336 return false; 337 } 338 339 var el, has3d; 340 341 el = document.createElement('p'); 342 el.style['transform'] = 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)'; 343 el.style['margin'] = '0'; 344 document.body.insertBefore(el, document.body.lastChild); 345 has3d = window.getComputedStyle(el).getPropertyValue('transform'); 346 347 if (has3d !== undefined) { 348 return has3d !== 'none'; 349 } else { 350 return false; 351 } 352 } 353 }; 354 355 // Toggle YouTube State (Play / Pause) 356 var toggleVideoState = function(element, state) { 357 var div = document.getElementById(element); 358 var iframe = div.getElementsByTagName('iframe')[0].contentWindow; 359 div.style.display = state == 'hide' ? 'none' : ''; 360 var func = state == 'hide' ? 'pauseVideo' : 'playVideo'; 361 iframe.postMessage('{"event":"command","func":"' + func + '","args":""}','*'); 362 div.style['display'] = 'block'; 363 }; 364 365 // Apply CSS Transitions 366 var applyTransition = function(transition, duration) { 367 panel.parents('.scotch-panel-canvas:first').css({ 368 '-ms-transition': 'all '+duration+'ms '+transition, 369 '-moz-transition': 'all '+duration+'ms '+transition, 370 '-o-transition': 'all '+duration+'ms '+transition, 371 '-webkit-transition': 'all '+duration+'ms '+transition, 372 'transition': 'all '+duration+'ms '+transition 373 }); 374 }; 375 376 // Toggle Translate Y 377 var translateY = function(distanceY) { 378 379 // Auto adapt height if unknown and enabled 380 if (panel.settings.forceMinHeight) { 381 panel.parents('.scotch-panel-canvas:first').css('min-height', distanceY); 382 } 383 384 if (has3d && hasTransitions && panel.settings.useCSS) { 385 386 // Open/Close Before Callbacks (CSS) 387 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 388 panel.settings.beforePanelOpen(); 389 } else { 390 panel.settings.beforePanelClose(); 391 } 392 393 panel.parents('.scotch-panel-canvas:first').css({ 394 '-ms-transform': 'translate3d(0, '+distanceY+'px, 0)', 395 '-moz-transform': 'translate3d(0, '+distanceY+'px, 0)', 396 '-o-transform': 'translate3d(0, '+distanceY+'px, 0)', 397 '-webkit-transform': 'translate3d(0, '+distanceY+'px, 0)', 398 'transform': 'translate3d(0, '+distanceY+'px, 0)' 399 }); 400 401 setTimeout(function(){ 402 403 // Open/Close After Callbacks (CSS) 404 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 405 panel.settings.afterPanelOpen(); 406 } else { 407 panel.settings.afterPanelClose(); 408 } 409 410 }, panel.settings.duration); 411 412 413 } else { 414 415 // Open/Close Before Callbacks (JS) 416 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 417 panel.settings.beforePanelOpen(); 418 } else { 419 panel.settings.beforePanelClose(); 420 } 421 422 if (panel.settings.useEasingPlugin) { 423 424 panel.parents('.scotch-panel-canvas:first').animate({ 425 top: distanceY+'px' 426 }, { 427 duration: panel.settings.duration, 428 easing: panel.settings.easingPluginTransition, 429 complete: function() { 430 431 // Open/Close After Callbacks (JS EASE) 432 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 433 panel.settings.afterPanelOpen(); 434 } else { 435 panel.settings.afterPanelClose(); 436 } 437 438 } 439 }); 440 441 } else { 442 443 panel.parents('.scotch-panel-canvas:first').animate({ 444 top: distanceY+'px' 445 }, panel.settings.duration, function() { 446 447 // Open/Close After Callbacks (JS NO EASE) 448 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 449 panel.settings.afterPanelOpen(); 450 } else { 451 panel.settings.afterPanelClose(); 452 } 453 454 }); 455 456 } 457 } 458 }; 459 460 // Toggle Translate X 461 var translateX = function(distanceX) { 462 463 if (has3d && hasTransitions && panel.settings.useCSS) { 464 465 // Open/Close Before Callbacks (CSS) 466 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 467 panel.settings.beforePanelOpen(); 468 } else { 469 panel.settings.beforePanelClose(); 470 } 471 472 panel.parents('.scotch-panel-canvas:first').css({
473 '-ms-transform': 'translate3d('+distanceX+', 0, 0)', 474 '-moz-transform': 'translate3d('+distanceX+', 0, 0)', 475 '-o-transform': 'translate3d('+distanceX+', 0, 0)', 476 '-webkit-transform': 'translate3d('+distanceX+', 0, 0)', 477 'transform': 'translate3d('+distanceX+', 0, 0)' 478 }); 479 480 setTimeout(function() { 481 482 // Open/Close After Callbacks (CSS) 483 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 484 panel.settings.afterPanelOpen(); 485 } else { 486 panel.settings.afterPanelClose(); 487 } 488 489 }, panel.settings.duration); 490 491 } else { 492 493 // Open/Close Before Callbacks (JS) 494 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 495 panel.settings.beforePanelOpen(); 496 } else { 497 panel.settings.beforePanelClose(); 498 } 499 500 if (panel.settings.useEasingPlugin) { 501 502 panel.parents('.scotch-panel-canvas:first').animate({ 503 left: distanceX 504 }, { 505 duration: panel.settings.duration, 506 easing: panel.settings.easingPluginTransition, 507 complete: function() { 508 509 // Open/Close After Callbacks (JS EASE) 510 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 511 panel.settings.afterPanelOpen(); 512 } else { 513 panel.settings.afterPanelClose(); 514 } 515 516 } 517 }); 518 519 } else { 520 521 panel.parents('.scotch-panel-canvas:first').animate({ 522 left: distanceX 523 }, panel.settings.duration, function() { 524 525 // Open/Close After Callbacks (JS NO EASE) 526 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 527 panel.settings.afterPanelOpen(); 528 } else { 529 panel.settings.afterPanelClose(); 530 } 531 532 }); 533 534 } 535 } 536 }; 537 538 539 /*======================================== 540 = PUBLIC FUNCTIONS = 541 ========================================*/ 542 // Open the Scotch Panel 543 panel.open = function() { 544 panel.parents('.scotch-panel-canvas:first').addClass('scotch-is-showing'); 545 546 // Load iframe if not loaded 547 if (panel.settings.type == 'iframe' && panel.settings.iframeURL && !panel.iframeIsLoaded) { 548 panel.iframeIsLoaded = true; 549 panel.find('iframe').attr('src', panel.settings.iframeURL); 550 } 551 552 // Play YouTube Video 553 if (panel.settings.type == 'video' && panel.settings.youtubeID && panel.settings.autoPlayVideo) { 554 toggleVideoState('video-id-'+panel.settings.youtubeID, ''); 555 } 556 557 if (panel.settings.direction == 'top') { 558 translateY(panel.height); 559 } 560 561 if (panel.settings.direction == 'bottom') { 562 translateY('-' + panel.height); 563 } 564 565 if (panel.settings.direction == 'left') { 566 translateX(panel.settings.distanceX); 567 } 568 569 if (panel.settings.direction == 'right') { 570 translateX('-' + panel.settings.distanceX); 571 } 572 }; 573 574 // Close ScotchPanel 575 panel.close = function() { 576 panel.parents('.scotch-panel-canvas:first').removeClass('scotch-is-showing'); 577 578 // Pause YouTube Video (after close...) 579 setTimeout(function(){ 580 if (panel.settings.type == 'video' && panel.settings.youtubeID && panel.settings.autoPlayVideo) { 581 toggleVideoState('video-id-'+panel.settings.youtubeID, 'hide'); 582 } 583 }, panel.settings.duration); 584 585 if (panel.settings.direction == 'top' || panel.settings.direction == 'bottom') { 586 translateY(0); 587 } 588 589 if (panel.settings.direction == 'left' || panel.settings.direction == 'right') { 590 translateX(0); 591 } 592 }; 593 594 // Toggle ScotchPanel 595 panel.toggle = function() { 596 if (panel.parents('.scotch-panel-canvas:first').hasClass('scotch-is-showing')) { 597 panel.close(); 598 } else { 599 panel.open(); 600 } 601 }; 602 603 604 605 606 /*========================================= 607 = MAKE MAGIC HAPPEN = 608 =========================================*/ 609 init(); 610 611 612 613 614 /*=============================== 615 = HELEPRS = 616 ===============================*/ 617 // Escape Key to Close 618 $(document).keyup(function(e) { 619 if (e.keyCode == 27 && panel.settings.enableEscapeKey) { 620 panel.close(); 621 } 622 }); 623 624 // Hover Helper 625 if (panel.settings.hoverSelector) { 626 $(panel.settings.hoverSelector).hover(function () { 627 panel.open(); 628 }, 629 function () { 630 panel.close(); 631 }); 632 } 633 634 // Click Helper 635 if (panel.settings.clickSelector) { 636 $(panel.settings.clickSelector).click(function () {
637 panel.toggle(); 638 639 return false; 640 }); 641 } 642 643 // Touch Helper 644 if (panel.settings.touchSelector) { 645 $(panel.settings.touchSelector).on('touchstart', function () { 646 panel.toggle(); 647 648 return false; 649 }); 650 } 651 652 // Return the Scotch Panel Object so Devs can do cool things with it 653 return panel; 654 }; 655 656}(jQuery));
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.