pyc-website

main website for pyc inc.

git clone https://9o.is/git/pyc-website.git

videogular-controls.js

(14907B)


      1 /**
      2  * @license Videogular v0.4.0 http://videogular.com
      3  * Two Fucking Developers http://twofuckingdevelopers.com
      4  * License: MIT
      5  */
      6 "use strict";
      7 angular.module("com.2fdevs.videogular.plugins.controls", [])
      8 	.directive(
      9 		"vgControls",
     10 		["$timeout", "VG_STATES", "VG_EVENTS", function($timeout, VG_STATES, VG_EVENTS){
     11 			return {
     12 				restrict: "E",
     13 				require: "^videogular",
     14 				transclude: true,
     15 				template: '<div id="controls-container" ng-show="isReady" ng-class="animationClass" ng-transclude></div>',
     16 				scope: {
     17 					autoHide: "=vgAutohide",
     18 					autoHideTime: "=vgAutohideTime"
     19 				},
     20 				link: function(scope, elem, attr, API) {
     21 					var w = 0;
     22 					var h = 0;
     23 					var autoHideTime = 2000;
     24 					var controlBarHeight = elem[0].style.height;
     25 					var hideInterval;
     26 					var isReadyInterval;
     27 
     28 					scope.isReady = false;
     29 
     30 					function onUpdateSize(target, params) {
     31 						w = params[0];
     32 						h = params[1];
     33 
     34 						elem.css("top", (parseInt(h, 10) - parseInt(controlBarHeight, 10)) + "px");
     35 					}
     36 
     37 					function onMouseMove() {
     38 						showControls();
     39 						scope.$apply();
     40 					}
     41 
     42 					function hideControls() {
     43 						scope.animationClass = "hide-animation";
     44 					}
     45 
     46 					function showControls() {
     47 						scope.animationClass = "show-animation";
     48 						$timeout.cancel(hideInterval);
     49 						if (scope.autoHide) hideInterval = $timeout(hideControls, autoHideTime);
     50 					}
     51 
     52 					function onPlayerReady() {
     53 						var size = API.getSize();
     54 
     55 						elem.css("top", (parseInt(size.height, 10) - parseInt(controlBarHeight, 10)) + "px");
     56 						isReadyInterval = $timeout(showWhenIsReady, 500);
     57 					}
     58 
     59 					function showWhenIsReady() {
     60 						$timeout.cancel(isReadyInterval);
     61 						scope.isReady = true;
     62 					}
     63 
     64 					// If vg-autohide has been set
     65 					if (scope.autoHide != undefined) {
     66 						scope.$watch("autoHide", function(value) {
     67 							if (value) {
     68 								scope.animationClass = "hide-animation";
     69 								API.videogularElement.bind("mousemove", onMouseMove);
     70 							}
     71 							else {
     72 								scope.animationClass = "";
     73 								$timeout.cancel(hideInterval);
     74 								API.videogularElement.unbind("mousemove", onMouseMove);
     75 								showControls();
     76 							}
     77 						});
     78 					}
     79 
     80 					// If vg-autohide-time has been set
     81 					if (scope.autoHideTime != undefined) {
     82 						scope.$watch("autoHideTime", function(value) {
     83 							autoHideTime = value;
     84 						});
     85 					}
     86 
     87 					API.$on(VG_EVENTS.ON_UPDATE_SIZE, onUpdateSize);
     88 
     89 					if (API.isPlayerReady()) onPlayerReady();
     90 					else API.$on(VG_EVENTS.ON_PLAYER_READY, onPlayerReady);
     91 				}
     92 			}
     93 		}
     94 	])
     95 	.directive(
     96 		"vgPlayPauseButton",
     97 		["VG_STATES", "VG_EVENTS", function(VG_STATES, VG_EVENTS) {
     98 			return {
     99 				restrict: "E",
    100 				require: "^videogular",
    101 				template: "<i class='fa fa-play fa-2x text-white' ng-class='playPauseIcon'></i>",
    102 				link: function(scope, elem, attr, API) {
    103 					function onChangeState(target, params) {
    104 						switch (params[0]) {
    105 							case VG_STATES.PLAY:
    106 								scope.playPauseIcon = {pause: true};
    107 								break;
    108 
    109 							case VG_STATES.PAUSE:
    110 								scope.playPauseIcon = {play: true};
    111 								break;
    112 
    113 							case VG_STATES.STOP:
    114 								scope.playPauseIcon = {play: true};
    115 								break;
    116 						}
    117 					}
    118 
    119 					function onClickPlayPause() {
    120 						API.playPause();
    121 						scope.$apply();
    122 					}
    123 
    124 					scope.playPauseIcon = {play: true};
    125 
    126 					elem.bind("click", onClickPlayPause);
    127 					API.$on(VG_EVENTS.ON_SET_STATE, onChangeState);
    128 				}
    129 			}
    130 		}
    131 	])
    132 	.directive(
    133 		"vgTimedisplay",
    134 		["VG_EVENTS", function(VG_EVENTS){
    135 			return {
    136 				require: "^videogular",
    137 				restrict: "E",
    138 				link: function(scope, elem, attr, API) {
    139 					var showHours = false;
    140 					var totalTimeUnparsed = 0;
    141 
    142 					function parseTime(time) {
    143 						var hours = Math.floor(time / 3600);
    144 						var mins = Math.floor((time % 3600) / 60);
    145 						var secs = Math.floor(time % 60);
    146 
    147 						return {hours: hours, mins: mins, secs: secs};
    148 					}
    149 
    150 					function displayTime(h, m, s) {
    151 						var displayTime = '';
    152 
    153 						var hh = h < 10 ? "0" + h : h;
    154 						var mm = m < 10 ? "0" + m : m;
    155 						var ss = s < 10 ? "0" + s : s;
    156 
    157 						if (showHours || h > 0) {
    158 							displayTime += hh + ':';
    159 						}
    160 
    161 						return displayTime + mm + ':' + ss;
    162 					}
    163 
    164 					function onUpdateTime(target, params) {
    165 						var time = parseTime(params[0]);
    166 						var timeLeft = parseTime(totalTimeUnparsed - params[0]);
    167 
    168 						scope.currentTime = displayTime(time.hours, time.mins, time.secs);
    169 						scope.timeLeft = displayTime(timeLeft.hours, timeLeft.mins, timeLeft.secs);
    170 					}
    171 
    172 					function onComplete(target, params) {
    173 						scope.currentTime = "00:00";
    174 					}
    175 
    176 					function onStartPlaying(target, params) {
    177 						totalTimeUnparsed = params[0];
    178 
    179 						var time = parseTime(totalTimeUnparsed);
    180 
    181 						showHours = (time.hours > 0);
    182 
    183 						scope.totalTime = displayTime(time.hours, time.mins, time.secs);
    184 					}
    185 
    186 					scope.currentTime = "00:00";
    187 					scope.totalTime = "00:00";
    188 
    189 					API.$on(VG_EVENTS.ON_START_PLAYING, onStartPlaying);
    190 					API.$on(VG_EVENTS.ON_UPDATE_TIME, onUpdateTime);
    191 					API.$on(VG_EVENTS.ON_COMPLETE, onComplete);
    192 				}
    193 			}
    194 		}
    195 	])
    196 	.directive(
    197 		"vgScrubbar",
    198 		["VG_EVENTS", "VG_STATES", "VG_UTILS", function(VG_EVENTS, VG_STATES, VG_UTILS){
    199 			return {
    200 				restrict: "AE",
    201 				require: "^videogular",
    202 				replace: true,
    203 				link: function(scope, elem, attr, API) {
    204 					var isSeeking = false;
    205 					var isPlaying = false;
    206 					var isPlayingWhenSeeking = false;
    207 					var touchStartX = 0;
    208 
    209 					function onScrubBarTouchStart(event) {
    210 						var touches = event.originalEvent.touches;
    211 						var touchX;
    212 
    213 						if (VG_UTILS.isiOSDevice()) {
    214 							touchStartX = (touches[0].clientX - event.originalEvent.layerX) * -1;
    215 						}
    216 						else {
    217 							touchStartX = event.originalEvent.layerX;
    218 						}
    219 
    220 						touchX = touches[0].clientX + touchStartX - touches[0].target.offsetLeft;
    221 
    222 						isSeeking = true;
    223 						if (isPlaying) isPlayingWhenSeeking = true;
    224 						seekTime(touchX * API.videoElement[0].duration / elem[0].scrollWidth);
    225 						API.pause();
    226 					}
    227 					function onScrubBarTouchEnd(event) {
    228 						if (isPlayingWhenSeeking) {
    229 							isPlayingWhenSeeking = false;
    230 							API.play();
    231 						}
    232 						isSeeking = false;
    233 					}
    234 					function onScrubBarTouchMove(event) {
    235 						var touches = event.originalEvent.touches;
    236 						var touchX;
    237 
    238 						if (isSeeking) {
    239 							touchX = touches[0].clientX + touchStartX - touches[0].target.offsetLeft;
    240 							seekTime(touchX * API.videoElement[0].duration / elem[0].scrollWidth);
    241 						}
    242 					}
    243 					function onScrubBarTouchLeave(event) {
    244 						isSeeking = false;
    245 					}
    246 
    247 					function onScrubBarMouseDown(event) {
    248 						event = VG_UTILS.fixEventOffset(event);
    249 
    250 						isSeeking = true;
    251 						if (isPlaying) isPlayingWhenSeeking = true;
    252 						seekTime(event.offsetX * API.videoElement[0].duration / elem[0].scrollWidth);
    253 						API.pause();
    254 					}
    255 					function onScrubBarMouseUp(event) {
    256 						event = VG_UTILS.fixEventOffset(event);
    257 
    258 						if (isPlayingWhenSeeking) {
    259 							isPlayingWhenSeeking = false;
    260 							API.play();
    261 						}
    262 						isSeeking = false;
    263 						seekTime(event.offsetX * API.videoElement[0].duration / elem[0].scrollWidth);
    264 					}
    265 					function onScrubBarMouseMove(event) {
    266 						if (isSeeking) {
    267 							event = VG_UTILS.fixEventOffset(event);
    268 							seekTime(event.offsetX * API.videoElement[0].duration / elem[0].scrollWidth);
    269 						}
    270 					}
    271 					function onScrubBarMouseLeave(event) {
    272 						isSeeking = false;
    273 					}
    274 					function seekTime(time) {
    275 						API.seekTime(time, false);
    276 					}
    277 
    278 					function onChangeState(target, params) {
    279 						if (!isSeeking) {
    280 							switch (params[0]) {
    281 								case VG_STATES.PLAY:
    282 									isPlaying = true;
    283 									break;
    284 
    285 								case VG_STATES.PAUSE:
    286 									isPlaying = false;
    287 									break;
    288 
    289 								case VG_STATES.STOP:
    290 									isPlaying = false;
    291 									break;
    292 							}
    293 						}
    294 					}
    295 
    296 					API.$on(VG_EVENTS.ON_SET_STATE, onChangeState);
    297 
    298 					// Touch move is really buggy in Chrome for Android, maybe we could use mouse move that works ok
    299 					if (VG_UTILS.isMobileDevice()) {
    300 						elem.bind("touchstart", onScrubBarTouchStart);
    301 						elem.bind("touchend", onScrubBarTouchEnd);
    302 						elem.bind("touchmove", onScrubBarTouchMove);
    303 						elem.bind("touchleave", onScrubBarTouchLeave);
    304 					}
    305 					else {
    306 						elem.bind("mousedown", onScrubBarMouseDown);
    307 						elem.bind("mouseup", onScrubBarMouseUp);
    308 						elem.bind("mousemove", onScrubBarMouseMove);
    309 						elem.bind("mouseleave", onScrubBarMouseLeave);
    310 					}
    311 				}
    312 			}
    313 		}
    314 	])
    315 	.directive(
    316 		"vgScrubbarcurrenttime",
    317 		["VG_EVENTS", function(VG_EVENTS){
    318 			return {
    319 				restrict: "E",
    320 				require: "^videogular",
    321 				link: function(scope, elem, attr, API) {
    322 					var percentTime = 0;
    323 
    324 					function onUpdateTime(target, params){
    325 						percentTime = Math.round((params[0] / params[1]) * 100);
    326 						elem.css("width", percentTime + "%");
    327 						scope.$apply();
    328 					}
    329 
    330 					function onComplete(target, params){
    331 						percentTime = 0;
    332 						elem.css("width", percentTime + "%");
    333 					}
    334 
    335 					API.$on(VG_EVENTS.ON_UPDATE_TIME, onUpdateTime);
    336 					API.$on(VG_EVENTS.ON_COMPLETE, onComplete);
    337 				}
    338 			}
    339 		}
    340 	])
    341 	.directive(
    342 		"vgVolume",
    343 		["VG_UTILS", function(VG_UTILS) {
    344 			return {
    345 				restrict: "E",
    346 				link: function(scope, elem, attr) {
    347 					function onMouseOverVolume() {
    348 						scope.volumeVisibility = "visible";
    349 						scope.$apply();
    350 					}
    351 
    352 					function onMouseLeaveVolume() {
    353 						scope.volumeVisibility = "hidden";
    354 						scope.$apply();
    355 					}
    356 
    357 					// We hide volume controls on mobile devices
    358 					if (VG_UTILS.isMobileDevice()) {
    359 						elem.css("display", "none");
    360 					}
    361 					else {
    362 						scope.volumeVisibility = "hidden";
    363 
    364 						elem.bind("mouseover", onMouseOverVolume);
    365 						elem.bind("mouseleave", onMouseLeaveVolume);
    366 					}
    367 				}
    368 			}
    369 		}
    370 	])
    371 	.directive(
    372 		"vgVolumebar",
    373 		["VG_EVENTS", "VG_UTILS", function(VG_EVENTS, VG_UTILS) {
    374 			return {
    375 				restrict: "E",
    376 				require: "^videogular",
    377 				template:
    378 					"<div class='verticalVolumeBar'>"+
    379 						"<div class='volumeBackground'>"+
    380 							"<div class='volumeValue'></div>"+
    381 							"<div class='volumeClickArea'></div>"+
    382 						"</div>"+
    383 					"</div>",
    384 				link: function(scope, elem, attr, API) {
    385 					var isChangingVolume = false;
    386 					var volumeBackElem = angular.element(elem[0].getElementsByClassName("volumeBackground"));
    387 					var volumeValueElem = angular.element(elem[0].getElementsByClassName("volumeValue"));
    388 
    389 					function onClickVolume(event) {
    390 						event = VG_UTILS.fixEventOffset(event);
    391 						var volumeHeight = parseInt(volumeBackElem.prop("offsetHeight"));
    392 						var value = event.offsetY * 100 / volumeHeight;
    393 						var volValue = 1 - (value / 100);
    394 						updateVolumeView(value);
    395 
    396 						API.setVolume(volValue);
    397 
    398 						scope.$apply();
    399 					}
    400 
    401 					function onMouseDownVolume(event) {
    402 						isChangingVolume = true;
    403 					}
    404 
    405 					function onMouseUpVolume(event) {
    406 						isChangingVolume = false;
    407 					}
    408 
    409 					function onMouseLeaveVolume(event) {
    410 						isChangingVolume = false;
    411 					}
    412 
    413 					function onMouseMoveVolume(event) {
    414 						if (isChangingVolume) {
    415 							event = VG_UTILS.fixEventOffset(event);
    416 							var volumeHeight = parseInt(volumeBackElem.prop("offsetHeight"));
    417 							var value = event.offsetY * 100 / volumeHeight;
    418 							var volValue = 1 - (value / 100);
    419 							updateVolumeView(value);
    420 
    421 							API.setVolume(volValue);
    422 
    423 							scope.$apply();
    424 						}
    425 					}
    426 
    427 					function updateVolumeView(value) {
    428 						volumeValueElem.css("height", value + "%");
    429 						volumeValueElem.css("top", (100 - value) + "%");
    430 					}
    431 
    432 					function onSetVolume(target, params) {
    433 						updateVolumeView(params[0] * 100);
    434 					}
    435 
    436 					function onChangeVisibility(value) {
    437 						elem.css("visibility", value);
    438 					}
    439 
    440 					elem.css("visibility", scope.volumeVisibility);
    441 
    442 					scope.$watch("volumeVisibility", onChangeVisibility);
    443 
    444 					volumeBackElem.bind("click", onClickVolume);
    445 					volumeBackElem.bind("mousedown", onMouseDownVolume);
    446 					volumeBackElem.bind("mouseup", onMouseUpVolume);
    447 					volumeBackElem.bind("mousemove", onMouseMoveVolume);
    448 					volumeBackElem.bind("mouseleave", onMouseLeaveVolume);
    449 
    450 					API.$on(VG_EVENTS.ON_SET_VOLUME, onSetVolume);
    451 				}
    452 			}
    453 		}
    454 	])
    455 	.directive(
    456 		"vgMutebutton",
    457 		["VG_EVENTS", function(VG_EVENTS) {
    458 			return {
    459 				restrict: "E",
    460 				require: "^videogular",
    461 				template: "<i class='fa fa-volume-up fa-2x text-white' ng-class='muteIcon'></i>",
    462 				link: function(scope, elem, attr, API) {
    463 					var isMuted = false;
    464 
    465 					function onClickMute(event) {
    466 						if (isMuted) {
    467 							scope.currentVolume = scope.defaultVolume;
    468 						}
    469 						else {
    470 							scope.currentVolume = 0;
    471 							scope.muteIcon = {mute: true};
    472 						}
    473 
    474 						isMuted = !isMuted;
    475 
    476 						API.setVolume(scope.currentVolume);
    477 
    478 						scope.$apply();
    479 					}
    480 
    481 					function onSetVolume(target, params) {
    482 						scope.currentVolume = params[0];
    483 
    484 						// TODO: Save volume with LocalStorage
    485 						// if it's not muted we save the default volume
    486 						if (!isMuted) {
    487 							scope.defaultVolume = params[0];
    488 						}
    489 						else {
    490 							// if was muted but the user changed the volume
    491 							if (params[0] > 0) {
    492 								scope.defaultVolume = params[0];
    493 							}
    494 						}
    495 
    496 						var percentValue = Math.round(params[0] * 100);
    497 						if (percentValue == 0) {
    498 							scope.muteIcon = {mute: true};
    499 						}
    500 						else if (percentValue > 0 && percentValue < 25) {
    501 							scope.muteIcon = {level0: true};
    502 						}
    503 						else if (percentValue >= 25 && percentValue < 50) {
    504 							scope.muteIcon = {level1: true};
    505 						}
    506 						else if (percentValue >= 50 && percentValue < 75) {
    507 							scope.muteIcon = {level2: true};
    508 						}
    509 						else if (percentValue >= 75) {
    510 							scope.muteIcon = {level3: true};
    511 						}
    512 
    513 						//scope.$apply();
    514 					}
    515 
    516 					scope.defaultVolume = 1;
    517 					scope.currentVolume = scope.defaultVolume;
    518 					scope.muteIcon = {level3: true};
    519 
    520 					//TODO: get volume from localStorage
    521 					elem.bind("click", onClickMute);
    522 
    523 					API.$on(VG_EVENTS.ON_SET_VOLUME, onSetVolume);
    524 				}
    525 			}
    526 		}
    527 	])
    528 	.directive(
    529 		"vgFullscreenbutton",
    530 		["$window", "VG_EVENTS", function($window, VG_EVENTS){
    531 			return {
    532 				restrict: "AE",
    533 				require: "^videogular",
    534 				scope: {
    535 					vgEnterFullScreenIcon: "=",
    536 					vgExitFullScreenIcon: "="
    537 				},
    538 				template: "<i class='fa fa-hand-o-left fa-2x text-white' ng-class='fullscreenIcon'></i>",
    539 				link: function(scope, elem, attr, API) {
    540 					function onEnterFullScreen() {
    541 						scope.fullscreenIcon = {exit: true};
    542 					}
    543 					function onExitFullScreen() {
    544 						scope.fullscreenIcon = {enter: true};
    545 					}
    546 					function onClickFullScreen(event) {
    547 						API.toggleFullScreen();
    548 
    549 						scope.$apply();
    550 					}
    551 
    552 					elem.bind("click", onClickFullScreen);
    553 					scope.fullscreenIcon = {enter: true};
    554 
    555 					API.$on(VG_EVENTS.ON_ENTER_FULLSCREEN, onEnterFullScreen);
    556 					API.$on(VG_EVENTS.ON_EXIT_FULLSCREEN, onExitFullScreen);
    557 				}
    558 			}
    559 		}
    560 	]);