Last active
December 10, 2015 13:08
-
-
Save hapticdata/4439271 to your computer and use it in GitHub Desktop.
starting point for binding an event (such as scroll) with various properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
example: | |
new ParallaxSprite({ | |
el: $('#element'), | |
watch: { | |
fn: function(){ return $(window).scrollTop(); }, | |
from: 0, | |
to: 1000 | |
}, | |
tween: { | |
'top': { | |
from: 0, | |
to: -500 | |
}, | |
'box-shadow': { | |
from: 0, | |
to: 4 | |
} | |
} | |
}); | |
or use html: | |
<img src="img.jpg" data-plax-watch-from="0" data-plax-watch-to="1000" data-plax-tween="top" data-plax-tween-from="1000" data-plax-tween-to="-100" > | |
$('[data-plax-watch-to]').each(function(){ parallaxSprite({ el: this }); }); | |
*/ | |
define(function( require, exports, module ){ | |
var $ = require('jquery'), | |
_ = require('underscore'), | |
Backbone = require('backbone'), | |
Rect = require('toxi/geom/Rect'), | |
ScaleMap = require('toxi/math/ScaleMap'); | |
var ParallaxSprite = Backbone.View.extend({ | |
tagName: 'div', | |
className: 'parallax-sprite', | |
initialize: function(){ | |
_.bindAll(this,'applyTween','bindScroll','__renderFirst','render'); | |
}, | |
applyTween: function(){ | |
//update the css, via the scalemap for every property | |
var css = {}; | |
for( var prop in this.tween ){ | |
css[prop] = this.tween[prop].current; | |
} | |
this.$el.css( css ); | |
}, | |
bindScroll: function(){ | |
if( !this.rendered ){ | |
this.render(); | |
} | |
$(window).scroll(this.render); | |
return this; | |
}, | |
eachTween: function( fn ){ | |
for( var prop in this.tween ){ | |
fn( this.tween[prop], prop ); | |
} | |
return this; | |
}, | |
isAtBeginning: function(){ | |
for( var prop in this.tween ){ | |
if( this.tween[prop].current !== this.tween[prop].from ){ | |
return false; | |
} | |
} | |
return true; | |
}, | |
isAtEnd: function(){ | |
for( var prop in this.tween ){ | |
if( this.tween[prop].current !== this.tween[prop].to ){ | |
return false; | |
} | |
} | |
return true; | |
}, | |
__renderFirst: function(){ | |
var watchProp; | |
//this.rect = new Rect({ x: 0, y: this.offsetY, width: this.$el.width(), height: this.$el.height() }); | |
if( this.options.applyTween ){ | |
this.applyTween = this.options.applyTween; | |
} | |
if( this.options.watch ){ | |
this.watch = {}; | |
if( this.options.watch.fn ){ | |
this.watch.fn = this.options.watch.fn; | |
} else { | |
//there should be a watch: {property: "" } | |
//if there isnt, watch scrollTop | |
watchProp = this.options.watch.property || 'scrollTop'; | |
this.watch.fn = function(){ return $(window)[watchProp](); }; | |
} | |
this.watch.from = this.options.watch.from; | |
this.watch.to = this.options.watch.to; | |
} | |
if( this.options.tween ){ | |
this.tween = this.options.tween; | |
this.maps = {}; | |
//create a scalemap for every tweening property | |
for( var prop in this.tween ){ | |
this.maps[prop] = new ScaleMap({ | |
input: { | |
min: this.watch.from, | |
max: this.watch.to | |
}, | |
output: { | |
min: this.tween[prop].from, | |
max: this.tween[prop].to | |
} | |
}); | |
this.tween[prop].current = this.maps[prop].getClippedValueFor( this.watch.fn() ); | |
} | |
} | |
this.rendered = true; | |
this.__atBeginning = this.isAtBeginning(); | |
this.__atEnd = this.isAtEnd(); | |
}, | |
render: function(){ | |
if( !this.rendered ){ | |
this.__renderFirst(); | |
} | |
//get the current value for our watched property | |
var current = this.watch.fn(); | |
//update the css, via the scalemap for every property | |
var css = {}; | |
for( var prop in this.tween ){ | |
this.tween[prop].current = this.maps[prop].getClippedValueFor( current ); | |
} | |
if( this.__atBeginning && !this.isAtBeginning() ){ | |
this.trigger('begin'); | |
this.__atBeginning = false; | |
} else if( !this.__atEnd && this.isAtEnd() ){ | |
this.trigger('end'); | |
this.__atEnd = true; | |
} | |
this.applyTween(); | |
return this; | |
}, | |
remove: function(){ | |
this.unbindScroll(); | |
Backbone.View.prototype.remove.call(this); | |
}, | |
unbindScroll: function(){ | |
$(window).unbind('scroll', this.render ); | |
return this; | |
} | |
}); | |
exports = module.exports = function( opts ){ | |
opts = opts || {}; | |
var tweenProp; | |
if( opts.el ){ | |
var $el = $(opts.el); | |
if( !opts.watch ){ | |
opts.watch = {}; | |
opts.watch.property = $el.attr('data-plax-watch'); | |
if( opts.watch.property === undefined ){ | |
opts.watch.property = "scrollTop"; | |
} | |
opts.watch.from = Number( $el.attr('data-plax-watch-from') ); | |
if( isNaN( opts.watch.from ) ){ | |
opts.watch.from = 0; | |
} | |
opts.watch.to = Number( $el.attr('data-plax-watch-to') ); | |
if( isNaN( opts.watch.to ) ){ | |
throw Error("Invalid ParallaxSprite requested, no watch param or data-plax-watch attributes"); | |
} | |
} | |
if( !opts.tween ){ | |
opts.tween = {}; | |
tweenProp = $el.attr('data-plax-tween'); | |
if( tweenProp === undefined ){ | |
tweenProp = 'top'; | |
} | |
opts.tween[ tweenProp ] = { | |
from: Number( $el.attr('data-plax-tween-from') ), | |
to: Number( $el.attr('data-plax-tween-to') ) | |
}; | |
if( isNaN(opts.tween[tweenProp].from) ){ | |
opts.tween[tweenProp].from = 0; | |
} | |
if( isNaN(opts.tween[tweenProp].to) ){ | |
throw Error("Invalid ParallaxSprite, incorrect tween params or no data-plax-tween attributes"); | |
} | |
} | |
} | |
return new ParallaxSprite( opts ); | |
}; | |
exports.ParallaxSprite = ParallaxSprite; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment