-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathjquery.embedly.scrollplay.js
150 lines (122 loc) · 3.69 KB
/
jquery.embedly.scrollplay.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*globals jQuery:true, playerjs:true */
;(function ( $, window, document, undefined ) {
// An object that keeps track of all the iframes on the page.
var Scroller = function(iframes){
this.init(iframes);
};
Scroller.prototype.init = function(iframes){
this.data = [];
// create a player for each of the iframes.
iframes.each($.proxy(function(i, elem){
var $elem = $(elem);
// create the player.
var player = new playerjs.Player(elem);
// when the player is ready, add it to the rotatation
player.on('ready', function(){
player.unmute();
this.add($elem, player);
}, this);
}, this));
};
// Add the elements positioning data.
Scroller.prototype.add = function($elem, player){
var t = $elem.offset().top,
b = t + $elem.height();
this.data.push({
top: t,
bottom: b,
$elem: $elem,
player: player
});
};
// Called by the on scroll event.
Scroller.prototype.scrolled = function(){
var $window = $(window);
// Get the scrollTop and scrollBottom.
var t = $window.scrollTop();
var b = t + $window.height();
// It possible to have multiple videos inframe, so we only want to play
// the first one or the one that has the largest percentage in frame.
$.each($.map(this.data, function(obj, i){
// We need to find the percentage of the video that's in frame.
var p = 0;
// There is overlap of the window and iframe.
if (obj.top <= b && obj.bottom >= t) {
// Height of the embed.
var h = obj.bottom - obj.top;
// Based on the window, figure out percentages.
if (obj.bottom > b){
p = (b - obj.top) / h;
} else if (obj.top < t){
p = (obj.bottom - t) / h;
} else {
p = 1;
}
}
// Stripped down object of what we need.
return {
p: p,
t: obj.top,
player: obj.player
};
}).sort(function(a, b){
// sort based on percentages.
if (a.p > b.p){
return -1;
} else if (a.p < b.p) {
return 1;
}
// If the percentages are equal, use the one higher on the page.
if (a.t < b.t){
return -1;
} else if (a.t > b.t){
return 1;
}
return 0;
}), function(i, obj){
// the first obj in the list should be the one we want to play, but
// make sure it has at least a little inframe.
if (i === 0 && obj.p > 0.25){
obj.player.play();
} else {
// pause the rest.
obj.player.pause();
}
});
};
// Called when the window is resized. It allows use to update the data
// to with the new top and bottom. It's a bit faster to do this, as window
// resize isn't called all that often.
Scroller.prototype.resized = function(){
$.each(this.data, function(i, obj){
obj.top = obj.$elem.offset().top;
obj.bottom = obj.top + obj.$elem.height();
});
// We call scrolled here as most likely something went out of frame.
this.scrolled();
};
Scroller.prototype.listen = function($elem, player){
var $window = $(window);
// Listen to the scroll event.
$window.on('scroll', $.proxy(function(){
// Nothings ready yet.
if (this.data.length === 0){
return false;
}
this.scrolled();
}, this));
// Listen to the resize event.
$window.on('resize', $.proxy(function(){
// Nothings ready yet.
if (this.data.length === 0){
return false;
}
this.resized();
}, this));
};
$.fn.scrollplay = function() {
var scroller = new Scroller(this);
scroller.listen();
return this;
};
})( jQuery, window, document );