var A13FRAMEWORK_slider_debug = false; /*global Modernizr, YT, $f, _V_, TweenMax, Linear, Power2, Sine, TimelineLite, A13FRAMEWORK */ (function($){ "use strict"; var a13slider = function(SliderOptions){ // Default Options var $html = $(document.documentElement), $window = $(window), body = document.body, $body = $(body), A13F = A13FRAMEWORK, defaultOptions = { // Functionality parent : body, // where will be embeded main element extra_class : '', // extra classes for slider main_slider : 0, // main slider have to br resized differently window_high : 0, // full size ratio : '', // proportional size, default 16/9 from theme style autoplay : 1, // Slideshow starts playing automatically slide_interval : 5000, // Length between transitions transition : 2, // 0-None, 1-Fade, 2-Carousel transition_speed: 750, // Speed of transition fit_variant : 0, // 0-always, 1-landscape, 2-portrait, 3-when_needed, 4-cover pattern : 0, // shows above images gradient : 0, // shows above images start_slide : 0, // slide that should be shown at start // Components texts : 1, // Will titles and descriptions be shown title_color : '', // bg color under slide title progress_bar : 1, // Timer for each slide thumb_links : 1, // Individual thumb links for each slide show_thumbs_on_start: 0, // Show thumbs on load original_items : {}, // list from which options.slides where generated slides : {} // here we will send slides with JSON format }; /* Global Variables ----------------------------*/ var launched = false, options = $.extend({}, defaultOptions, SliderOptions), //options of slide show $parent = $(options.parent), slides = options.slides, //params of each slide slides_num = slides.length, //number of slides all_slides = {}, //$slides_list.find('li') $root = {}, //container of every slider part $slides_list = {}, //container of slides fit_variant = options.fit_variant, pattern = options.pattern, gradient = options.gradient, thumbs = {}, //thumb_list.children(), thumb_width = 0, //thumbs.eq(0).outerWidth(true), tray_width = 0, //width of visible tray tray_no_move = false, //if there is enough thumbs to move them thumbs_busy = false, thumb_list_w = 0, //width of all thumbnails maxThumbsMove = 0, //maximum value of thumbs left position slide_id_pre = 'ss-slide-', p_bar_enabled = options.progress_bar, slider_interval_time= options.slide_interval, transition_type = options.transition, transition_speed = transition_type === 0 ? 0 : parseFloat(options.transition_speed/1000), thumb_links = options.thumb_links, thumbs_on_load = options.show_thumbs_on_start, title_color = options.title_color, //Minor animation times minorShowTime = 300, minorHideTime = 200, // Elements thumb_list = {}, // Thumbnail list tray, // Thumbnail tray tray_i, // div.inner keeps all together for hiding tray_button, // thumbs opener slide_count_num, // current slide number play_button, // Play/Pause button next_button, // Next slide button prev_button, // Prev slide button // Internal variables current_slide_number = options.start_slide, // Current slide number is_slider_playing = false, // Tracks paused on/off is_video_playing = false, // Tracks paused on/off slideshow_interval_id = 0, // Stores slideshow timer hide_items_interval_id = 0, // Stores hiding items timer thumb_interval = 0, // Thumbnail interval clean_after_goTo_function = false, // Trigger to update images after slide jump loadYouTubeAPI = false, // Bool if YT API should load loadVimeoAPI = false, // Bool if Vimeo API should load loadNativeVideoAPI = false, // Bool if Native Video API should load videos = {}, // videos from options click_event = 'click touchend', //css for hidden elements hidden = { opacity : 1, visibility : 'hidden', x : '0%' }; /* Prepares Vars and HTML ----------------------------*/ var prepareEnv = function(){ //no slides - no slider if( options.slides.length === 0 ){ return; } // Add in slide markers var sliderIterator = 0, slideSet = '', thumbMarkers = '', slider_classes = '', is_video = false, ts; //this slide from array //collect slides while(sliderIterator <= slides_num-1){ ts = slides[sliderIterator]; is_video = ts.type === 'video'; //prepare slide HTML slideSet = slideSet+'
  • '; //collect video info if(is_video){ //check which API is needed if(ts.video_type === 'youtube' && loadYouTubeAPI !== 'loaded'){ loadYouTubeAPI = true; } else if(ts.video_type === 'vimeo' && loadVimeoAPI !== 'loaded'){ loadVimeoAPI = true; } else if(ts.video_type === 'html5' && loadNativeVideoAPI !== 'loaded'){ loadNativeVideoAPI = true; } //copy video details videos[slide_id_pre+sliderIterator] = ts; } // Slide Thumbnail Links if (thumb_links){ thumbMarkers += '
  • '; } //increase iterator sliderIterator++; } //we load marked video APIs loadVideoApi(); if(pattern > 0){ slider_classes += ' pattern pattern-'+pattern; } if(gradient > 0){ slider_classes += ' gradient'; } if(thumb_links){ slider_classes += ' with-thumbs'; if(thumbs_on_load){ slider_classes += ' thumbs-open'; } } if(options.extra_class.length){ slider_classes += ' '+options.extra_class; } //Place slider HTML $parent.append('' + '
    ' + '' + '
    ' + ((slides_num > 1)? (thumb_links? '' : '') + (p_bar_enabled? '' : '') + '1'+slides_num+'' : '') + '
    ' + (thumb_links? '
    ' : '')+ ((slides_num > 1)? ( ''+ ''+ '' ) : '') + '
    '+ ''); //root element $root = $parent.children('.a13-slider'); //container of slides $slides_list = $root.find('ul.slider-slides'); //append ready html $slides_list.append(slideSet); if (thumb_links){ tray_button = $root.find('.thumb-tray-button'); tray = $root.find('.slider-thumb-tray'); tray_i = tray.children(); tray_i.append(''); //fill vars thumb_list = tray.find('.slider-thumb-list'); thumbs = thumb_list.children(); positionThumbs(); } //save other slider elements all_slides = $slides_list.find('li'); play_button = $root.find('.slider-play-button'); next_button = $root.find('.next-slide-control'); prev_button = $root.find('.prev-slide-control'); slide_count_num = $root.find('.slides-count').find('.num'); //hide slides initially TweenMax.set(all_slides, hidden); //prepare play button if (p_bar_enabled){ TweenMax.set(play_button.find('.circle'), {scale:0}); } //watch slider height sliderHeight(); //prepare slides // Set current slide fillSlide(current_slide_number, 'activeslide', 1); //load previous slide if (slides_num > 2){ fillSlide(_getPreviousSlideNumber(), 'prevslide'); } //load next slide if (slides_num > 1){ fillSlide(_getNextSlideNumber()); $slides_list.addClass('cursor-grab'); } }, /* Launch Slider ----------------------------*/ launch = function(){ if(launched === true ){ return; } launched = true; //show slider $slides_list.addClass('show'); $parent.find('.show-with-slider').addClass('show'); // Call function for before slide transition beforeAnimation(); events(); if( slides_num > 1 ){ // Start slide show if auto-play enabled if(options.autoplay){ playToggle(); } else{ indicatePlayerState('pause'); } } }, onResize = function(){ //stretch slider sliderHeight(); //resize all images resizeNow(); $root.trigger('timeForResize'); }, /* Bind events ----------------------------*/ events = function(){ var hide_items_callback = function() { $root.addClass('hide-items'); }, key_events = function (event) { var key = event.keyCode; // Left Arrow if ((key === 37)){ prevSlide(); } // Right Arrow else if ((key === 39)) { nextSlide(); } // Spacebar else if (key === 32) { playToggle(); //to not scroll page event.preventDefault(); } }, resizeCallback = A13F.debounce(onResize, 250); // Hide controllers if mouse doesn't move for some time period $root.on('mousemove click touchstart', function() { $root.removeClass('hide-items'); clearTimeout(hide_items_interval_id); // Timeout will be cleared on each slide movement also hide_items_interval_id = setTimeout(hide_items_callback, 3000); }); if(options.autoplay && slides_num > 1){ hide_items_interval_id = setTimeout(hide_items_callback, 3000); } // Keyboard Navigation $root.on('keydown.a13-slider', key_events); //controls next_button.on( click_event, nextSlide); prev_button.on( click_event, prevSlide); play_button.on( click_event, playToggle); //small screens only $slides_list.on(click_event, 'div.texts-opener', textsToggle); //Touch event(changing slides) & drag sliderDragEvents(); //thumbs actions if(thumb_links){ if(tray_button){ tray_button.on( click_event, toggleThumbsTray ); } thumbsEvents(); } // Adjust image when browser is resized $window.on('resize.a13-slider', resizeCallback); //also when logo is loaded $body.on('a13LogoLoaded', sliderHeight ); /* Remove events and timeouts ----------------------------*/ var destroyCallback = function(){ //timeouts stopMovingToNextSlide(); clearTimeout(hide_items_interval_id); $root.off('a13-slider-destroy', destroyCallback); $html.off('keydown.a13-slider', key_events); $window.off('resize.a13-slider', resizeCallback); }; $root.on('a13-slider-destroy', destroyCallback); }, sliderDragEvents = function(){ var drag_start_x = 0, drag_end_x = 0, drag_start_y = 0, drag_end_y = 0, current_slide_position = 0, is_dragging = false, //touchStart or mouseDown is enabling dragging is_waiting = true, //waiting for direction of dragging is_scrolling = false, //vertical scrolling of window rather then slider is_sliding = false, //sliding of slider rather then window just_paused = false, drag_threshold = 30, //pixels change_slide_threshold = 0.06,//6% of slide width after_drag_time = 0.7, slide_clickable = true, drag_ticking = false, drag_rAF = 0,//requestAnimationFrame ID slider_width = 0, current_slide, next_slide, prev_slide, getCurrentSlideXOffset = function(){ return typeof current_slide[0]._gsTransform !== 'undefined'? current_slide[0]._gsTransform.x : 0; }, mouseDown = function(e) { //check touch event if(e.type==='touchstart'){ if(e.originalEvent.touches.length === 1){ e = e.originalEvent.touches[0]; } else{ return; } } else{ //for mouse action we disable it to prevent default browser image drag e.preventDefault(); } //reset variables drag_rAF = 0; drag_ticking = false; just_paused = false; is_waiting = true; is_scrolling = false; is_sliding = false; drag_start_x = drag_end_x = e.pageX; drag_start_y = drag_end_y = e.pageY; slider_width = $slides_list.width(); //pause slider id needed if(is_slider_playing){ just_paused = true; playToggle(); } //prepare slides for animating current_slide = all_slides.eq(current_slide_number); prev_slide = all_slides.eq(_getPreviousSlideNumber()); next_slide = all_slides.eq(_getNextSlideNumber()); //prepare for drag is_dragging = true; slide_clickable = false; current_slide_position = getCurrentSlideXOffset(); //grabbing cursor $slides_list.removeClass('cursor-grab').addClass('cursor-grabbing'); $body.addClass('cursor-grabbing'); //stop any scroll animation TweenMax.set(current_slide, { xPercent : '0%', x: current_slide_position }); TweenMax.set(prev_slide, { xPercent : '-100%', x: current_slide_position , autoAlpha : 1 }); TweenMax.set(next_slide, { xPercent : '100%', x: current_slide_position , autoAlpha : 1 }); }, mouseMove = function(){ drag_ticking = false; if (is_sliding) { //update position of slides TweenMax.set([current_slide, prev_slide, next_slide], {x : current_slide_position + drag_end_x - drag_start_x}); } }, mouseMoveTick = function(e) { var cords = e; if(e.type==='touchmove') { if (e.originalEvent.touches.length === 1) { cords = e.originalEvent.touches[0]; } else { return; } } drag_end_x = cords.pageX; drag_end_y = cords.pageY; //detect where user scrolls if(is_waiting){ //check if user scrolls page vertically if(Math.abs(drag_end_y - drag_start_y) > 15){ //bigger threshold before we decide then for X axis is_scrolling = true; is_waiting = false; } //or user is using slider else if(Math.abs(drag_end_x - drag_start_x) > 3){ is_sliding = true; is_waiting = false; } } //user slides so we prevent default vertically scrolling action if(!is_scrolling && !is_waiting){ e.preventDefault(); } if (!drag_ticking) { drag_rAF = requestAnimationFrame(mouseMove); } drag_ticking = true; }, mouseUp = function(e) { //prepare touch event if(e.type==='touchend') { if (e.originalEvent.changedTouches.length !== 1) { return; } } //where we dragging, or it just random end od touch/click if (is_dragging) { //cancel any animation that could occur after drag is over if(drag_rAF !== 0){ cancelAnimationFrame(drag_rAF); } //remove grabbing cursor $slides_list.removeClass('cursor-grabbing').addClass('cursor-grab'); $body.removeClass('cursor-grabbing'); var moved_distance = drag_end_x - drag_start_x; //if dragged less then threshold, then it was probably click if (Math.abs(moved_distance) < drag_threshold) { slide_clickable = true; //move back to current slide TweenMax.to([current_slide, prev_slide, next_slide], after_drag_time, { x: 0 }); } //enough of next/prev slide is visible? else if( Math.abs( current_slide_position + moved_distance ) > change_slide_threshold * slider_width ){ //lets move to previous slide if(current_slide_position + moved_distance > 0){ //this hides "previous" slide, so we will have to make it visible again changeSlide(true, true); if(slides_num > 2){ //this one won't be needed TweenMax.set(next_slide, hidden); } //swap current slide to next slide position TweenMax.set(current_slide, { xPercent : '100%', x: -slider_width + current_slide_position + moved_distance, autoAlpha : 1 }); //swap previous slide to current slide position TweenMax.set(prev_slide, { xPercent : '0%', x: -slider_width + current_slide_position + moved_distance }); //finish drag with animation TweenMax.to( [current_slide, prev_slide], after_drag_time, {x : 0, ease: Power2.easeInOut} ); } //lets move to next slide else{ //this hides "previous" slide, so we will have to make it visible again changeSlide(false, true); if(slides_num > 2){ //this one won't be needed TweenMax.set(prev_slide, hidden); } //swap current slide to previous slide position TweenMax.set(current_slide, { xPercent : '-100%', x: slider_width + current_slide_position + moved_distance, autoAlpha : 1 }); //swap next slide to current slide position TweenMax.set(next_slide, { xPercent : '0%', x: slider_width + current_slide_position + moved_distance }); //finish drag with animation TweenMax.to( [current_slide, next_slide], after_drag_time, {x : 0, ease: Power2.easeInOut} ); } } //move back to current slide else{ TweenMax.to([current_slide, prev_slide, next_slide], after_drag_time, { x: 0 }); } } //just in case re enable click else{ slide_clickable = true; } //clean after event is_dragging = false; is_sliding = false; is_waiting = false; is_scrolling = false; }, onDestroy = function(){ $root .off('a13-slider-destroy', onDestroy); $body .off('mousemove.slides_drag', mouseMoveTick) .off('mouseup.slides_drag', mouseUp) .off('touchmove.slides_drag', mouseMoveTick) .off('touchend.slides_drag', mouseUp); $(document) .off('mouseleave.slides_drag', mouseUp); }; if(slides_num > 1){ //destroy $root .on('a13-slider-destroy', onDestroy); //mouse drag events $slides_list.on('mousedown.slides_drag', mouseDown); $body .on('mousemove.slides_drag', mouseMoveTick) .on('mouseup.slides_drag', mouseUp); $(document) .on('mouseleave.slides_drag', mouseUp); //touch drag events $slides_list.on('touchstart.slides_drag', mouseDown) .on('touchmove.slides_drag', mouseMoveTick) .on('touchend.slides_drag', mouseUp); } //click on slider $slides_list.on( click_event, 'li',{}, function(e){ if(is_scrolling){ return; } //for touch event we have to do check for clickable here, as it runs before touchend on body if(slides_num > 1 && e.type === 'touchend'){ //if dragged less then threshold, then it was probably click if (is_dragging && (Math.abs(drag_end_x - drag_start_x) < drag_threshold)) { slide_clickable = true; } } if(slide_clickable){ //check if this is video var index = all_slides.index($(this)), target = $(e.target); //KNOWN ISSUE //when dragging HTML5 video it receives click and starts to play //not easy to fix if(slides[index].type === 'video'){ //click on video cover if(target.is('div.video-poster')){ playVideo(); } return; } //check if we didn't click some link in description if(target.is('a.slide') || target.is('img')){ //if this slide is link if(slides[index].url.length){ return; } else{ //continue execution } } else if(target.is('a') && !target.is('.slide') || target.parents('a').length > 0){ return; } e.preventDefault(); if(!just_paused){ playToggle(); } } }); }, thumbsEvents = function(){ var drag_start_x = 0, drag_end_x = 0, thumbs_list_position = 0, is_dragging = false, drag_threshold = 30, thumb_clickable = true, wheel_ticking = false, drag_ticking = false, drag_rAF = 0,//requestAnimationFrame ID start_move_time = 0, //for checking if current move want get out of tray scope checkEdges = function(distance, strict){ //allow for drag beyond edge ? strict = typeof strict === 'undefined' ? false : strict; if(distance > 0){ return strict? 0 : Math.round(Math.pow(distance,1/2)); } else if(distance < maxThumbsMove){ return strict ? maxThumbsMove : maxThumbsMove - Math.round(Math.pow(maxThumbsMove - distance, 1/2)); } return distance; }, getThumbsXOffset = function(){ return typeof thumb_list[0]._gsTransform !== 'undefined'? thumb_list[0]._gsTransform.x : 0; }, onResize = function(){ thumb_list_w = thumb_list.width(); tray_width = tray.width(); // Update Thumb Interval & Page thumb_interval = Math.floor(tray_width / thumb_width) * thumb_width; // Adjust thumbnail markers if (thumb_list_w > tray_width){ maxThumbsMove = tray_width - thumb_list_w; tray_no_move = false; tray.addClass('cursor-grab'); var current_position = getThumbsXOffset(); //fix right side edge if(current_position < maxThumbsMove){ TweenMax.set(thumb_list, {x: maxThumbsMove}); } //fix left side edge else if(current_position > 0){ TweenMax.set(thumb_list, {x: 0}); } } //less images then width else{ TweenMax.set(thumb_list, {x: (tray_width - thumb_list_w)/2}); tray_no_move = true; tray.removeClass('cursor-grab'); } }, mouseWheelScroll = function(delta){ var offset = getThumbsXOffset(), first_visible = thumbs.eq(Math.ceil(-offset / thumb_width)), left = first_visible.position().left, to_end = first_visible.nextAll().andSelf().length * thumb_width, to_move = delta * thumb_width, scroll_improve = 0.9, move; //move forward if(to_move < 0){ //if less then 10% of thumb is scrolled, jump only one thumb if( -offset - to_move - left < (1-scroll_improve)*thumb_width ){ to_move += thumb_width; } if(tray_width > (to_end + to_move) ){ //forward edge move = maxThumbsMove; //right edge } else{ //forward normal move = -left + to_move; //normal move } } //move backward else{ //if less then 90% thumb to scroll, jump to another(improves backward scrolling) if( -offset + (-left + to_move) < scroll_improve*thumb_width ){ to_move += thumb_width; } if((offset + to_move) > 0 ){ //backward edge move = 0; //left edge } else{ //backward normal move = -left + to_move; //normal move } } _animateThumbs(move); }, requestWheelTick = function(event, delta){ //do nothing if(!tray_no_move){ event.preventDefault(); if (!wheel_ticking) { requestAnimationFrame(function(){ wheel_ticking = false; mouseWheelScroll(delta); } ); } wheel_ticking = true; } }, mouseDown = function(e) { if (!tray_no_move) { e.preventDefault(); if(e.type==='touchstart'){ if(e.originalEvent.touches.length === 1){ e = e.originalEvent.touches[0]; } else{ return; } } //reset drag_rAF = 0; drag_ticking = false; drag_start_x = drag_end_x = e.pageX; start_move_time = Number(new Date()); //prepare for drag is_dragging = true; thumbs_list_position = getThumbsXOffset(); thumb_clickable = false; tray.removeClass('cursor-grab').addClass('cursor-grabbing'); $body.addClass('cursor-grabbing'); //stop any scroll animation TweenMax.set(thumb_list, {x: checkEdges(thumbs_list_position)}); } }, mouseMove = function(){ drag_ticking = false; if (is_dragging) { //update position of thumbs TweenMax.set(thumb_list, {x: checkEdges(thumbs_list_position + (drag_end_x - drag_start_x))}); } }, mouseMoveTick = function(e) { if (!drag_ticking) { drag_rAF = requestAnimationFrame(mouseMove); } if(e.type==='touchmove') { if (e.originalEvent.touches.length === 1) { e = e.originalEvent.touches[0]; } else { return; } } drag_end_x = e.pageX; drag_ticking = true; }, mouseUp = function(e) { if(e.type==='touchend') { if (e.originalEvent.changedTouches.length === 1) { e = e.originalEvent.changedTouches[0]; } else { return; } } if (is_dragging) { //cancel any animation that could occur after drag is over if(drag_rAF !== 0){ cancelAnimationFrame(drag_rAF); } //clean after drag is_dragging = false; tray.removeClass('cursor-grabbing').addClass('cursor-grab'); $body.removeClass('cursor-grabbing'); //if dragged less then threshold, then it was probably click if (Math.abs(drag_end_x - drag_start_x) < drag_threshold) { thumb_clickable = true; } //calculate mouseUp animation var time = Number(new Date()) - start_move_time, distance = drag_start_x - e.pageX, px_per_second = Math.round(Math.abs(distance) / (time / 1000)), friction_factor = 1000, animation_time = px_per_second / friction_factor, animation_distance = Math.pow(px_per_second, 2) / (2 * friction_factor), new_x = checkEdges(getThumbsXOffset() - animation_distance * (distance > 0 ? 1 : -1), true); //recalculate friction and time to get to edge if(new_x === 0 || new_x === maxThumbsMove){ if(new_x === 0){ friction_factor = Math.pow(px_per_second, 2) / (Math.abs(getThumbsXOffset())*2); } else{ friction_factor = Math.pow(px_per_second, 2) / (Math.abs(maxThumbsMove - getThumbsXOffset())*2); } animation_time = px_per_second/friction_factor; } //make animation TweenMax.to(thumb_list, animation_time, { x: new_x, ease: Sine.easeOut } ); } //just in case re enable click else{ thumb_clickable = true; } }, onDestroy = function(){ $root .off('a13-slider-destroy', onDestroy) .off('timeForResize', onResize); $body .off('mousemove.thumbs_list', mouseMoveTick) .off('mouseup.thumbs_list', mouseUp) .off('touchmove.thumbs_list', mouseMoveTick) .off('touchend.thumbs_list', mouseUp); $(document) .off('mouseleave.thumbs_list', mouseUp); }; //resize & destroy $root .on('a13-slider-destroy', onDestroy) .on('timeForResize', onResize); //scrolling with mouse tray.on('mousewheel', requestWheelTick); //mouse drag events tray.on('mousedown.thumbs_list', mouseDown); $body .on('mousemove.thumbs_list', mouseMoveTick) .on('mouseup.thumbs_list', mouseUp); $(document) .on('mouseleave.thumbs_list', mouseUp); //touch drag events tray.on('touchstart.thumbs_list', mouseDown); $body .on('touchmove.thumbs_list', mouseMoveTick) .on('touchend.thumbs_list', mouseUp); //mouse hover classes tray .on('mouseenter', function () { if (!tray_no_move) { //inform other elements to not animate thumbs thumbs_busy = true; } }) .on('mouseleave', function () { if (!is_dragging) { thumbs_busy = false; } }); //open thumb thumbs .on( click_event, function(e){//click cause we don't want to respond to touchStart e.preventDefault(); //for touch event we have to do check for clickable here, as it runs before touchend on body if(e.type === 'touchend'){ //if dragged less then threshold, then it was probably click if (is_dragging && (Math.abs(drag_end_x - drag_start_x) < drag_threshold)) { thumb_clickable = true; } } if(thumb_clickable){ goTo(thumbs.index(this)); } }); }, toggleThumbsTray = function(e){ if(typeof e !== 'undefined'){ e.stopPropagation(); e.preventDefault(); } //if hiding tray if(tray_button.hasClass('active')){ tray_button.removeClass('active'); $root.removeClass('thumbs-open'); } //if opening tray else{ positionThumbs(); tray_button.addClass('active'); $root.addClass('thumbs-open'); } }, positionThumbs = function(){ thumb_width = thumbs.eq(0).outerWidth(true); tray_width = tray.width(); thumb_list_w = slides_num * thumb_width; maxThumbsMove = tray_width - thumb_list_w; // Make thumb tray proper size thumb_list.width(thumb_list_w); //Adjust to true width of thumb markers //less images then width if(thumb_list_w < tray_width){ TweenMax.set(thumb_list, {x: (tray_width - thumb_list_w)/2}); tray_no_move = true; tray.removeClass('cursor-grab'); } else{ tray_no_move = false; tray.addClass('cursor-grab'); } //Thumbnail Tray Navigation thumb_interval = Math.floor(tray_width / thumb_width) * thumb_width; }, /* Loads APIs for Video types ----------------------------*/ loadVideoApi = function(){ //load Youtube API if(loadYouTubeAPI === true){ //this function will run when YT API will load window.onYouTubeIframeAPIReady = function() { if(A13FRAMEWORK_slider_debug){ console.log('Youtube Api ready!'); } YT_ready(true); }; //load YT API (function(){ var tag = document.createElement('script'); tag.src = "//www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); })(); } //load Vimeo API if(loadVimeoAPI === true){ //load VIMEO API (function(){ var tag = document.createElement('script'); tag.src = "https://f.vimeocdn.com/js/froogaloop2.min.js"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); })(); } //load native video API if(loadNativeVideoAPI === true){ //load mediaElement API //loaded already } }, /* Define YT_ready function. ----------------------------*/ YT_ready = (function(){ var onReady_funcs = [], api_isReady = false; /* @param func function Function to execute on ready * @param func Boolean If true, all queued functions are executed * @param b_before Boolean If true, the func will be added to the first position in the queue */ return function(func, b_before){ if(typeof func === "function") { //if api si loaded or we have youtube object if (api_isReady || typeof YT === 'object'){ api_isReady = true; //mark it loaded func(); } else { onReady_funcs[b_before?"unshift":"push"](func); } } else if (func === true) { api_isReady = true; for (var i=0; i 150) { $root.css({ margin : 0, paddingTop: 0, height : total }); } //use normal size else { $root.css({ margin : '', paddingTop: _sliderProportion(), height : '' }); } } else{ $root.css({ paddingTop: _sliderProportion() }); } }, _sliderProportion = function(){ var ratio = options.ratio.split('/'); if(ratio.length === 2){ ratio[0] = parseInt(ratio[0],10); ratio[1] = parseInt(ratio[1],10); if(A13F.isInteger(ratio[0]) && A13F.isInteger(ratio[1]) && ratio[0] > 0 && ratio[1] > 0){ return ratio[1]/ratio[0]*100+'%'; } } return ''; }, /* Resize Images ----------------------------*/ resizeNow = function(image){ //all images or only one? var is_big_resize = typeof image === 'undefined', elem = is_big_resize? all_slides.children('a').children('img') : $(image); // Resize each image elem.each(function(){ var this_image = $(this), image_height = this_image.data('origHeight'), image_width = this_image.data('origWidth'), space_width = $slides_list.width(), space_height = $slides_list.height(), image_ratio = (image_height/image_width).toFixed(4), space_ratio = (space_height/space_width).toFixed(4), resize_width = 0, resize_height = 0, new_css, fit_always = fit_variant === 0, fit_landscape = fit_variant === 1, fit_portrait = fit_variant === 2, fit_when_needed = fit_variant === 3, fit_cover = fit_variant === 4, // Size & Position //Cover: Image will always cover all available area //Always: Image will never exceed browser width or height (Ignores min. dimensions) //Landscape: Landscape images will not exceed browser width //Portrait: Portrait images will not exceed browser height //When Needed: Best for small images that shouldn't be stretched resizeWidth = function(){ resize_width = space_width; resize_height = space_width * image_ratio; }, resizeHeight = function(){ resize_height = space_height; resize_width = space_height / image_ratio; }; /*-----Resize Image-----*/ if (fit_when_needed){ //reset resize_width = image_width; resize_height = image_height; if( image_height > space_height || image_width > space_width){ if (space_ratio > image_ratio){ resizeWidth(); } else { resizeHeight(); } } } else if (fit_always){ if (space_ratio > image_ratio){ resizeWidth(); } else { resizeHeight(); } } else if (fit_cover){ if (space_ratio > image_ratio){ resizeHeight(); } else { resizeWidth(); } } else{ // Normal Resize if (space_ratio > image_ratio){ // If landscapes are set to fit if(fit_landscape && image_ratio < 1){ resizeWidth(); } else{ resizeHeight(); } } else { // If portraits are set to fit if(fit_portrait && image_ratio >= 1){ resizeHeight(); }else{ resizeWidth(); } } } /*-----End Image Resize-----*/ new_css = { width : resize_width, height : resize_height, // Horizontally Center left : (space_width - resize_width)/2, // Vertically Center top : (space_height - resize_height)/2 }; //animate current image back to proper place if needed if(is_big_resize && this_image.closest('li').data('slide-id') === slide_id_pre+current_slide_number){ TweenMax.to(this_image, 0.5, new_css); } //resize other images else{ this_image.css(new_css); } }); }, /* Filling next and ----------------------------*/ fillSurroundingSlides = function(number){ //if slide was not filled yet fillSlide(_getNextSlideNumber(number)); fillSlide(_getPreviousSlideNumber(number)); }, /* Filling empty slides when need ----------------------------*/ fillSlide = function(slide_to_fill_number, bonus_class, is_first_slide){ var target_slide = all_slides.eq(slide_to_fill_number), slide_options = slides[slide_to_fill_number], slide_type = slide_options.type, addClass = (typeof bonus_class !== 'undefined'), first = (typeof is_first_slide !== 'undefined'), imageLink, item; //if slide is empty if (!target_slide.html()){ if(slide_type === 'image') { imageLink = (slide_options.url) ? "href='" + slide_options.url + "'" : ""; // If link exists, build it item = $(''); //add classes to li target_slide.addClass('image-loading' + (addClass ? ' ' + bonus_class : '')); TweenMax.set(target_slide, hidden); item .appendTo(target_slide).wrap('') .load(function () { _origDim($(this)); resizeNow(this); target_slide.removeClass('image-loading'); item.hide().fadeIn(minorShowTime); //start slider if we have first slide prepared if (first) { launch(); } //check if there shouldn't be called ken burns effect for this slide //useful when changing slides with goTo else if (slide_to_fill_number === current_slide_number) { kenBurnsEffect(); } }) .attr('src', slide_options.image).attr('alt', slide_options.alt_attr); //photo bg color target_slide.css('background-color', slide_options.bg_color); } else if(slide_type === 'video'){ //cover for video $('
    ').appendTo(target_slide); //when image is loaded hide loading animation $('') .load(function(){ //var cover = $('
    ').appendTo(target_slide); target_slide.removeClass('image-loading'); //cover.hide().fadeOut(minorShowTime); }) .attr('src', slide_options.image); target_slide.addClass('image-loading' + (addClass? ' '+bonus_class : '')); TweenMax.set(target_slide, hidden); if(slide_options.video_type === 'html5'){ target_slide.append($(slide_options.video_url).html()); } else{ target_slide.append('