Showing time of the video frame on hover over seek bar - angularjs

I am trying to show the time on hover of seek bar of a html5 video. ( similar to how youtube does it).
I have tried to use the timeupdate event on the video as below but looks like there is more to it.
<script>
function myFunction(event) {
// The currentTime property
document.getElementById("demo").innerHTML = event.currentTime;
var video = event;
video.addEventListener('progress', function() {
var bufferedEnd = video.buffered.end(video.buffered.length - 1);
var duration = video.duration.toFixed(1);
alert(duration);
if (duration > 0) {
document.getElementById('buffered-amount').style.width = ((bufferedEnd / duration)*100) + "%";
}
});
// display the current and remaining times
video.addEventListener("timeupdate", function () {
// Current time
var vTime = video.currentTime;
var vLength = video.duration.toFixed(1);
document.getElementById("curTime").textContent = vTime.toFixed(1);
document.getElementById("vRemaining").textContent = (vLength - vTime).toFixed(1);
}, false);
}
</script>
html:
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<div class="buffered">
<span id="buffered-amount"></span>
</div>
<div class="progress">
<span id="progress-amount"></span>
</div>
<p>Playback position: <span id="demo"></span></p>
<p>Current Time: <span id="curTime"></span></p>
<p>Remaining Time: <span id="vRemaining"></span></p>
I did try to understand multiple posts but did not find a solution.
Do I need to use onmouseover event instead? How do I calculate the time of the video frame when the user positions the mouse on the slider?

I would make a custom controls something like this:
Using the width of the controls div and video.duration to calculate the new time.
Hope this helps!
window.onload = function(){
controls.innerText = ''
function getNewTime(e){
return e.clientX / controls.clientWidth * video.duration
}
controls.addEventListener('mousemove', function(e){
controls.innerText = (getNewTime(e).toFixed(2))
})
controls.addEventListener('click', function(e){
video.currentTime = getNewTime(e)
})
video.addEventListener('click', function(){
video.play()
}
)
}
body{
margin:0;
background:black;
}
#wrapper{
display:flex;
flex-direction:column;
}
#video{
flex:1;
height:calc(100vh - 32px);
}
#controls{
height:32px;
background:red;
display:flex;
justify-content:center;
align-items:center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Custom Video Control</title>
</head>
<body>
<div id='wrapper'>
<video id='video' src='http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4'></video>
<div id='controls'>loading</div>
</div>
</body>
</html>
edit: to clarify my answer
If you look at the code: e.clientX / controls.clientWidth * video.duration you will see that
e.clientX is the current x position of your mouse on the controls rectangle.
controls.clientWidth is the total width of the controls rectangle.
video.duration is the total time of the video.
so if I would put my mouse on the end of the of the rectanlge. I would get 100% of the video duration. and in the beginning I would get 0%. if I would put my mouse at exactly in the middle I would get exactly the time of the middle of the video.
with video.currentTime I can change the current time of the video so that the frame is exactly the right frame of the time.

Try using controls attribute. You will get similar control bar that is present on YouTube videos.
If this attribute is present, Gecko will offer controls to allow the user to control video playback, including volume, seeking, and pause/resume playback.
https://developer.mozilla.org/pl/docs/Web/HTML/Element/video
Example in code.pen:(wait for video to load)
http://codepen.io/mikemoney/pen/QdQvXY
Example on SO: (wait for video to load)
<video src="http://www.sample-videos.com/video/mp4/480/big_buck_bunny_480p_1mb.mp4" autoplay poster="https://i.ytimg.com/vi/1iGy1Rp93o4/maxresdefault.jpg" controls width="480">
</video>

Related

How to show a progress bar in AngularJS

i'm kind of new using AngularJs framework and i am not that good in English. so i hope somebody can help me solve my problem and never mind my grammar hehe. i know mostly of progress bar in angularjs triggered by ng-show, but what if i want to put a progress bar before an object tag loads. for example
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="70"
aria-valuemin="0" aria-valuemax="100" style="width:70%">
<object width="400" height="400" data="file.pdf"></object>
</div>
</div>
let assume that that "file.pdf" is being fetch from the server. that being said it needs time to load, so i want to put a progress bar on that time while the data if being fetch from the server and hide it when the object is fully loaded thank you guys.
data flow example :
(file.pdf) ----Fetching---- [controller]----Progress bar--View(html)
Hope this will help you out. This is a basic example for showing and hiding a spinner bar on button click.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Welcome to LearnKode - A code learning platform</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
<style>
.loader {
border: 16px solid #f3f3f3; /* Light grey */
border-top: 16px solid #3498db; /* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
margin: 0 auto;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
html, body, container {
height: 100%;
width: 100%;
margin: 0;
}
</style>
</head>
<body ng-app="changeExample">
<div class="container" ng-controller="ExampleController">
<button class="btn" ng-click="ShowSpinner()">Show Spinner</button>
<button class="btn" ng-click="HideSpinner()">Hide Spinner</button>
<div ng-if="ShowSpinnerStatus" class="loader"></div>
</div>
<script>
var app = angular.module("changeExample", []);
app.controller('ExampleController', ['$scope', function ($scope) {
$scope.ShowSpinnerStatus = true;
$scope.ShowSpinner = function(){
$scope.ShowSpinnerStatus = true;
};
$scope.HideSpinner = function(){
$scope.ShowSpinnerStatus = false;
};
}]);
</script>
</body>
</html>
You can show and hide the spinner on a service call like this.
$scope.ShowSpinner();
LoginService.authenticateUser(userName, password).then(
function(response){
$scope.HideSpinner();
if( response.isSuccess ){
// Login Success
}
else{
//Login Fail
}
},
function(error){
//Network related error
$scope.HideSpinner();
}
);
Your English is really good and you need not worry about it at all. Coming back to your question, you are on the right path. You would need to use ng-show or ng-hide, whatever you choose. Let's say you choose ng-show In your controller, you would declare a variable,
$scope.isProgessBarVisible = true;
and then, within the controller itself, upon return from http call from the server, you would set it to false.
$http.get('someUrl')
.then(function successCallback(response) {
//load you pdf file content
$scope.isProgessBarVisible = false;
}
And in the HTML
<div class="progress">
<div class="progress-bar" role="progressbar" ng-show="isProgessBarVisible" aria-valuenow="70"
aria-valuemin="0" aria-valuemax="100" style="width:70%">
<object width="400" height="400" data="file.pdf"></object>
</div>
With this in place, the progress bar will show up until the file is fetched from server and displayed.
I think the problem is not just about showing/hiding the progress bar, perhaps it is about how to hide the progress bar when the <object>'s content finish loading.
Initially, I tried to use ng-load on the <object> but somehow it didn't work. So I tried to use onload which does work. But since the onLoad() handler function is outside angular environment, I had to get back the angular scope to be able to set the variable $scope.showProgress that will hide the progress bar.
See the plunkr yourself, and let me know if that is what you are looking for.
Plunkr https://plnkr.co/edit/wxgetLZdST0WcPEHyraZ
Note: I don't know whether it is possible to get the progress status number (% loaded), but at least we can show "Loading..." or a spinner icon while the <object> is loading.
http://chieffancypants.github.io/angular-loading-bar/
angular.module('app', ['angular-loading-bar']);
angular-loading-bar is a good option for $http calls

How to toggle between a play and pause button?

Essentially, I would like to know the best way to toggle between two img or div on a user click. So, first the play image is visible and when user clicks, play image is hidden and pause image is shown. When user clicks pause image, pause image is hidden and play image is shown.
I tried using an ng-show but I could only figure out how to show both images without hiding the other. So, a play image would be next to the pause image, which is not ideal.
Thanks in advance :)
Code I have tried that does not work:
HTML
<button ng-click="changeStatus" ng-show="checkStatus">Play</button>
<button ng-click="changeStatusAgain" ng-hide="checkStatus">Pause</button>
Controller:
$scope.changeStatus=function(){
$scope.checkStatus = false;
}
$scope.changeStatusAgain=function(){
$scope.checkStatus = true;
}
https://jsfiddle.net/n8nnwtte/
Use the same expression for both and negate it according to your logic.
HTML
<button class="play" ng-show="!song.playing" ng-click="song.togglePlay()">
<button class="pause" ng-show="song.playing" ng-click="song.togglePlay()">
JS
var $scope.song = {
playing: false, // Set the initial state
togglePlay: function() {
$scope.song.playing = !$scope.song.playing; // This would alternate the state each time
// Do something with the song
if ($scope.song.playing) { /*..*/ } else { /*..*/ }
}
};
This assumes you have a song object defined in your scope and that it has a boolean property called playing. So if song.playing is falsy we show the play button and if it's truthy we show the pause button.
The togglePlay() method defined can then be used to alternate the state of song.playing in addition to its role of actually controlling the playback.
JavaScript Toggle (Play/Pause) Sound on Click Event of DOM Element
his post shows how to toggle (play/pause) sound by JavaScript manipulation of onclick event of a DOM element. Browser support of HTML5 audio tag is a must in this example.
https://siongui.github.io/code/javascript-sound/toggle.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript Toggle (Play/Pause) Sound on Click Event of DOM Element</title>
</head>
<body>
<button id="player" type="button"
onclick="javascript:toggleSound();">
Click to Toggle Sound
</button>
<audio id="audio">
<source src="Wat_Metta_Buddha_Qualities.mp3" type="audio/mpeg">
Your browser does not support this audio format.
</audio>
<script type="text/javascript">
function toggleSound() {
var audioElem = document.getElementById('audio');
if (audioElem.paused)
audioElem.play();
else
audioElem.pause();
}
</script>
</body>
</html>

popup a div on mouseover in Angularjs

I'm new in AngularJS, how can i show popup a div on mouseover using AngularJS. If i resize a div on mouseover, it changes whole structure, how to show popup div without disturbing neighbors elements.
Markup
<div ng-repeat="x in images | filter:test" style="float:left; width:30%" ng-mouseover="count=1" ng-mouseleave="count=0" >
<img ng-src="{{x.path}}"
style="width: 100px; height:100px"><div> {{x.company}}</div>
<div style="background-color:#E6E6FA;text-align: center;"ng-show="count">
price:{{x.price}}</br>
size:{{x.size}}</br>
</div>
</img>
<div/>
I added extra things in markup like company,size on mouseover. help me in pop a image on mouseover. Thanks in advance
You have to do two things. First you have to position your popover element absolute, so that it doesn't disturb the flow of the other elements when it pops up. Something like this (z-index is what makes it to be over the other elements):
.popover {
position: absolute;
z-index: 100;
}
And in your html-markup you can use the ng-mouseover directive.
<div ng-mouseover="showPopover()" ng-mouseleave="hidePopover()">
more info
</div>
<div class="popover" ng-show="popoverIsVisible">Popover Content</div>
Your angular controller will probably look something like this
$scope.showPopover = function() {
$scope.popoverIsVisible = true;
};
$scope.hidePopover = function () {
$scope.popoverIsVisible = false;
};
If you have more than one, you are probably better of putting all that stuff into a directive

Fotorama: height for slides with html content

this is my first question on Stackoverflow, I hope it makes sense :)
I need to create a swipeable image gallery with html content in each slide (text, images, external links, social network buttons etc) and full screen option.
Fotorama is the best solution I have found, I am a very big fan of it :)
However, I am finding it difficult to fit the html content in the gallery, as it gets cropped to the height of the first image.
I need the image to be in the html, not a background image. And I need all the content to be visible both in the normal mode and in the full screen mode. The text can vary in length and the images in size, so I cannot give the gallery a fixed height.
Does it make sense?
I couldn't find a similar question asked already, so if you have any idea please let me know!
Thanks :)
This is the simplified code of what I have done so far, any comment is more than welcome!
<div class="fotorama" data-allowfullscreen="true" data-nav="thumbs" data-click="false" data-width="100%">
<div data-thumb="image-01.jpg" id="slide1">
<h2>Title 01</h2>
<img src="image-01.jpg" width="100%">
<div class="content">
<p>Blah blah blah</p>
<div class="photoShare">
<h6>Share</h6>
<!-- Social Network Buttons -->
</div>
<div class="buyThisPhoto">
<!-- Buy this photo link -->
</div>
</div>
</div>
<!-- etc -->
Update:
I am working on possibe solution, using the API. Seems to work but any suggestion for improvement is welcome :)
$(function () {
var $fotoramaDiv = $('#fotorama').fotorama();
var fotorama = $fotoramaDiv.data('fotorama');
$('.fotorama').on('fotorama:ready ' + 'fotorama:show ' + 'fotorama:load ', function () {
var currentContainer = $(".fotorama__active").children('div');
var newHeight = /* calculate the height by adding up the heights of the elements contained in currentContainer */;
fotorama.resize({
height: newHeight
});
}).fotorama();
});

How to enable double click event to fotorama slider to make full screen

How to enable double click event to fotorama slider to make full screen, like what we are seeing on right top corner
You can use this jquery events http://api.jquery.com/dblclick/ to execute this function
fotorama.requestFullScreen()
remember you should initialize fotorama manually in the header of the api you can see how do it.
Here is a example for you !
http://jsfiddle.net/meickol/8dv7k/ how you see is easy! good luck!
HTML
<base href="http://fotorama.s3.amazonaws.com/i/okonechnikov/">
<!-- Fotorama -->
<div class="fotorama_custom" data-width="700" data-ratio="700/467" data-max-width="100%">
<img src="1-lo.jpg">
<img src="2-lo.jpg">
<img src="9-lo.jpg">
<img src="6-lo.jpg">
<img src="5-lo.jpg">
</div>
SCRIPT
<script>
// 1. Initialize fotorama manually.
var $fotoramaDiv = jQuery('.fotorama_custom').fotorama({
click:false,
allowfullscreen:true,
});
// 2. Get the API object.
var fotorama = $fotoramaDiv.data('fotorama');
jQuery('.fotorama').dblclick(function(){
fotorama.requestFullScreen();
});
</script>

Resources