Skip to content

Commit

Permalink
@janpaepke updates new options triggerAtCenter and playoutAnimations,…
Browse files Browse the repository at this point in the history
… new functions updatePin and triggerCheckAnim, fix positioning of certain elements, fix pinning after refresh, add support for repeat animations
  • Loading branch information
johnpolacek committed Dec 18, 2012
1 parent 8414465 commit 53d5115
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 65 deletions.
2 changes: 1 addition & 1 deletion css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ blockquote {
#title-line3 { top: -120px; }
.title-line span { display: inline-block; line-height: 1.1; position: relative; }
.twitter-follow-button { position: relative; top: 8px; left: 4px; }
#title-info { position: relative; z-index:99998; }
#title-info { position: relative; z-index:99998; margin-top: 40px; opacity: 0; }

.credit {
font-size: 20px;
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ <h1>Credits</h1>
TweenMax.from( $('#title-line3 .char4'), .5+Math.random(), {css:{top: '-200px', left:'1000px'}, ease:Elastic.easeOut}),
TweenMax.from( $('#title-line3 .char5'), .5+Math.random(), {css:{top: '200px', left:'1000px'}, ease:Elastic.easeOut})
])
.from( $('#title-info'), 1, {css:{opacity:0, 'margin-top':40}, delay:-1, ease:Quad.easeOut});
.to( $('#title-info'), .5, {css:{opacity:.99, 'margin-top':0}, delay:-1, ease:Quad.easeOut});

function initScrollAnimations() {
$('#content-wrapper').css('display','block');
Expand Down
197 changes: 134 additions & 63 deletions js/jquery.superscrollorama.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
/*
SUPERSCROLLORAMA - The jQuery plugin for doing scroll animations
by John Polacek (@johnpolacek)
Powered by the Greensock Tweening Platform
http://www.greensock.com
Greensock License info at http://www.greensock.com/licensing/
Dual licensed under MIT and GPL.
Thanks to Jan Paepke (@janpaepke) for making various improvements
*/

(function($) {

$.superscrollorama = function(options) {

var superscrollorama = this;
var defaults = {isVertical:true};
var defaults = {
isVertical:true, // are we scrolling vertically or horizontally?
triggerAtCenter: true, // the animation triggers when the respective Element's origin is in the center of the scrollarea. This can be changed here to be at the edge (-> false)
playoutAnimations: true // when scrolling past the animation should they be played out (true) or just be jumped to the respective last frame (false)?
};
superscrollorama.settings = $.extend({}, defaults, options);


// PRIVATE VARS

var animObjects = [],
pinnedObjects = [],
didScrollCheck = false;

// PRIVATE FUNCTIONS

function init() {
// scroll to top of page
$('html, body').animate({ scrollTop: 0 }, 0);

$(window).scroll(function() {
didScrollCheck = true;
});
Expand All @@ -42,19 +45,37 @@
didScrollCheck = false;
}
}


// reset a pin Object
function resetPinObj (pinObj) {
pinObj.el.css('position',pinObj.origPosition);
pinObj.el.css('top', pinObj.origPositioning.top);
pinObj.el.css('bottom', pinObj.origPositioning.bottom);
pinObj.el.css('left', pinObj.origPositioning.left);
pinObj.el.css('right', pinObj.origPositioning.right);
}

// set a Tween Progress (use totalProgress for TweenMax and TimelineMax to include repeats)
function setTweenProgress(tween, progress) {
if (tween.totalProgress) {
tween.totalProgress(progress).pause();
} else {
tween.progress(progress).pause();
}
}

function checkScrollAnim() {
var currScrollPoint = superscrollorama.settings.isVertical ? $(window).scrollTop() : $(window).scrollLeft();
var offsetAdjust = superscrollorama.settings.isVertical ? -$(window).height()/2 : -$(window).width()/2;
var offsetAdjust = superscrollorama.settings.triggerAtCenter ? (superscrollorama.settings.isVertical ? -$(window).height()/2 : -$(window).width()/2) : 0;
var i, startPoint, endPoint;

// check all animObjects
var numAnim = animObjects.length;
for (i=0; i<numAnim; i++) {
var animObj = animObjects[i],
target = animObj.target,
offset = animObj.offset;

if (typeof(target) === 'string') {
startPoint = superscrollorama.settings.isVertical ? $(target).offset().top : $(target).offset().left;
offset += offsetAdjust;
Expand All @@ -66,95 +87,111 @@
startPoint = superscrollorama.settings.isVertical ? target.offset().top : target.offset().left;
offset += offsetAdjust;
}

startPoint += offset;
endPoint = animObj.dur ? startPoint + animObj.dur : startPoint;

if ((currScrollPoint > startPoint && currScrollPoint < endPoint) && animObj.state !== 'TWEENING') {
// if it should be TWEENING and isn't..
animObj.state = 'TWEENING';
animObj.start = startPoint;
animObj.end = endPoint;
animObj.tween.progress((currScrollPoint - animObj.start)/(animObj.end - animObj.start)).pause();
setTweenProgress(animObj.tween, (currScrollPoint - animObj.start)/(animObj.end - animObj.start));
} else if (currScrollPoint < startPoint && animObj.state !== 'BEFORE') {
// if it should be at the BEFORE tween state and isn't..
animObj.tween.reverse();
if (superscrollorama.settings.playoutAnimations) {
animObj.tween.reverse();
} else {
setTweenProgress(animObj.tween, 0);
}
animObj.state = 'BEFORE';
} else if (currScrollPoint > endPoint && animObj.state !== 'AFTER') {
// if it should be at the AFTER tween state and isn't..
animObj.tween.play();
if (superscrollorama.settings.playoutAnimations) {
animObj.tween.play();
} else {
setTweenProgress(animObj.tween, 1);
}
animObj.state = 'AFTER';
} else if (animObj.state === 'TWEENING') {
// if it is TWEENING..
animObj.tween.progress((currScrollPoint - animObj.start)/(animObj.end - animObj.start)).pause();
setTweenProgress(animObj.tween, (currScrollPoint - animObj.start)/(animObj.end - animObj.start));
}
}

// check all pinned elements
var numPinned = pinnedObjects.length;
for (i=0; i<numPinned; i++) {
var pinObj = pinnedObjects[i];
var el = pinObj.el;
var elHeight = el.outerHeight();

// should object be pinned?
if (pinObj.state != 'PINNED') {


if (pinObj.state === 'UPDATE') resetPinObj(pinObj); // revert to original Position so startPoint and endPoint will be calculated to the correct values

startPoint = pinObj.spacer ?
superscrollorama.settings.isVertical ? pinObj.spacer.offset().top : pinObj.spacer.offset().left :
superscrollorama.settings.isVertical ? el.offset().top : el.offset().left;

startPoint += pinObj.offset;

endPoint = startPoint + pinObj.dur;

if (currScrollPoint > startPoint && currScrollPoint < endPoint) {
// pin it
var oldState = pinObj.state;
pinObj.state = 'PINNED';
// set original position value for unpinning
pinObj.origPositionVal = superscrollorama.settings.isVertical ? el.css('top') : el.css('left');
if (pinObj.origPositionVal === 'auto')
pinObj.origPositionVal = 0;
else
pinObj.origPositionVal = parseInt(pinObj.origPositionVal, 10);


// set original position values for unpinning
pinObj.origPositioning = {
top: el.css('top'),
left: el.css('left'),
bottom: el.css('bottom'),
right: el.css('right')
};
// change to fixed position
var realCoordinates = el.offset();
el.css('position','fixed');
if (superscrollorama.settings.isVertical)
if (superscrollorama.settings.isVertical) {
el.css('top', -pinObj.offset);
else
el.css('left', realCoordinates.left); // translate from position in parent to fixed
} else {
el.css('left', -pinObj.offset);

el.css('top', realCoordinates.top); // translate from position in parent to fixed
}

pinObj.pinStart = startPoint;
pinObj.pinEnd = endPoint;

if (pinObj.spacer)
pinObj.spacer.css('height', pinObj.dur + elHeight);

if (pinObj.onPin)
if (oldState === "UPDATE") {
if (pinObj.anim)
setTweenProgress(pinObj.anim, 0); // reset the progress, otherwise the animation won't be updated to the new position
} else if (pinObj.onPin) {
pinObj.onPin();
}
}

// Check to see if object should be unpinned
// update immediately (we may be further in the animation already, i.e. refresh within the pinrange or a pinUpdate was run)
setTweenProgress(pinObj.anim, (currScrollPoint - pinObj.pinStart)/(pinObj.pinEnd - pinObj.pinStart));
}
} else {

// Check to see if object should be unpinned
if (currScrollPoint < pinObj.pinStart || currScrollPoint > pinObj.pinEnd) {

// unpin it
pinObj.state = currScrollPoint < pinObj.pinStart ? 'BEFORE' : 'AFTER';
if (pinObj.anim&&pinObj.state === 'BEFORE') {
pinObj.anim.progress(0);
setTweenProgress(pinObj.anim, 0);
} else if (pinObj.anim && pinObj.state === 'AFTER'){
pinObj.anim.progress(1);
setTweenProgress(pinObj.anim, 1);
}
// revert to original position value
el.css('position',pinObj.origPosition);
if (superscrollorama.settings.isVertical)
el.css('top', pinObj.origPositionVal);
else
el.css('left', pinObj.origPositionVal);

// revert to original position values
resetPinObj(pinObj);

if (pinObj.spacer)
pinObj.spacer.css('height', currScrollPoint < pinObj.pinStart ? 0 : pinObj.dur);

Expand All @@ -163,40 +200,39 @@
}
else if (pinObj.anim) {
// do animation
pinObj.anim.progress((currScrollPoint - pinObj.pinStart)/(pinObj.pinEnd - pinObj.pinStart));
setTweenProgress(pinObj.anim, (currScrollPoint - pinObj.pinStart)/(pinObj.pinEnd - pinObj.pinStart));
}
}
}

}

// PUBLIC FUNCTIONS
superscrollorama.addTween = function(target, tween, dur, offset) {

tween.pause();

animObjects.push({
target:target,
tween: tween,
offset: offset || 0,
dur: dur || 0,
state:'BEFORE'
});

return superscrollorama;
};

superscrollorama.pin = function(el, dur, vars) {
if (typeof(el) === 'string') el = $(el);
if (vars.anim) vars.anim.pause();

// create wrapper for pinned elements that aren't absolute or fixed position
var pinSpacer = null;
if (el.css('position') === 'relative' || el.css('position') === 'static') {
pinSpacer = $('<div class="pin-spacer"></div>');
el.before(pinSpacer);
}

pinnedObjects.push({
el:el,
state:'BEFORE',
Expand All @@ -208,15 +244,50 @@
onPin:vars.onPin,
onUnpin:vars.onUnpin
});


return superscrollorama;
};

superscrollorama.updatePin = function (el, dur, vars) { // Update a Pinned object. dur and vars are optional to only change vars and keep dur just pass NULL for dur
if (typeof(el) === 'string') el = $(el);
if (vars.anim) vars.anim.pause();
var numPinned = pinnedObjects.length;


for (i=0; i<numPinned; i++) {
var pinObj = pinnedObjects[i];
if (el.get(0) == pinObj.el.get(0)) {

if (dur) pinObj.dur = dur;
if (vars.anim) pinObj.anim = vars.anim;
if (vars.offset) pinObj.offset = vars.offset;
if (vars.onPin) pinObj.onPin = vars.onPin;
if (vars.onUnpin) pinObj.onUnpin = vars.onUnpin;

if ((dur || vars.anim || vars.offset) && pinObj.state === 'PINNED') { // this calls for an immediate update!
pinObj.state = 'UPDATE';
checkScrollAnim();
}
}
}

return superscrollorama;
};



superscrollorama.triggerCheckAnim = function (immediately) { // if immediately is true it will be updated right now, if false it will wait until next tweenmax tick. default is false
if (immediately) {
checkScrollAnim();
} else {
didScrollCheck = true;
}
return superscrollorama;
};


// INIT
init();

return superscrollorama;
};

})(jQuery);

0 comments on commit 53d5115

Please sign in to comment.