SitePoint Sponsor

User Tag List

Results 1 to 3 of 3

Thread: Marquee Help

  1. #1
    SitePoint Addict avstu's Avatar
    Join Date
    May 2005
    Posts
    297
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Marquee Help

    Ok I have this JS Marquee I am using on my forum. However there is two things I need to do and although this may be simple to most, I don't have a clue when it comes to this coding..

    The two things I would like to achieve:

    • Slow the marque down
    • stop the marque on rollover


    Marque Coding:

    Code:
    /**
    * author Remy Sharp
    * url http://remysharp.com/tag/marquee
    */
    
    (function ($) {
        $.fn.marquee = function (klass) {
            var newMarquee = [],
                last = this.length;
    
            // works out the left or right hand reset position, based on scroll
            // behavior, current direction and new direction
            function getReset(newDir, marqueeRedux, marqueeState) {
                var behavior = marqueeState.behavior, width = marqueeState.width, dir = marqueeState.dir;
                var r = 0;
                if (behavior == 'alternate') {
                    r = newDir == 1 ? marqueeRedux[marqueeState.widthAxis] - (width*2) : width;
                } else if (behavior == 'slide') {
                    if (newDir == -1) {
                        r = dir == -1 ? marqueeRedux[marqueeState.widthAxis] : width;
                    } else {
                        r = dir == -1 ? marqueeRedux[marqueeState.widthAxis] - (width*2) : 0;
                    }
                } else {
                    r = newDir == -1 ? marqueeRedux[marqueeState.widthAxis] : 0;
                }
                return r;
            }
    
            // single "thread" animation
            function animateMarquee() {
                var i = newMarquee.length,
                    marqueeRedux = null,
                    $marqueeRedux = null,
                    marqueeState = {},
                    newMarqueeList = [],
                    hitedge = false;
                    
                while (i--) {
                    marqueeRedux = newMarquee[i];
                    $marqueeRedux = $(marqueeRedux);
                    marqueeState = $marqueeRedux.data('marqueeState');
                    
                    if ($marqueeRedux.data('paused') !== true) {
                        // TODO read scrollamount, dir, behavior, loops and last from data
                        marqueeRedux[marqueeState.axis] += (marqueeState.scrollamount * marqueeState.dir);
    
                        // only true if it's hit the end
                        hitedge = marqueeState.dir == -1 ? marqueeRedux[marqueeState.axis] <= getReset(marqueeState.dir * -1, marqueeRedux, marqueeState) : marqueeRedux[marqueeState.axis] >= getReset(marqueeState.dir * -1, marqueeRedux, marqueeState);
                        
                        if ((marqueeState.behavior == 'scroll' && marqueeState.last == marqueeRedux[marqueeState.axis]) || (marqueeState.behavior == 'alternate' && hitedge && marqueeState.last != -1) || (marqueeState.behavior == 'slide' && hitedge && marqueeState.last != -1)) {                        
                            if (marqueeState.behavior == 'alternate') {
                                marqueeState.dir *= -1; // flip
                            }
                            marqueeState.last = -1;
    
                            $marqueeRedux.trigger('stop');
    
                            marqueeState.loops--;
                            if (marqueeState.loops === 0) {
                                if (marqueeState.behavior != 'slide') {
                                    marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
                                } else {
                                    // corrects the position
                                    marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir * -1, marqueeRedux, marqueeState);
                                }
    
                                $marqueeRedux.trigger('end');
                            } else {
                                // keep this marquee going
                                newMarqueeList.push(marqueeRedux);
                                $marqueeRedux.trigger('start');
                                marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
                            }
                        } else {
                            newMarqueeList.push(marqueeRedux);
                        }
                        marqueeState.last = marqueeRedux[marqueeState.axis];
    
                        // store updated state only if we ran an animation
                        $marqueeRedux.data('marqueeState', marqueeState);
                    } else {
                        // even though it's paused, keep it in the list
                        newMarqueeList.push(marqueeRedux);                    
                    }
                }
    
                newMarquee = newMarqueeList;
                
                if (newMarquee.length) {
                    setTimeout(animateMarquee, 25);
                }            
            }
            
            // TODO consider whether using .html() in the wrapping process could lead to loosing predefined events...
            this.each(function (i) {
                var $marquee = $(this),
                    width = $marquee.attr('width') || $marquee.width(),
                    height = $marquee.attr('height') || $marquee.height(),
                    $marqueeRedux = $marquee.after('<div ' + (klass ? 'class="' + klass + '" ' : '') + 'style="display: block-inline; width: ' + width + 'px; height: ' + height + 'px; overflow: hidden;"><div style="float: left; white-space: nowrap;">' + $marquee.html() + '</div></div>').next(),
                    marqueeRedux = $marqueeRedux.get(0),
                    hitedge = 0,
                    direction = ($marquee.attr('direction') || 'left').toLowerCase(),
                    marqueeState = {
                        dir : /down|right/.test(direction) ? -1 : 1,
                        axis : /left|right/.test(direction) ? 'scrollLeft' : 'scrollTop',
                        widthAxis : /left|right/.test(direction) ? 'scrollWidth' : 'scrollHeight',
                        last : -1,
                        loops : $marquee.attr('loop') || -1,
                        scrollamount : $marquee.attr('scrollamount') || this.scrollAmount || 2,
                        behavior : ($marquee.attr('behavior') || 'scroll').toLowerCase(),
                        width : /left|right/.test(direction) ? width : height
                    };
                
                // corrects a bug in Firefox - the default loops for slide is -1
                if ($marquee.attr('loop') == -1 && marqueeState.behavior == 'slide') {
                    marqueeState.loops = 1;
                }
    
                $marquee.remove();
                
                // add padding
                if (/left|right/.test(direction)) {
                    $marqueeRedux.find('> div').css('padding', '0 ' + width + 'px');
                } else {
                    $marqueeRedux.find('> div').css('padding', height + 'px 0');
                }
                
                // events
                $marqueeRedux.bind('stop', function () {
                    $marqueeRedux.data('paused', true);
                }).bind('pause', function () {
                    $marqueeRedux.data('paused', true);
                }).bind('start', function () {
                    $marqueeRedux.data('paused', false);
                }).bind('unpause', function () {
                    $marqueeRedux.data('paused', false);
                }).data('marqueeState', marqueeState); // finally: store the state
                
                // todo - rerender event allowing us to do an ajax hit and redraw the marquee
    
                newMarquee.push(marqueeRedux);
    
                marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
                $marqueeRedux.trigger('start');
                
                // on the very last marquee, trigger the animation
                if (i+1 == last) {
                    animateMarquee();
                }
            });            
    
            return $(newMarquee);
        };
    }(jQuery));

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,702
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Currently the animation occurs every 25 milliseconds.
    Code:
    setTimeout(animateMarquee, 25);
    There is an attribute you can set on the marquee called scrollamount where you can set the scroll speed to less than one pixel.

    According to the demo page, rollover already stops the marquee.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Addict avstu's Avatar
    Join Date
    May 2005
    Posts
    297
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It did, but the other part of it kept causing errors on my site so i took it out!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •