-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.motion.js
104 lines (97 loc) · 3.8 KB
/
jquery.motion.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(function($){
$.fn.withMotion = function(mover, speed, callback, spacerClass, maxEffected){
var that = this;
return function(){
$(that).motion(mover, speed, callback, spacerClass, maxEffected);
};
};
$.fn.motion = function(mover, speed, callback, spacerClass, maxEffected){
var config = {
spacerClass: "__spacer__",
callback: $.noop || function(){},
maxEffected: 100,
speed: "medium"
};
if ($.isFunction(mover)){
$.extend(
config,
{
mover: mover,
callback: callback,
spacerClass: spacerClass,
maxEffected: maxEffected
});
} else {
$.extend(config,mover);
}
var effected = this;
if (effected.length > config.maxEffected){
config.mover.call(this);
config.callback();
return;
}
// step 1: go through effected elements and save their current position.
effected.each(
function(){
$.data(this, "fromPosition", $(this).offset());
});
config.mover.call(this);
var animating = 0;
var spacers = [];
function check(){
if (animating === 0){
effected.css({position:'', left:'', top:''});
for (var i=0,ii=spacers.length; i<ii; i++){
spacers[i].remove();
}
config.callback();
}
}
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
effected.each(
function(){
// save new position of effected element
var $this = $(this);
var toPosition = $this.offset();
var fromPosition = $.data(this, "fromPosition");
if (!toPosition || !fromPosition){
// probably removed
return;
}
/**
* animate the effected element. This will automatically skip over elements which:
* a) have not actually moved
* b) are not within the viewable window space.
*/
if ((fromPosition.top != toPosition.top || fromPosition.left != toPosition.left) &&
((fromPosition.top < docViewBottom && fromPosition.top >= docViewTop) ||
(toPosition.top < docViewBottom && toPosition.top >= docViewTop))){
// add spacers for effected element
var spacer = $('<'+this.tagName+' class="'+this.className+' '+config.spacerClass+'">'
+ '</'+this.tagName+'>')
.css(
{
height: $this.height(),
width: $this.width()
});
spacers.push(spacer);
$this.after(spacer);
$this.css({position:'absolute',
top:fromPosition.top+"px",
left:fromPosition.left+"px"});
$this.animate(
{
top:toPosition.top+"px",
left:toPosition.left+"px"
},
config.speed,
function(){
animating--;
check();
});
animating++;
}
});
};
})(jQuery);