Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
Merge pull request #25 from Pita/ce919ecdf3019d5aae1bbc73bf1dca13a5db…
Browse files Browse the repository at this point in the history
…9bf1

Fixes issue #22 and #23 updating PEP and resolving issues being able to be dragged from parent
  • Loading branch information
JohnMcLear committed May 31, 2012
2 parents ba7db7a + ce919ec commit 7318bf9
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 82 deletions.
243 changes: 170 additions & 73 deletions static/js/jquery.pep.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/***************************************************
* Pep! (jquery.pep.js)
/*******************************************************************
* Pep! (jquery.pep.js)
* [ Version 0.21 ]
* ----------------------------------------------------------
* Copyright 2012, Brian Gonzalez
* Dual licensed under the MIT or GPL Version 2 licenses.
*
*
* Dependencies:
* - jQuery
Expand All @@ -20,8 +23,8 @@
cssEaseString: "cubic-bezier(0.210, 1, 0.220, 1.000)",
cssEaseDuration: 1000,
constrainToWindow: false,
constrainToParent: false, // EXPERIMENTAL! use with caution. you've been warned.
shouldEase: true,
boundToParent: false,
drag: function(){},
start: function(){},
stop: function(){},
Expand All @@ -48,10 +51,11 @@
this._dt = null;
this._offset = null;
this._velocityQueue = [null,null,null,null,null];
this.tempFxn = {};
this._startTrigger = this._isTouch() ? "touchstart" : "mousedown";
this._endTrigger = this._isTouch() ? "touchend" : "mouseup";
this._moveTrigger = this._isTouch() ? "touchmove" : "mousemove";
this._positionType = this.options.boundToParent ? 'position' : 'offset';
this._positionType = this.options.constrainToParent ? 'position' : 'offset';
this.init();
}

Expand All @@ -60,61 +64,88 @@
var self = this;
var $this = $(this.el);

// build our debug div
if (this.options.debug && !($('#debug').length > 0) ) $('body').append("<div id='debug' style='position: fixed; bottom: 0; right: 0; z-index: 10000; text-align: right'>debug mode</div>");
if (this.options.debug && !($('#debug').length > 0) )
this._buildDebugDiv();

// Bind the magic
$this.bind( this._startTrigger, function(e){ self._do(e); } );
};

Pep.prototype._bindings = function(){};

Pep.prototype._do = function(event){

// Non-touch device or non-pinch on touch device?
// Non-touch device -- or -- non-pinch on touch device?
if ( !this._isTouch() || ( this._isTouch() && event.originalEvent.hasOwnProperty('touches') && event.originalEvent.touches.length == 1 ) ){
event.preventDefault();
var self = this;
var $this = $(this.el);
if( $this.hasClass( self.options.activeClass ) ) $.fn.pep.stopping();
var self = this;
var $this = $(this.el);
$this.addClass( this.options.activeClass );
this._x = self._isTouch() ? event.originalEvent.pageX : event.pageX;
this._y = self._isTouch() ? event.originalEvent.pageY : event.pageY;
this._startX = this._x;
this._startY = this._y;
this._start = true;
this._active = true;
this._started = false;
this._x = self._isTouch() ? event.originalEvent.pageX : event.pageX;
this._y = self._isTouch() ? event.originalEvent.pageY : event.pageY;
this._startX = this._x;
this._startY = this._y;
this._start = true;
this._active = true;
this._started = false;
this._moveEvent = null;
this._container = this.options.constrainToParent ? $this.parent() : $(window);
self._log( this._startTrigger );

// remove CSS3 animation
$this.css( self._cssEaseHashReset() );

// dragging
$.fn.pep.dragging = function(event){

// ----------------------------------------------
// stopping -------------------------------------
var _doStop = function(event){
if ( self._active ){
if (self.options.shouldEase) self._ease();
self._doRest(event, self);
self._container.unbind( self._moveTrigger, _doDrag );
$(window).unbind( self._endTrigger, _doStop );
self._log( self._endTrigger );
self._active = false;
self._velocityQueue = [null,null,null,null,null];

// fire user's stop event.
self.options.stop(event, self);
}
};
$(window).bind( this._endTrigger + " " + this.options.stopEvents, _doStop ); // ... then bind our stop trigger


// -------------------------------------------------
// dragging ----------------------------------------
var _doDrag = function(event){

// Stop all drag events
if (disable) {
//$(self.el).trigger( self._endTrigger );
$.fn.pep.stopping();
_doStop();
return;
}

self._offset = $this[self._positionType]();

// fire user's drag event.
self.options.drag(event, self);

var curX = (self._isTouch() ? event.originalEvent.touches[0].pageX : event.pageX);
var curY = (self._isTouch() ? event.originalEvent.touches[0].pageY : event.pageY);


// make `relative` parent if constrainToParent
if ( self.options.constrainToParent ){
self._handleParentRelative();
$this.css({ position: 'absolute' });
}

// put our target element exectly where it is...
// but make it movable (pos absolute)
if ($this.css('position') !== 'absolute') {
$this.css({ position: 'absolute', top: self._offset.top, left: self._offset.left});
}
self._offset = $this[self._positionType]();
$this.css({ position: 'absolute', top: self._offset.top, left: self._offset.left, zIndex: 1});

// remove `relative` parent if !constrainToParent
if ( !self.options.constrainToParent )
self._handleParentRelative();

// LIFO queue to help us manage velocity
// Last in, first out (LIFO) queue to help us manage velocity
self._lifo( { time: event.timeStamp, x: curX, y: curY } );

// mouse off screen? -10 is a buffer
Expand All @@ -129,28 +160,12 @@
var xOp = ( dx >= 0 ) ? "+=" + Math.abs(dx / self._scale)*mult : "-=" + Math.abs(dx / self._scale)*mult;
var yOp = ( dy >= 0 ) ? "+=" + Math.abs(dy / self._scale)*mult : "-=" + Math.abs(dy / self._scale)*mult;

if (self.options.boundToParent) {
var pos = $this.position();
var $parent = $this.parent();

pos.right = $parent.width() - $this.width();
pos.bottom = $parent.height() - $this.outerHeight();

if (pos.left >= pos.right && dx > 0) {
xOp = pos.right;
}

if (pos.left <= 0 && dx <= 0) {
xOp = 0;
}

if (pos.top >= pos.bottom && dy > 0) {
yOp = pos.bottom;
}

if (pos.top <= 0 && dy <= 0) {
yOp = 0;
}
// If `constrainToParent` option is set, return if
// we hit the edge and we're moving in the direction
if (self.options.constrainToParent) {
var hash = self._handleConstrainToParent(dx, dy);
xOp = (hash.x !== false) ? hash.x : xOp;
yOp = (hash.y !== false) ? hash.y : yOp;
}

self._x = curX;
Expand All @@ -163,31 +178,28 @@
self.options.start(event, self);
self._started = true;
}

$this.css({ top: yOp , left: xOp });

$this.css({ top: yOp , left: xOp }); // move it....

self._log( [self._moveTrigger, ", ", curX, " ", self._xDir, ", ", curY, " ", self._yDir].join('') );
self._start = false;
};

$(window).bind( this._moveTrigger, $.fn.pep.dragging ); // ... then bind out drag trigger
// this._container.bind( this._moveTrigger, _doDrag );

// stop
$.fn.pep.stopping = function(event){
if ( self._active ){
if (self.options.shouldEase) self._ease();
self._doRest(event, self);
$(window).unbind( self._moveTrigger, $.fn.pep.dragging );
$this.unbind( self._endTrigger, $.fn.pep.stopping );
self._log( self._endTrigger );
self._active = false;
self._velocityQueue = [null,null,null,null,null];
$this.removeClass( self.options.activeClass );

// fire user's stop event.
self.options.stop(event, self);
}
var storeMoveEvent = function(event){
self._moveEvent = event;
};
$(window).bind( this._endTrigger + " " + this.options.stopEvents, $.fn.pep.stopping ); // ... then bind our stop trigger

this._container.bind( this._moveTrigger, storeMoveEvent ); // ... then bind our drag trigger

(function watchMoveLoop(){
if ( !self._active ) return;
_pepRequestAnimFrame(watchMoveLoop);
if (self._moveEvent !== null ) _doDrag(self._moveEvent);
})($, self, _doDrag);


}
};

Expand All @@ -207,9 +219,10 @@
this.options.shouldEase = true;
};

Pep.prototype._isTouch = function(){ return ('ontouchstart' in document.documentElement); };
Pep.prototype.setScale = function(val){ this._scale = val; };

Pep.prototype._isTouch = function(){ return ('ontouchstart' in document.documentElement); };

Pep.prototype._log = function(msg){
if (this.options.debug){
if ( $('#msg').length == 0 ) $('#debug').append("<div id='msg'></div><div id='velocity'></div>");
Expand Down Expand Up @@ -244,12 +257,26 @@

Pep.prototype._ease = function(){
$this = $(this.el);
var pos = $this.position();
var vel = this._velocity();
var dt = this._dt;
var mult = 1;

var dimHash = this._dimensionHash();
var upperXLimit = dimHash.parent.width - dimHash.self.width;
var upperYLimit = dimHash.parent.height - dimHash.self.height;

var x = ( vel.x > 0 ) ? "+=" + vel.x * mult : "-=" + Math.abs(vel.x) * mult;
var y = ( vel.y > 0 ) ? "+=" + vel.y * mult : "-=" + Math.abs(vel.y) * mult;

if ( this.options.constrainToParent ){
x = ( pos.left + vel.x < 0 ) ? 0 : x;
y = ( pos.top + vel.y < 0 ) ? 0 : y;

x = ( pos.left + vel.x > upperXLimit ) ? upperXLimit : x;
y = ( pos.top + vel.y > upperYLimit ) ? upperYLimit : y;
}

// . The CSS3 easing magic .
$this.css( this._cssEaseHash( this.options.cssEaseDuration, this.options.cssEaseString ) );
$this.css({ top: y, left: x });
Expand Down Expand Up @@ -290,8 +317,61 @@

Pep.prototype._doRest = function(event, obj){
var self = this;
this.timeout = setTimeout( function(){ self.options.rest(event, obj); }, self.options.cssEaseDuration );
}

this.timeout = setTimeout( function(){
self.options.rest(event, obj);
$(self.el).removeClass( self.options.activeClass );
}, self.options.cssEaseDuration );
};

Pep.prototype._buildDebugDiv = function() {
$('body').append("<div id='debug' style='position: fixed; bottom: 0; right: 0; z-index: 10000; text-align: right'>debug mode</div>");
};

Pep.prototype._handleParentRelative = function() {
if (this.options.constrainToParent){
$(this.el).parent().css({ position: 'relative' });
}
else{
$(this.el).parent().css({ position: 'static' });
}
};

Pep.prototype._handleConstrainToParent = function(dx, dy) {
var $this = $(this.el);
var pos = $this.position();
var posX = pos.left;
var posY = pos.top;
var dimHash = this._dimensionHash();
var upperXLimit = dimHash.parent.width - dimHash.self.width;
var upperYLimit = dimHash.parent.height - dimHash.self.height;
var hash = { x: false, y: false };

// is our object moving near our lower X & Y limits?
if (posX <= 0 && dx < 0 ) hash.x = 0;
if (posY <= 0 && dy < 0) hash.y = 0;

// is our object moving near our upper X & Y limits?
if (posX >= upperXLimit && dx > 0) hash.x = upperXLimit;
if (posY >= upperYLimit && dy > 0) hash.y = upperYLimit;

return hash;

};

Pep.prototype._dimensionHash = function() {
var $this = $(this.el);

var hash = { self : {
width: $this.outerWidth(),
height: $this.outerHeight() } ,
parent : { width: $this.parent().width(),
height: $this.parent().height() }
}

return hash;

};

// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
Expand All @@ -315,3 +395,20 @@
};

})( jQuery, window, document );


//
// requestAnimationFrame Polyfill
// More info:
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
//
window._pepRequestAnimFrame = (function(callback) {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
Loading

0 comments on commit 7318bf9

Please sign in to comment.