A way to do slides including video/image

var isPad = (navigator.userAgent.match(/iPad/i) != null);
Slides = function()
{
    // context
    var t = this;
    // member variables
    t.domReady = false;
    t.config = {};
    t.global = new Global;
    t.configLoaded = false;
    t.current = -1;
    t.slideImageClass = 'slide-main-image';
    t.slideClass = 'slide';
    t.layerClass = 'layer';
    t.slideshowControlsId = 'slideshow-controls';
    t.flashVideoPlayerIdStub = 'flash-video-player-container-';
    t.flashVideoPlayerClass = 'flash-video-player-container';
    t.isTransitioning = false;
    t.timeoutId = null;
    t.slideStartedAt = null;
    t.paused = false;
    t.elapsedTimeAtPause = null;
    t.stoppedAtEnd = false;
    t.playPauseButtonOver = false;
    t.videoSupport = ''; // will equal 'html5' | 'flash' | 'none'
    t.flashLoadedBinds = [];
    t.firstSlideShowCompleteEvent = 'FirstSlideShowCompleteEvent';
    
    
    // when DOM is ready, alert this object and try to run setup
    $(function() {
    	t.domReady = true;
        t.setup();
    });


    // set up and load the config from external JSON
    t.loadConfig = function()
    {
        // bail if conditions already met
        if (t.configLoaded)
            return;
        
        $.ajax(t.global.configURL, {
            'dataType': 'json',
            'success': function(data){
                t.config = data;
                t.configLoaded = true;
                t.setup();
            },
            'error': function(jqXHR, textStatus, errorThrown) {
                // console.log('axaj error', jqXHR, textStatus, errorThrown);
            }
        });
    };
    

    // when config is loaded and DOM is ready, setup our slides
    t.setup = function()
    {
        // bail if conditions not met
        if (!t.domReady || !t.configLoaded)
            return;

        // DISABLED: SEE COMMENT BELOW
        // detect what kind of video support we have
        /*if (Modernizr.video && Modernizr.video.h264)
        {
            t.videoSupport = 'html5';
        }
        else if (swfobject.hasFlashPlayerVersion(t.global.flashPlayerVersion))
        {
            t.videoSupport = 'flash';
        }
        else
        {
            t.videoSupport = 'none';
        }*/

        // COMMENT
        // This Slides file once supports a flash version of just the 
        // video player (VideoPlayer.swf), but we're disabling that for
        // clarity. If the HTML5 video tag is not supported, this Slides
        // should never been run.
        t.videoSupport = 'html5';
        
        // change the config for the iPad
        if (isPad)
        {
            for (var i in t.config.slides)
            {
                if (t.config.slides[i].type == 'video')
                {
                    var slide = t.config.slides[i];
                    var layer = slide.layers[0];
                    slide.type = 'image';
                    layer.type = 'image';
                    layer.src = layer.poster;
                }
            }
        }

        t.clearAllSlides();
        for (index in t.config.slides)
        {
            t.config.slides[index]['loaded'] = false;
            t.addSlide(t.config.slides[index], index);
        }
        
        $(window).resize(t.adjustSlideBackgrounds);
        t.adjustSlideBackgrounds();
        
        var controlsHTML = '<div id="'+t.slideshowControlsId+'" style="display:none;">';
        controlsHTML += '<a href="#" class="play-pause">Play/Pause</a>';
        controlsHTML += '<a href="#" class="previous">Previous</a>';
        controlsHTML += '<span></span>';
        controlsHTML += '<a href="#" class="next">Next</a>';
        controlsHTML += '</div>';
        
        $(t.global.containerQuery).append(controlsHTML);
        
        $('#'+t.slideshowControlsId+' a.play-pause')
            .mouseenter(t.playPauseOver)
            .mouseleave(t.playPauseOut)
            .click(function(event){
                event.preventDefault();
                t.playPause();
            });
        $('#'+t.slideshowControlsId+' a.previous').click(function(event) {
            event.preventDefault();
            t.previousSlideFromButton();
        });
        $('#'+t.slideshowControlsId+' a.next').click(function(event) {
            event.preventDefault();
            t.nextSlideFromButton();
        });

        if (t.config.autoplay)
        {
            t.showSlide(0);
            t.paused = false;
        }
        else
        {
            t.paused = true;
            t.setControllerState(0);
            t.showSlide(0, true);
        }

        t.playPauseSetState();
    }
    

    // remove all slides
    t.clearAllSlides = function()
    {
        $('#'+t.global.slideshowId).empty();
    }
    

    // add slide
    t.addSlide = function(data, index)
    {
        var setFlashVideoPlayerLater = false;
        var tag = $('<div class="'+t.slideClass+'"></div>');
        tag.fadeTo(0, 0);

        for (layerIndex in data.layers)
        {
            var layer = data.layers[layerIndex];
            var d = null;
            if (layerIndex == 0)
            {
                if (layer.type == 'image')
                {
                    tag.append('<div class="'+t.slideImageClass+'"><img src="'+t.config.baseURL+layer.src+'"/></div>');
                    d = tag.find('div:last');
                    var i = d.find('img');
                    i.load(function(){
                        data.loaded = true;
                    })
                    if (data.zoomAlign == 'topLeft')            i.css({'top':0,'left':0});
                    else if (data.zoomAlign == 'top')           i.css({'top':0,'right':0,'left':0});
                    else if (data.zoomAlign == 'topRight')      i.css({'top':0,'right':0});
                    else if (data.zoomAlign == 'left')          i.css({'top':0,'bottom':0,'left':0});
                    else if (data.zoomAlign == 'center')        i.css({'top':0,'right':0,'bottom':0,'left':0});
                    else if (data.zoomAlign == 'right')         i.css({'top':0,'right':0,'bottom':0});
                    else if (data.zoomAlign == 'bottomLeft')    i.css({'bottom':0,'left':0});
                    else if (data.zoomAlign == 'bottom')        i.css({'right':0,'bottom':0,'left':0});
                    else if (data.zoomAlign == 'bottomRight')   i.css({'right':0,'bottom':0});
                }
                else if (layer.type == 'video' && t.videoSupport == 'html5')
                {
                    tag.append('<video><source src="'+t.config.baseURL+layer.src+'" type="video/mp4"/></video>');
                    d = tag.find('video:last');
                    tag.find('video').css({'z-index':layerIndex});
                    tag.find('video').bind('canplaythrough', function(){
                        data.loaded = true;
                    });
                }
                else if (layer.type == 'video' && t.videoSupport == 'flash')
                {
                    var flashVideoPlayerId = t.flashVideoPlayerIdStub+index;
                    tag.append('<div id="'+flashVideoPlayerId+'"></div>');
                    d = tag.find('div:last');
                    d.addClass(t.flashVideoPlayerClass);
                    var flashvars = {};
                    var params = {};
                    var attributes = {};
                    flashvars.index = index;
                    flashvars.width = t.config.width;
                    flashvars.height = t.config.height;
                    flashvars.videoURL = t.config.baseURL+layer.src;
                    params.wmode = 'opaque';
                    attributes.wmode = 'opaque';
                    d = $('#'+flashVideoPlayerId);
                    setFlashVideoPlayerLater = true;
                }
                // unknown type! bail!
                else
                    return;

                // if (d != null)
                // {
                //     if (data.align == 'topLeft')            d.css({'top':0,'left':0});
                //     else if (data.align == 'top')           d.css({'top':0,'right':0,'left':0});
                //     else if (data.align == 'topRight')      d.css({'top':0,'right':0});
                //     else if (data.align == 'left')          d.css({'top':0,'bottom':0,'left':0});
                //     //else if (data.align == 'center')        d.css({'top':'-100%','right':'-100%','bottom':'-100%','left':'-100%'});
                //     else if (data.align == 'right')         d.css({'top':0,'right':0,'bottom':0});
                //     else if (data.align == 'bottomLeft')    d.css({'bottom':0,'left':0});
                //     else if (data.align == 'bottom')        d.css({'right':0,'bottom':0,'left':0});
                //     else if (data.align == 'bottomRight')   d.css({'right':0,'bottom':0});
                // }
            }
            else
            {
                // any type that is a link
                if (layer.url)
                {
                    tag.append('<a href="'+layer.url+'"></a>');
                    d = tag.find('a:last');
                    if (layer.target)
                        d.attr('target', layer.target);
                    if (layer.type == 'sprite')
                        d.mouseenter(function(){
                            $(this).css({'background-position':'0 -'+layer.height+'px'});
                        }).mouseleave(function(){
                            $(this).css({'background-position':'0 0'});
                        });
                }
                
                // if just text
                else if (layer.type == 'text')
                {
                    tag.append('<div></div>');
                    d = tag.find('div:last');
                }
                
                else if (layer.type == 'image')
                {
                    tag.append('<img src="'+t.config.baseURL+blank.png"/>');
                    d = tag.find('img:last');
                }
                
                // apply to all layers
                d.addClass(t.layerClass);
                d.addClass(layer.type);
                if (layer.text)
                    d.append(layer.text);
                if (layer.x && layer.y)
                    d.css({
                        'left':layer.x,
                        'top':layer.y
                    });
                if (layer.width)
                    d.width(layer.width);
                if (layer.height)
                    d.height(layer.height);
                if (layer.layerClass)
                    d.addClass(layer.layerClass);
                if (layer.size)
                    d.css({'font-size':layer.size});
                if (layer.font)
                    d.css({'font-family':layer.font});
                if (layer.color)
                    d.css({'color':layer.color});
                if (layer.lineHeight)
                    d.css({'line-height':layer.lineHeight+'px'});
                if (layer.src && layer.type != 'video')
                    d.css({
                        'backgroundImage':'url('+t.config.baseURL+layer.src+')',
                        'textIndent':-5000
                    });
                d.css({
                    'overflow':'hidden'
                });
                
            }
            if (d)
                d.css({'z-index':layerIndex});
        }
        
        $('#'+t.global.slideshowId).append(tag);
        
        if (setFlashVideoPlayerLater)
            swfobject.embedSWF(t.global.flashVideoPlayerURL, flashVideoPlayerId, '100%', '100%', t.global.flashPlayerVersion, t.global.flashPlayerExpressInstallURL, flashvars, params, attributes);
    }
    

    // show slide based on index
    t.showSlide = function(index, pauseSlide)
    {
        // if we're in the middle of a transition, bail.
        if (t.isTransitioning)
            return;
            
        if (typeof(pauseSlide) == 'undefined')
            pauseSlide = false;
        
        t.isTransitioning = true;
        var data = t.config.slides[index];
        var doIt = function()
        {
            // current slide
            var currentSlide = $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index);
            
            // move z-index of new slide to top
            currentSlide.css({'z-index':t.config.slides.length-1});
            var j = 0;
            for (var i = 0; i < t.config.slides.length; i++)
            {
                if (i == index)
                    continue;
                $('#'+t.global.slideshowId+' .'+t.slideClass).eq(i).css({'z-index':j});
                j++;
            }

            // set current state in controller
            t.setControllerState(index);

            if (t.current != -1)
            {
                var fadeOutCurrent = t.current;
                $('#'+t.global.slideshowId+' .'+t.slideClass).eq(t.current).fadeTo(data.transition * 1000, 0, function(){
                    t.stopVideo(fadeOutCurrent, true);
                });
            }

            t.elapsedTimeAtPause = 0;
            
            // start playing if video
            if (data.type == 'video' && !pauseSlide)
            {
                t.playVideo(index, true);
            }
            else if (data.type == 'video' && pauseSlide)
            {
                
            }
            // otherwise if image, do ken burns effect
            else if (data.type == 'image' && !pauseSlide)
            {
                t.startKenBurns(index, t.getSlideDuration(index, true), true);
            }
            else if (data.type == 'image' && pauseSlide)
            {
                var c = t.calculateZoom(data.zoomStart);
                var img = currentSlide.find('img');
                img.width(c).height(c);
            }

            t.adjustSlideBackgrounds();
            var previous = t.current;
            currentSlide.fadeTo(data.transition * 1000, 1, function(){
                if (index == 0 && previous == -1)
                    $('#'+t.global.slideshowId).trigger(t.firstSlideShowCompleteEvent);
                t.isTransitioning = false;
            });
            t.current = index;

            if (!pauseSlide)
            {
                t.setSlideTimeout();
            }
        }
        
        
        if (data.loaded)
        {
            doIt();
        }
        else
        {
            if (data.type == 'image')
                $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('.'+t.slideImageClass+' img').load(doIt);
            else
                t.bindFunctionToVideoReady(index, doIt);
        }
    }
    

    // if possible, show next slide
    t.nextSlide = function()
    {
        if (t.current >= t.config.slides.length - 1 && !t.config.loop)
        {
            t.stoppedAtEnd = true;
            t.paused = true;
            t.playPauseSetState();
            t.stopVideo(t.current);
        }
        else if (t.current >= t.config.slides.length - 1 && t.config.loop)
        {
            t.showSlide(0);
        }
        else
        {
            t.showSlide(t.current + 1);
        }
    }


    t.previousSlideFromButton = function()
    {
        if (t.isTransitioning)
            return;

        if (t.current == 0 && !t.config.loop)
            return;
        
        if (t.timeoutId)
            clearTimeout(t.timeoutId);

        if (t.stoppedAtEnd && t.config.slides.length > 1)
        {
            t.showSlide(t.config.slides.length - 2);
            t.paused = false;
            t.stoppedAtEnd = false;
            t.playPauseSetState();
        }
        else
        {
            var slideId;
            if (t.current > 0)
                slideId = t.current - 1;
            else if (t.current == 0 && t.config.loop)
                slideId = t.config.slides.length - 1;
            else 
                slideId = 0; // should never happen
            if (slideId == t.current)
                t.previous = null;
            t.showSlide(slideId, t.paused);
        }
    }

    t.nextSlideFromButton = function()
    {
        if (t.isTransitioning)
            return;

        var lastSlide = t.config.slides.length - 1;
        
        if (t.current == lastSlide && !t.config.loop)
            return;

        if (t.timeoutId)
            clearTimeout(t.timeoutId);

        var slideId;
        if (t.current == lastSlide && t.config.loop)
            slideId = 0;
        else if (t.current < lastSlide)
            slideId = t.current + 1;
        else
            return; // this should never happen

        if (slideId == t.current)
            t.previous = null;

        t.showSlide(slideId, t.paused);
    }

    t.setSlideTimeout = function()
    {
        // calculate how long the slide should be on-screen
        var index = t.current;
        var slideDuration = t.getSlideDuration(index);

        // set the timeout to transition to next slide
        if (t.timeoutId)
            clearTimeout(t.timeoutId);
        t.timeoutId = setTimeout(t.nextSlide, slideDuration);
        
        // set time this was set to object
        var d = new Date();
        t.slideStartedAt = d.getTime();
    }

    t.getSlideDuration = function(index, excludeNextTransition)
    {
        if (typeof(excludeNextTransition) == 'undefined')
            excludeNextTransition = false;
        
        var data = t.config.slides[index];
        var currentSlide = $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index);
        var nextIndex = (index < t.config.slides.length - 1) ? index + 1 : 0;
        var nextTransition = (excludeNextTransition) ? 0 : t.config.slides[nextIndex].transition;
        var slideDuration = (data.type == 'video') ? t.getDuration(index) : data.interval;
        return ((slideDuration - nextTransition) * 1000) - t.elapsedTimeAtPause;
    }
    
    t.startKenBurns = function(index, duration, reset)
    {
        if (!t.isSlideImage(index))
            return;
        
        if (typeof(reset) == 'undefined')
            reset = false;
            
        t.stopKenBurns(index);
            
        var img = $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('img');
        var data = t.config.slides[index];

        if (reset)
        {
            var c1 = t.calculateZoom(data.zoomStart);
            img.width(c1).height(c1);
        }
        var c2 = t.calculateZoom(data.zoomEnd);
        img.animate({
            'width':c2,
            'height':c2
        },
        {
            'duration':duration,
            'easing':'linear'
        });
    }
    
    t.stopKenBurns = function(index)
    {
        if (!t.isSlideImage(index))
            return;
        
        var img = $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('img');
        var data = t.config.slides[index];

        img.stop();
    }
    
    t.calculateZoom = function(zoom)
    {
        if (zoom < 100)
            zoom = 100;
        else if (zoom > 200)
            zoom = 200;
        return zoom + '%';
    }
    
    t.playPause = function()
    {
        if (t.isTransitioning)
            return;

        // if stopped at the end. start the whole thing over
        if (t.stoppedAtEnd && !t.config.loop)
        {
            t.showSlide(0);
            t.paused = false;
            t.stoppedAtEnd = false;
            t.playPauseSetState();
            return;
        }
        
        // find current video if it exists
        // var currentVideo = $('#'+t.global.slideshowId+' .'+t.slideClass).eq(t.current).find('video');
        var index = t.current;

        // unpause
        if (t.paused)
        {
            t.setSlideTimeout();
            t.paused = false;
            t.playPauseSetState();
            t.playVideo(index);
            t.startKenBurns(index, t.getSlideDuration(index, true));
            // if (currentVideo.length > 0)
            //     currentVideo.get(0).play();
        }
        
        // pause
        else
        {
            
            if (t.timeoutId)
                clearTimeout(t.timeoutId);
            var d = new Date();
            t.elapsedTimeAtPause += d.getTime() - t.slideStartedAt;
            t.paused = true;
            t.playPauseSetState();
            t.stopVideo(index);
            t.stopKenBurns(index);
            // if (currentVideo.length > 0)
            //     currentVideo.get(0).pause();
        }
    }
    
    t.playPauseOver = function()
    {
        t.playPauseButtonOver = true;
        t.playPauseSetState();
    }
    
    t.playPauseOut = function()
    {
        t.playPauseButtonOver = false;
        t.playPauseSetState();
    }
    
    t.playPauseSetState = function()
    {
        var xPos = (t.paused) ? '0' : '-9px';
        var yPos = (t.playPauseButtonOver) ? '-11px' : '0';
        $('#'+t.slideshowControlsId+' a.play-pause').css({'background-position':xPos+' '+yPos});
    }
    
    t.stopVideo = function(index, seekToBegining)
    {
        if (!t.isSlideVideo(index))
            return;

        if (typeof(seekToBegining) == 'undefined')
            seekToBegining = false;

        if (t.videoSupport == 'html5')
        {
            $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('video').each(function(){
                this.pause();
                if (seekToBegining)
                    this.currentTime = 0;
            });
        }
        else if (t.videoSupport == 'flash')
        {
            var flashObj = $('#'+t.flashVideoPlayerIdStub+index).get(0);
            if (seekToBegining)
                flashObj.stopVideo();
            else
                flashObj.pauseVideo();
        }
    }
    
    t.playVideo = function(index, startFromBegining)
    {
        if (!t.isSlideVideo(index))
            return;

        if (typeof(startFromBegining) == 'undefined')
            startFromBegining = false;
        if (t.videoSupport == 'html5')
        {
            $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('video').each(function(){
                if (startFromBegining)
                    this.currentTime = 0;
                this.play();
            });
        }
        else if (t.videoSupport == 'flash')
        {
            var flashObj = $('#'+t.flashVideoPlayerIdStub+index).get(0);
            if (startFromBegining)
            {
                flashObj.playVideoFromBeginning();
            }
            else
                flashObj.playVideo();
        }
    }
    
    t.restartVideo = function(index)
    {
        if (!t.isSlideVideo(index))
            return;

        if (t.videoSupport == 'html5')
        {
            $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('video').each(function(){
                if (startFromBegining)
                    this.currentTime = 0;
                this.play();
            });
        }
    }
    
    t.bindFunctionToVideoReady = function(index, func)
    {
        if (!t.isSlideVideo(index))
            return;
        
        if (t.videoSupport == 'html5')
        {
            $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('video').bind('canplaythrough', func);
        }
        else if (t.videoSupport == 'flash')
        {
            t.flashLoadedBinds.push({'index':index, 'func':func});
        }
    }
    
    t.getDuration = function(index)
    {
        if (!t.isSlideVideo(index))
            return;
        
        if (t.videoSupport == 'html5')
        {
            return $('#'+t.global.slideshowId+' .'+t.slideClass).eq(index).find('video').get(0).duration;
        }
        else if (t.videoSupport == 'flash')
        {
            var flashObj = $('#'+t.flashVideoPlayerIdStub+index).get(0);
            return flashObj.getDuration();
        }
    }
    
    t.setControllerState = function(index)
    {
        $('#'+t.slideshowControlsId+' span').html((index+1) + '/' + t.config.slides.length);
        if ($('#'+t.slideshowControlsId+':hidden').length > 0)
        {
            var c = $('#'+t.slideshowControlsId);
            if ($.support.opacity)
                c.fadeTo(500, 1);
            else
                c.show();
        }
    }
    
    t.setFlashSlideAsLoaded = function(index)
    {
        t.config.slides[index].loaded = true;
        for (var i = 0; i < t.flashLoadedBinds.length; i++)
        {
            if (t.flashLoadedBinds[i].index == index)
            {
                t.flashLoadedBinds[i].func();
                t.flashLoadedBinds.splice(i, 1);
                break;
            }
        }
    }
    
    t.isSlideVideo = function(index)
    {
        return (t.config.slides[index].type == 'video');
    }

    t.isSlideImage = function(index)
    {
        return (t.config.slides[index].type == 'image');
    }

    // durring slideshow setup, this gets set to window resize to adjust the size of all slide
    // bottom layers (images and videos)
    t.adjustSlideBackgrounds = function()
    {
        var c = $(t.global.containerQuery);
        var w = parseInt(c.width());
        var h = parseInt(c.height());

        if (h == 0)
        {
            setTimeout(t.adjustSlideBackgrounds, 50);
            return;
        }

        var i = $('#'+t.global.slideshowId).find('.'+t.slideImageClass+', video');
        var rw = w / t.config.width;
        var rh = h / t.config.height;
        var r = (rw > rh) ? rw : rh;
        var iw = t.config.width * r;
        var ih = t.config.height * r;
        i.width(Math.round(iw));
        i.height(Math.round(ih));
        i.each(function(index){
            var a = t.config.slides[index].align;
        
            var left = 0;
            if ($.inArray(a, ['top', 'center', 'bottom']) != -1)                left = Math.round((w - iw) / 2);
            else if ($.inArray(a, ['topRight', 'right', 'bottomRight']) != -1)  left = Math.round(w - iw);
        
            var top = 0;
            if ($.inArray(a, ['left', 'center', 'right']) != -1)                    top = Math.round((h - ih) / 2);
            else if ($.inArray(a, ['bottomLeft', 'bottom', 'bottomRight']) != -1)   top = Math.round(h - ih);
        
            $(this).css({
                'left': left,
                'top': top
            });
        });
    }
};

 

你可能感兴趣的:(Ajax,css,html5,Flash)