Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

156
LINES

< > BotCompany Repo | #1032505 // marquee.jquery.js (<marquee> handler)

Document

1  
/**
2  
* author Remy Sharp
3  
* url http://remysharp.com/tag/marquee
4  
* https://remysharp.com/2008/09/10/the-silky-smooth-marquee/
5  
*/
6  
7  
(function ($) {
8  
    $.fn.marquee = function (klass) {
9  
        var newMarquee = [],
10  
            last = this.length;
11  
12  
        // works out the left or right hand reset position, based on scroll
13  
        // behavior, current direction and new direction
14  
        function getReset(newDir, marqueeRedux, marqueeState) {
15  
            var behavior = marqueeState.behavior, width = marqueeState.width, dir = marqueeState.dir;
16  
            var r = 0;
17  
            if (behavior == 'alternate') {
18  
                r = newDir == 1 ? marqueeRedux[marqueeState.widthAxis] - (width*2) : width;
19  
            } else if (behavior == 'slide') {
20  
                if (newDir == -1) {
21  
                    r = dir == -1 ? marqueeRedux[marqueeState.widthAxis] : width;
22  
                } else {
23  
                    r = dir == -1 ? marqueeRedux[marqueeState.widthAxis] - (width*2) : 0;
24  
                }
25  
            } else {
26  
                r = newDir == -1 ? marqueeRedux[marqueeState.widthAxis] : 0;
27  
            }
28  
            return r;
29  
        }
30  
31  
        // single "thread" animation
32  
        function animateMarquee() {
33  
            var i = newMarquee.length,
34  
                marqueeRedux = null,
35  
                $marqueeRedux = null,
36  
                marqueeState = {},
37  
                newMarqueeList = [],
38  
                hitedge = false;
39  
                
40  
            while (i--) {
41  
                marqueeRedux = newMarquee[i];
42  
                $marqueeRedux = $(marqueeRedux);
43  
                marqueeState = $marqueeRedux.data('marqueeState');
44  
                
45  
                if ($marqueeRedux.data('paused') !== true) {
46  
                    // TODO read scrollamount, dir, behavior, loops and last from data
47  
                    marqueeRedux[marqueeState.axis] += (marqueeState.scrollamount * marqueeState.dir);
48  
49  
                    // only true if it's hit the end
50  
                    hitedge = marqueeState.dir == -1 ? marqueeRedux[marqueeState.axis] <= getReset(marqueeState.dir * -1, marqueeRedux, marqueeState) : marqueeRedux[marqueeState.axis] >= getReset(marqueeState.dir * -1, marqueeRedux, marqueeState);
51  
                    
52  
                    if ((marqueeState.behavior == 'scroll' && marqueeState.last == marqueeRedux[marqueeState.axis]) || (marqueeState.behavior == 'alternate' && hitedge && marqueeState.last != -1) || (marqueeState.behavior == 'slide' && hitedge && marqueeState.last != -1)) {                        
53  
                        if (marqueeState.behavior == 'alternate') {
54  
                            marqueeState.dir *= -1; // flip
55  
                        }
56  
                        marqueeState.last = -1;
57  
58  
                        $marqueeRedux.trigger('stop');
59  
60  
                        marqueeState.loops--;
61  
                        if (marqueeState.loops === 0) {
62  
                            if (marqueeState.behavior != 'slide') {
63  
                                marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
64  
                            } else {
65  
                                // corrects the position
66  
                                marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir * -1, marqueeRedux, marqueeState);
67  
                            }
68  
69  
                            $marqueeRedux.trigger('end');
70  
                        } else {
71  
                            // keep this marquee going
72  
                            newMarqueeList.push(marqueeRedux);
73  
                            $marqueeRedux.trigger('start');
74  
                            marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
75  
                        }
76  
                    } else {
77  
                        newMarqueeList.push(marqueeRedux);
78  
                    }
79  
                    marqueeState.last = marqueeRedux[marqueeState.axis];
80  
81  
                    // store updated state only if we ran an animation
82  
                    $marqueeRedux.data('marqueeState', marqueeState);
83  
                } else {
84  
                    // even though it's paused, keep it in the list
85  
                    newMarqueeList.push(marqueeRedux);                    
86  
                }
87  
            }
88  
89  
            newMarquee = newMarqueeList;
90  
            
91  
            if (newMarquee.length) {
92  
                setTimeout(animateMarquee, 25);
93  
            }            
94  
        }
95  
        
96  
        // TODO consider whether using .html() in the wrapping process could lead to loosing predefined events...
97  
        this.each(function (i) {
98  
            var $marquee = $(this),
99  
                width = $marquee.attr('width') || $marquee.width(),
100  
                height = $marquee.attr('height') || $marquee.height(),
101  
                $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(),
102  
                marqueeRedux = $marqueeRedux.get(0),
103  
                hitedge = 0,
104  
                direction = ($marquee.attr('direction') || 'left').toLowerCase(),
105  
                marqueeState = {
106  
                    dir : /down|right/.test(direction) ? -1 : 1,
107  
                    axis : /left|right/.test(direction) ? 'scrollLeft' : 'scrollTop',
108  
                    widthAxis : /left|right/.test(direction) ? 'scrollWidth' : 'scrollHeight',
109  
                    last : -1,
110  
                    loops : $marquee.attr('loop') || -1,
111  
                    scrollamount : $marquee.attr('scrollamount') || this.scrollAmount || 2,
112  
                    behavior : ($marquee.attr('behavior') || 'scroll').toLowerCase(),
113  
                    width : /left|right/.test(direction) ? width : height
114  
                };
115  
            
116  
            // corrects a bug in Firefox - the default loops for slide is -1
117  
            if ($marquee.attr('loop') == -1 && marqueeState.behavior == 'slide') {
118  
                marqueeState.loops = 1;
119  
            }
120  
121  
            $marquee.remove();
122  
            
123  
            // add padding
124  
            if (/left|right/.test(direction)) {
125  
                $marqueeRedux.find('> div').css('padding', '0 ' + width + 'px');
126  
            } else {
127  
                $marqueeRedux.find('> div').css('padding', height + 'px 0');
128  
            }
129  
            
130  
            // events
131  
            $marqueeRedux.bind('stop', function () {
132  
                $marqueeRedux.data('paused', true);
133  
            }).bind('pause', function () {
134  
                $marqueeRedux.data('paused', true);
135  
            }).bind('start', function () {
136  
                $marqueeRedux.data('paused', false);
137  
            }).bind('unpause', function () {
138  
                $marqueeRedux.data('paused', false);
139  
            }).data('marqueeState', marqueeState); // finally: store the state
140  
            
141  
            // todo - rerender event allowing us to do an ajax hit and redraw the marquee
142  
143  
            newMarquee.push(marqueeRedux);
144  
145  
            marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
146  
            $marqueeRedux.trigger('start');
147  
            
148  
            // on the very last marquee, trigger the animation
149  
            if (i+1 == last) {
150  
                animateMarquee();
151  
            }
152  
        });            
153  
154  
        return $(newMarquee);
155  
    };
156  
}(jQuery));

download  show line numbers   

Travelled to 3 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx

No comments. add comment

Snippet ID: #1032505
Snippet name: marquee.jquery.js (<marquee> handler)
Eternal ID of this version: #1032505/2
Text MD5: 2b038fa3855b9bfdb5010206711007fe
Author: stefan
Category: javascript
Type: Document
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-09-11 22:33:56
Source code size: 7597 bytes / 156 lines
Pitched / IR pitched: No / No
Views / Downloads: 162 / 59
Version history: 1 change(s)
Referenced in: [show references]