Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First commit

  • Loading branch information...
commit 364d225b1ac32f94a41737adf46a0018feada996 0 parents
@joequery authored
6 .gitignore
@@ -0,0 +1,6 @@
+#Ignore komodo project files
+.komodotools
+stickyscroller.komodoproject
+diagram.psd
+easing.js
+nonweb/
152 GetSet.js
@@ -0,0 +1,152 @@
+/************************************************************/
+//Class GetSet
+//Purpose: Creates dynamic getters and setters
+/************************************************************/
+
+var GetSet = {};
+
+//=========================================================//
+//Public Method override
+//Purpose: Override default values through iteration
+//Parameters:
+// obj: The object whose default values will be overridden
+//Postcondition: options Object is altered
+//=========================================================//
+GetSet.override = function(options, defaults)
+{
+ //Store this scope
+ var $this = options;
+
+
+ for (var i in defaults)
+ {
+ if(!($this[i]))
+ {
+ $this[i] = defaults[i];
+ }
+ }
+};
+
+//=========================================================//
+//Public getFunctions
+//Purpose: Copies one objects functions to another
+//Parameters:
+// template: The object whose method will be copied
+// recepient: The object receiving the template methods
+//Postcondition: recepient object is altered
+//=========================================================//
+GetSet.getFunctions = function(template, recepient)
+{
+ for (var i in template)
+ {
+ if(template[i].constructor == Function)
+ {
+ recepient[i] = template[i];
+ }
+ }
+};
+
+
+//=========================================================//
+//Public Method gettters
+//Purpose: Dynamically creates accessor methods(getters)
+//Parameters:
+// scope: The scope in which the accessor methods will be
+// applied
+// prefix: Goes before the property. i.e. (get)Name
+// camel: whether to induce camel case
+// obj: Accessors
+//Postcondition: scope has been altered to include
+//accessor methods
+//=========================================================//
+GetSet.getters = function(options)
+{
+ //Over-ride default values
+ var defaults =
+ {
+ prefix: "get",
+ camel: true
+ };
+
+ //Override defaults values
+ GetSet.override(options, defaults);
+
+ //If prefix is set to 'none', force blank. A blank string as a parameter
+ //evaluates to null for some reason.
+ options.prefix = (options.prefix === "none") ? "" : options.prefix;
+
+ //Iterate through the properties of the object
+ var str;
+ for ( var i in options.obj )
+ {
+ //If camel case is enabled and no blank prefix
+ if(options.camel && options.prefix != "")
+ {
+ str = i.charAt(0).toUpperCase() + i.substr(1);
+ }
+ else
+ {
+ str = i;
+ }
+ (function(i)
+ {
+ // Dynamically create an accessor method
+ options.scope[ options.prefix + str ] = function()
+ {
+ return options.obj[i];
+ };
+ })(i);
+ }
+};
+
+//=========================================================//
+//Public Method setters
+//Purpose: Dynamically creates muator methods(setters)
+//Parameters:
+// scope: The scope in which the mutator methods will be
+// applied
+// prefix: Goes before the property. i.e. (set)Name
+// camel: whether to induce camel case
+// obj: The object that will have mutators
+//Postcondition: scope has been altered to include mutator
+//methods
+//=========================================================//
+GetSet.setters = function(options)
+{
+ //Over-ride default values
+ var defaults =
+ {
+ prefix: "set",
+ camel: true
+ };
+
+ //Override defaults values
+ GetSet.override(options, defaults);
+
+ //If prefix is set to 'none', force blank. A blank string as a parameter
+ //evaluates to null for some reason.
+ options.prefix = (options.prefix === "none") ? "" : options.prefix;
+
+ //Iterate through the properties of the object
+ var str;
+ for ( var i in options.obj )
+ {
+ //If camel case is enabled and no blank prefix
+ if(options.camel && options.prefix != "")
+ {
+ str = i.charAt(0).toUpperCase() + i.substr(1);
+ }
+ else
+ {
+ str = i;
+ }
+ (function(i)
+ {
+ // Dynamically create an accessor method
+ options.scope[ options.prefix + str ] = function(val)
+ {
+ options.obj[i] = val;
+ };
+ })(i);
+ }
+};
BIN  StickScroller.zip
Binary file not shown
277 StickyScroller.js
@@ -0,0 +1,277 @@
+/*****************************************************************************/
+// Class Scroller
+// Purpose: Create a fixed scroller
+// Parameters:
+// obj: The object that will be scrolling
+// start: What distance from the top (in px) the effect starts
+// end: What distance from the top (in px) the effect ends
+// interval: What scroll distance triggers the callback
+// range: How many pixels after the
+// margin: Margin from the top of the browser
+// Dependencies:
+// GetSet class. Included in Vert Library @ http://vertstudios.com/vertlib.js
+/******************************************************************************/
+
+function StickyScroller(obj, options)
+{
+ //Keep track of how many scrollers we have
+ if ( typeof StickyScroller.counter === 'undefined' )
+ {
+ StickyScroller.counter = 0;
+ }
+ else
+ {
+ StickyScroller.counter++;
+ }
+
+ //Store function scope
+ var $this = this;
+
+ //Store initial top and left/right values
+ var top = $(obj).css('top');
+ var left = $(obj).css('left');
+ var right = $(obj).css('right');
+
+ var scroll = 0;
+ var tempScroll = 0;
+
+ //------------------------------------------------------------
+ // Set default property values
+ //------------------------------------------------------------
+ var defaults = {
+ start: 0,
+ end: 10000,
+ interval: $(obj).height(),
+ margin: parseInt(top, 10),
+ range: $(obj).height()
+ }, settings = jQuery.extend(defaults,options);
+ obj = $(obj);
+
+ settings.index = 0;
+ settings.oldIndex = 0;
+
+ //Accessors for settings
+ GetSet.getters({scope: $this, obj: settings});
+
+ //------------------------------------------------------------//
+ // Callback Functions //
+ //------------------------------------------------------------//
+ var Callback = {};
+
+ Callback.newIndex = function(){}; //When the index changes
+ Callback.limbo = function(){}; //When scroller not in range
+ Callback.scroll = function(){}; //On window scroll
+
+ //Get setters for Callback functions
+ GetSet.setters({scope: this, prefix: "on", obj: Callback});
+
+ //=========================================================//
+ //Public distanceFrom
+ //Purpose: Determines the distance in pixels between
+ // the scroller and an index
+ //Parameters:
+ // index: The index whose distance from scroller will be calculated
+ //Postcondition: Returns an integer
+ //=========================================================//
+ this.distanceFrom = function(index)
+ {
+ //Check for both references: "Top" of the range and "bottom"
+ var top = index*settings.interval + settings.start
+ var bottom = index*settings.interval + settings.range + settings.start
+
+ var distanceFromTop = Math.abs(scroll-top);
+ var distanceFromBottom = Math.abs(scroll-bottom);
+
+ //Return the smallest distance
+ if(distanceFromTop < distanceFromBottom)
+ {
+ return distanceFromTop;
+ }
+ else
+ {
+ return distanceFromBottom;
+ }
+ };
+
+ //=========================================================//
+ //Public closestIndex
+ //Purpose: Determines the closest index
+ //Postcondition: Returns the closest index as an integer
+ //=========================================================//
+ this.closestIndex = function()
+ {
+ //If index is 0, automatically return 1
+ if(settings.index === 0)
+ {
+ return 1;
+ }
+
+ //Distance from next/previous index
+ var dPrev = this.distanceFrom(settings.index-1);
+ var dNext = this.distanceFrom(settings.index+1);
+
+ //Return the index associated with the smallest distance
+ if(dPrev <= dNext)
+ {
+ return settings.index-1;
+ }
+ else
+ {
+ return settings.index+1;
+ }
+ };
+
+ //=========================================================//
+ //Private getIndex
+ //Purpose: returns index
+ //=========================================================//
+ var getIndex = function()
+ {
+ //Make sure movement would be in the bounds
+ if(scroll > settings.start && scroll < settings.end)
+ {
+ //Possible new index
+ tempIndex = Math.floor((scroll-settings.start)/settings.interval);
+
+ //Make sure the index is different before reassigning
+ //or executing the callback
+ if(tempIndex !== settings.index)
+ {
+ //Store old index
+ settings.oldIndex = settings.index;
+
+ //Assign new index
+ settings.index = tempIndex;
+ }
+ }
+ //If scroll goes beyond end mark, set distance at end mark
+ else if(scroll >= settings.end)
+ {
+ settings.oldIndex = settings.index;
+ settings.index = Math.floor((settings.end-settings.start)/settings.interval);
+ }
+ //If scroll goes beyond beginning mark, set distance at start
+ else
+ {
+ settings.oldIndex = settings.index;
+ settings.index = 0;
+ }
+ };
+
+ //=========================================================//
+ //Public firstIndex
+ //Purpose: Returns first index
+ //Postcondition: Returns an integer
+ //=========================================================//
+ this.firstIndex = function()
+ {
+ return 0;
+ };
+
+ //=========================================================//
+ //Public lastIndex
+ //Purpose: Returns last index
+ //Postcondition: Returns an integer
+ //=========================================================//
+ this.lastIndex = function()
+ {
+ return Math.floor((settings.end-settings.start+settings.margin)/settings.interval);
+ };
+
+ //=========================================================//
+ //Public inRange
+ //Purpose: Determines if the scroller is in interval range
+ //Postcondition: Returns boolean
+ //=========================================================//
+ this.inRange = function()
+ {
+ var upperbound = settings.index * settings.interval + settings.start;
+ var lowerbound = settings.index * settings.interval + settings.start + settings.range;
+ var inRange = (scroll >= upperbound ) && (scroll <= lowerbound);
+ return inRange;
+ };
+
+
+ //------------------------------------------------------------//
+ // On Browser Scroll //
+ //------------------------------------------------------------//
+ var wrap = $('<div id="scrollcontainer' + StickyScroller.counter + '">').css(
+ {
+ width: obj.width(),
+ height: obj.height(),
+ position: "absolute",
+ top: top,
+ left: left,
+ right: right
+ });
+
+ obj.wrap(wrap);
+
+ $(window).scroll(function()
+ {
+ scroll = $(window).scrollTop();
+
+ //Get the current index
+ getIndex();
+
+ //If scroll less than beginning, set back to beginning
+ if(scroll < settings.start)
+ {
+ $(obj).css({
+ position : 'absolute',
+ top: 0,
+ left: 0,
+ right: 0});
+
+ $("#scrollcontainer"+ StickyScroller.counter).css({
+ position : 'absolute',
+ top: settings.start+settings.margin,
+ left: left,
+ right: right});
+ }
+
+ //If scroll greater than ending position, set to end
+ else if(scroll > settings.end)
+ {
+ $(obj).css({
+ position : 'absolute',
+ top: 0,
+ left: 0,
+ right: 0});
+
+ $("#scrollcontainer"+ StickyScroller.counter).css({
+ position : 'absolute',
+ top: settings.end+settings.margin,
+ left: left,
+ right: right});
+
+ }
+
+ //Make sure we stay in the specified boundaries
+ else
+ {
+ //Put back to fixed
+ $(obj).css({
+ position : 'fixed',
+ top: settings.margin,
+ left: left,
+ right: right});
+ }
+
+ //If in the specified range and a new index, do the callback
+ if(settings.oldIndex !== settings.index)
+ {
+ Callback.newIndex(settings.index);
+ }
+
+ //Do the "limbo" call back, which is a callback that executes when
+ //the scroller is not in the range, but still between start and end
+ if( !$this.inRange() && scroll > settings.start && scroll < settings.end )
+ {
+ Callback.limbo(settings.index);
+ }
+
+ //Do the scroll callback regardless of what happens
+ Callback.scroll(settings.index);
+ });
+}
6 StickyScroller.min.js
@@ -0,0 +1,6 @@
+/************************************************************/
+// Class StickyScroller
+// Purpose: Create a fixed scroller
+/************************************************************/
+
+function StickyScroller(f,g){if(typeof StickyScroller.counter==='undefined'){StickyScroller.counter=0;}else{StickyScroller.counter++;}var h=this;var i=$(f).css('top');var j=$(f).css('left');var k=$(f).css('right');var l=0;var m=0;var n={start:0,end:10000,interval:$(f).height(),margin:parseInt(i,10),range:$(f).height()},settings=jQuery.extend(n,g);f=$(f);settings.index=0;settings.oldIndex=0;GetSet.getters({scope:h,obj:settings});var o={};o.newIndex=function(){};o.limbo=function(){};o.scroll=function(){};GetSet.setters({scope:this,prefix:"on",obj:o});this.distanceFrom=function(a){var b=a*settings.interval+settings.start;var c=a*settings.interval+settings.range+settings.start;var d=Math.abs(l-b);var e=Math.abs(l-c);if(d<e){return d;}else{return e;}};this.closestIndex=function(){if(settings.index===0){return 1;}var a=this.distanceFrom(settings.index-1);var b=this.distanceFrom(settings.index+1);if(a<=b){return settings.index-1;}else{return settings.index+1;}};var p=function(){if(l>settings.start&&l<settings.end){tempIndex=Math.floor((l-settings.start)/settings.interval);if(tempIndex!==settings.index){settings.oldIndex=settings.index;settings.index=tempIndex;}}else if(l>=settings.end){settings.oldIndex=settings.index;settings.index=Math.floor((settings.end-settings.start)/settings.interval);}else{settings.oldIndex=settings.index;settings.index=0;}};this.firstIndex=function(){return 0;};this.lastIndex=function(){return Math.floor((settings.end-settings.start+settings.margin)/settings.interval);};this.inRange=function(){var a=settings.index*settings.interval+settings.start;var b=settings.index*settings.interval+settings.start+settings.range;var c=(l>=a)&&(l<=b);return c;};var q=$('<div id="scrollcontainer'+StickyScroller.counter+'">').css({width:f.width(),height:f.height(),position:"absolute",top:i,left:j,right:k});f.wrap(q);$(window).scroll(function(){l=$(window).scrollTop();p();if(l<settings.start){$(f).css({position:'absolute',top:0,left:0,right:0});$("#scrollcontainer"+StickyScroller.counter).css({position:'absolute',top:settings.start+settings.margin,left:j,right:k});}else if(l>settings.end){$(f).css({position:'absolute',top:0,left:0,right:0});$("#scrollcontainer"+StickyScroller.counter).css({position:'absolute',top:settings.end+settings.margin,left:j,right:k});}else{$(f).css({position:'fixed',top:settings.margin,left:j,right:k});}if(settings.oldIndex!==settings.index){o.newIndex(settings.index);}if(!h.inRange()&&l>settings.start&&l<settings.end){o.limbo(settings.index);}o.scroll(settings.index);});}
41 demo.css
@@ -0,0 +1,41 @@
+#main{
+margin-top: 0px;
+margin-left: 30px;
+}
+ #scrollbox{
+ position: fixed;
+ top: 400px;
+ left: 50px;
+ width: 100px;
+ background-color: #FF0000;
+ height: 100px;
+ }
+
+ #blocks{
+ margin-top: 400px;
+ }
+
+ .block{
+ margin: 0px 0px 100px 130px;
+ height: 200px;
+ width: 200px;
+ background-color: #000000;
+ }
+
+ #blankspace{
+ height: 1000px;
+ }
+
+ .blue{
+ background-color: #000099;
+ }
+
+ #info{
+ position: absolute;
+ top: 0px;
+ left: 250px;
+ }
+
+ .blue{
+ background-color: #000099;
+ }
68 demo.php
@@ -0,0 +1,68 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>Sticky Scroller</title>
+ <link rel="stylesheet" type="text/css" href="demo.css" />
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
+ <script type="text/javascript" src="http://www.vertstudios.com/vertlib.min.js"></script>
+ <script type="text/javascript" src="StickyScroller.min.js"></script>
+ <script type="text/javascript" src="GetSet.js"></script>
+
+
+ <script type="text/javascript">
+ $(window).load(function()
+ {
+ var scroller = new StickyScroller("#scrollbox",
+ {
+ start: 300,
+ end: 1800,
+ interval: 300,
+ range: 100,
+ margin: 100
+ });
+
+ var opacity = .25;
+ var fadeTime = 500;
+ var current;
+
+ //Apply opacity to all but first item.
+ $(".block").slice(1).css('opacity', opacity);
+
+
+ scroller.onNewIndex(function(index)
+ {
+ $("#scrollbox").html("Index " + index);
+ });
+
+ scroller.onScroll(function(index)
+ {
+ if(scroller.inRange())
+ {
+ current = $(".block").eq(index).css("opacity", 1);
+ $(".block").not(current).css("opacity", opacity);
+ }
+ });
+
+
+ });
+
+ </script>
+
+</head>
+<body>
+ <div id="main">
+ <div id="scrollbox">Index 0</div>
+ <div id="blocks">
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div id="blankspace"></div>
+ </div>
+ </div>
+
+</body>
+</html>
49 demo2.css
@@ -0,0 +1,49 @@
+#main{
+margin-top: 0px;
+margin-left: 30px;
+}
+ #scrollbox{
+ position: fixed;
+ top: 100px;
+ left: 50px;
+ width: 100px;
+ background-color: #FF0000;
+ height: 100px;
+ }
+
+ #code{
+ position: fixed;
+ top: 85px;
+ left: 400px;
+ width: 400px;
+ height: 200px;
+ }
+
+ #blocks{
+ margin-top: 100px;
+ }
+
+ .block{
+ margin: 0px 0px 100px 130px;
+ height: 200px;
+ width: 200px;
+ background-color: #000000;
+ }
+
+ #blankspace{
+ height: 1000px;
+ }
+
+ .blue{
+ background-color: #000099;
+ }
+
+ #info{
+ position: absolute;
+ top: 0px;
+ left: 250px;
+ }
+
+ .blue{
+ background-color: #000099;
+ }
71 demo2.php
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>Sticky Scroller</title>
+ <link rel="stylesheet" type="text/css" href="demo2.css" />
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
+ <script type="text/javascript" src="http://www.vertstudios.com/vertlib.min.js"></script>
+ <script type="text/javascript" src="StickyScroller.min.js"></script>
+ <script type="text/javascript" src="GetSet.js"></script>
+
+
+ <script type="text/javascript">
+ $(window).load(function()
+ {
+ var options = {
+ start: 0,
+ end: 1200,
+ interval: 300,
+ range: 100
+ }
+ var scroller = new StickyScroller("#scrollbox", options);
+ var code = new StickyScroller("#code", options);
+
+ scroller.onNewIndex(function(index)
+ {
+ $("#scrollbox").html("Index " + index);
+ });
+
+ scroller.onScroll(function(index)
+ {
+ if(scroller.inRange())
+ {
+
+ }
+ });
+ });
+ </script>
+
+</head>
+<body>
+ <div id="main">
+ <div id="scrollbox">Index 0</div>
+ <div id="code"><pre>
+ var options = {
+ start: 0,
+ end: 1200,
+ interval: 300
+ }
+ var scroller = new StickyScroller("#scrollbox", options);
+ var code = new StickyScroller("#code", options);
+
+ scroller.onNewIndex(function(index)
+ {
+ $("#scrollbox").html("Index " + index);
+ });
+ </pre></div>
+
+ <div id="blocks">
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div class="block"></div>
+ <div id="blankspace"></div>
+ </div>
+ </div>
+
+</body>
+</html>
BIN  diagram.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 readme.txt
@@ -0,0 +1,24 @@
+//------------------------------------------
+// jQuery Sticky Scroller
+//------------------------------------------
+
+Example call:
+var scroller = new StickyScroller("#scrollbox",
+{
+ start: 300,
+ end: 1800,
+ interval: 300,
+ range: 100,
+ margin: 100
+});
+
+Property descriptions.
+start: At what vertical position of the scrollbar the object will actually begin scrolling (in pixels)
+end: At what vertical position of the scrollbar the object will stop scrolling (in pixels)
+margin: How many pixels below the browser window the object will be fixed while scrolling (in pixels)
+interval: The length of each index (in pixels)
+range: Length of a range of pixels starting at the top of interval. Convenient for callbacks.
+
+To see full documentation, head over to
+http://www.vertstudios.com/blog/jquery-sticky-scroller-position-fixed-plugin/
+
Please sign in to comment.
Something went wrong with that request. Please try again.