PageSourceSearch

https://www.duaexplorer.com/Scripts/circle.player.js

js duaexplorer.com collected 2026-10-02 00:29:40 UTC 7,952 bytes, 244 lines download raw bytes

1/*
2 * CirclePlayer for the jPlayer Plugin (jQuery)
3 * http://www.jplayer.org
4 *
5 * Copyright (c) 2009 - 2011 Happyworm Ltd
6 * Dual licensed under the MIT and GPL licenses.
7 *  - http://www.opensource.org/licenses/mit-license.php
8 *  - http://www.gnu.org/copyleft/gpl.html
9 *
10 * Version: 1.0.1 (jPlayer 2.0.9)
11 * Date: 30th May 2011
12 *
13 * Author: Mark J Panaghiston @thepag
14 *
15 * CirclePlayer prototype developed by:
16 * Mark Boas @maboa
17 * Silvia Benvenuti @aulentina
18 * Jussi Kalliokoski @quinirill
19 *
20 * Inspired by :
21 * Neway @imneway http://imneway.net/ http://forrst.com/posts/Untitled-CPt
22 * and
23 * Liam McKay @liammckay http://dribbble.com/shots/50882-Purple-Play-Pause
24 *
25 * Standing on the shoulders of :
26 * John Resig @jresig
27 * Mark Panaghiston @thepag
28 * Louis-Rémi Babé @Louis_Remi
29 */
30
31var cir_width = 52;
32
33var CirclePlayer = function(jPlayerSelector, media, options) {
34	var	self = this,
35
36		defaults = {
37			// solution: "flash, html", // For testing Flash with CSS3
38			supplied: "m4a, oga",
39			// Android 2.3 corrupts media element if preload:"none" is used.
40			// preload: "none", // No point preloading metadata since no times are displayed. It helps keep the buffer state correct too.
41			cssSelectorAncestor: "#cp_container_1",
42			cssSelector: {
43				play: ".cp-play",
44				pause: ".cp-pause"
45			}
46		},
47
48		cssSelector = {
49			bufferHolder: ".cp-buffer-holder",
50			buffer1: ".cp-buffer-1",
51			buffer2: ".cp-buffer-2",
52			progressHolder: ".cp-progress-holder",
53			progress1: ".cp-progress-1",
54			progress2: ".cp-progress-2",
55			circleControl: ".cp-circle-control"
56		};
57
58	this.cssClass = {
59		gt50: "cp-gt50",
60		fallback: "cp-fallback"
61	};
62
63	this.spritePitch = cir_width;
64	this.spriteRatio = 0.5; // Number of steps / 100
65
66	this.player = $(jPlayerSelector);
67	this.media = $.extend({}, media);
68	this.options = $.extend(true, {}, defaults, options); // Deep copy
69
70	this.cssTransforms = Modernizr.csstransforms;
71	this.audio = {};
72	this.dragging = false; // Indicates if the progressbar is being 'dragged'.
73
74	this.eventNamespace = ".CirclePlayer"; // So the events can easily be removed in destroy.
75
76	this.jq = {};
77	$.each(cssSelector, function(entity, cssSel) {
78		self.jq[entity] = $(self.options.cssSelectorAncestor + " " + cssSel);
79	});
80
81	this._initSolution();
82	this._initPlayer();
83};
84
85CirclePlayer.prototype = {
86	_createHtml: function() {
87	},
88	_initPlayer: function() {
89		var self = this;
90		this.player.jPlayer(this.options);
91
92		this.player.bind($.jPlayer.event.ready + this.eventNamespace, function(event) {
93			if(event.jPlayer.html.used && event.jPlayer.html.audio.available) {
94				self.audio = $(this).data("jPlayer").htmlElement.audio;
95			}
96			$(this).jPlayer("setMedia", self.media);
97			self._initCircleControl();
98		});
99
100		this.player.bind($.jPlayer.event.play + this.eventNamespace, function(event) {
101			$(this).jPlayer("pauseOthers");
102		});
103
104		// This event fired as play time increments
105		this.player.bind($.jPlayer.event.timeupdate + this.eventNamespace, function(event) {
106			if (!self.dragging) {
107				self._timeupdate(event.jPlayer.status.currentPercentAbsolute);
108			}
109		});
110
111		// This event fired as buffered time increments
112		this.player.bind($.jPlayer.event.progress + this.eventNamespace, function(event) {
113			var percent = 0;
114			if((typeof self.audio.buffered === "object") && (self.audio.buffered.length > 0)) {
115				if(self.audio.duration > 0) {
116					var bufferTime = 0;
117					for(var i = 0; i < self.audio.buffered.length; i++) {
118						bufferTime += self.audio.buffered.end(i) - self.audio.buffered.start(i);
119						// console.log(i + " | start = " + self.audio.buffered.start(i) + " | end = " + self.audio.buffered.end(i) + " | bufferTime = " + bufferTime + " | duration = " + self.audio.duration);
120					}
121					percent = 100 * bufferTime / self.audio.duration;
122				} // else the Metadata has not been read yet.
123				// console.log("percent = " + percent);
124			} else { // Fallback if buffered not supported
125				// percent = event.jPlayer.status.seekPercent;
126				percent = 0; // Cleans up the inital conditions on all browsers, since seekPercent defaults to 100 when object is undefined.
127			}
128			self._progress(percent); // Problem here at initial condition. Due to the Opera clause above of buffered.length > 0 above... Removing it means Opera's white buffer ring never shows like with polyfill.
129			// Firefox 4 does not always give the final progress event when buffered = 100%
130		});
131
132		this.player.bind($.jPlayer.event.ended + this.eventNamespace, function(event) {
133			self._resetSolution();
134		});
135	},
136	_initSolution: function() {
137		if (this.cssTransforms) {
138			this.jq.progressHolder.show();
139			this.jq.bufferHolder.show();
140		}
141		else {
142			this.jq.progressHolder.addClass(this.cssClass.gt50).show();
143			this.jq.progress1.addClass(this.cssClass.fallback);
144			this.jq.progress2.hide();
145			this.jq.bufferHolder.hide();
146		}
147		this._resetSolution();
148	},
149	_resetSolution: function() {
150		if (this.cssTransforms) {
151			this.jq.progressHolder.removeClass(this.cssClass.gt50);
152			this.jq.progress1.css({'transform': 'rotate(0deg)'});
153			this.jq.progress2.css({'transform': 'rotate(0deg)'}).hide();
154		}
155		else {
156			this.jq.progress1.css('background-position', '0 ' + this.spritePitch + 'px');
157		}
158	},
159	_initCircleControl: function() {
160		var self = this;
161		this.jq.circleControl.grab({
162			onstart: function(){
163				self.dragging = true;
164			}, onmove: function(event){
165				var pc = self._getArcPercent(event.position.x, event.position.y);
166				self.player.jPlayer("playHead", pc).jPlayer("play");
167				self._timeupdate(pc);
168			}, onfinish: function(event){
169				self.dragging = false;
170				var pc = self._getArcPercent(event.position.x, event.position.y);
171				self.player.jPlayer("playHead", pc).jPlayer("play");
172			}
173		});
174	},
175	_timeupdate: function(percent) {
176		var degs = percent * 3.6+"deg";
177
178		var spriteOffset = (Math.floor((Math.round(percent))*this.spriteRatio)-1)*-this.spritePitch;
179
180		if (percent <= 50) {
181			if (this.cssTransforms) {
182				this.jq.progressHolder.removeClass(this.cssClass.gt50);
183				this.jq.progress1.css({'transform': 'rotate(' + degs + ')'});
184				this.jq.progress2.hide();
185			} else { // fall back
186				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
187			}
188		} else if (percent <= 100) {
189			if (this.cssTransforms) {
190				this.jq.progressHolder.addClass(this.cssClass.gt50);
191				this.jq.progress1.css({'transform': 'rotate(180deg)'});
192				this.jq.progress2.css({'transform': 'rotate(' + degs + ')'});
193				this.jq.progress2.show();
194			} else { // fall back
195				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
196			}
197		}
198	},
199	_progress: function(percent) {
200		var degs = percent * 3.6+"deg";
201
202		if (this.cssTransforms) {
203			if (percent <= 50) {
204				this.jq.bufferHolder.removeClass(this.cssClass.gt50);
205				this.jq.buffer1.css({'transform': 'rotate(' + degs + ')'});
206				this.jq.buffer2.hide();
207			} else if (percent <= 100) {
208				this.jq.bufferHolder.addClass(this.cssClass.gt50);
209				this.jq.buffer1.css({'transform': 'rotate(180deg)'});
210				this.jq.buffer2.show();
211				this.jq.buffer2.css({'transform': 'rotate(' + degs + ')'});
212			}
213		}
214	},
215	_getArcPercent: function(pageX, pageY) {
216		var	offset	= this.jq.circleControl.offset(),
217			x	= pageX - offset.left - this.jq.circleControl.width()/2,
218			y	= pageY - offset.top - this.jq.circleControl.height()/2,
219			theta	= Math.atan2(y,x);
220
221		if (theta > -1 * Math.PI && theta < -0.5 * Math.PI) {
222			theta = 2 * Math.PI + theta;
223		}
224
225		// theta is now value between -0.5PI and 1.5PI
226		// ready to be normalized and applied
227
228		return (theta + Math.PI / 2) / 2 * Math.PI * 10;
229	},
230	setMedia: function(media) {
231		this.media = $.extend({}, media);
232		this.player.jPlayer("setMedia", this.media);
233	},
234	play: function(time) {
235		this.player.jPlayer("play", time);
236	},
237	pause: function(time) {
238		this.player.jPlayer("pause", time);
239	},
240	destroy: function() {
241		this.player.unbind(this.eventNamespace);
242		this.player.jPlayer("destroy");
243	}
244};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.