I have a video that I want to play based on the user's scroll position (as the user scrolls, the video plays; when the scroll stops the video pauses).
This works fine with most mp4 videos, however when I try to us a video that has a 1920x1080 resolution the playback is "choppy", only updating the video image once the user is done scrolling (mouseup) and not during the scroll (mousedown).
Here is an example in jsfiddle. The default video in the example has a resolution of 1920x1080. The commented video link is 1280x720 and works fine. This happens with every 1080 video tested. 1920 width is preferred because the video in the finished product should be full-screen-width and should cover most desktop screens without losing much resolution quality.
Here is the code:
HTML
<div id="main-wrapper">
<video id="main-video" width="auto" height="240" controls preload>
<source src="http://mirrors.standaloneinstaller.com/video-sample/jellyfish-25-mbps-hd-hevc.mp4" type="video/mp4">
<!--
<source src="http://mirrors.standaloneinstaller.com/video-sample/star_trails.mp4" type="video/mp4">
-->
Your browser does not support the video tag.
</video>
</div>
JavaScript:
var myContent = $('#main-video');
var myContentConainter =$('#main-wrapper');
var vid = document.getElementById("main-video");
var originalTop = 0;
var scrollPos=0;
var atTopState = false;
var vid = document.getElementById("main-video");
var videoToHeightRatio= .012;
var videoLength;
vid.onloadedmetadata = function() {
videoLength =vid.duration;
};
vid.pause();
document.addEventListener("scroll", function(){
////// Set up variables ////////
var windowTop = $(window).scrollTop();
var windowBottom = $(window).scrollTop() + $(window).height();
var windowMidPoint = ($(window).scrollTop()) +( $(window).height() / 2 );
var contentTop = $(myContent).offset().top;
var contentBottom = contentTop + $(myContent).height();
var contentMidpoint = contentTop + ($(myContent).height()/2);
var windowHeight = window.innerHeight;
var windowWidth = window.innerWidth;
//Video stuff
var currentSec = vid.currentTime;
var videoContainerOverlow = videoLength/videoToHeightRatio;
var containerHeight = $(window).height();
var newContainerHeight = containerHeight + videoContainerOverlow
myContentConainter.css('height',newContainerHeight+"px");
if (windowTop >= contentTop){
if (atTopState==false){
originalTop = contentTop;
myContent.css("position","fixed")
myContent.css("top","0")
}
vid.currentTime = (windowTop / videoContainerOverlow) * videoLength;
atTopState = true;
}
if( windowTop < originalTop){
myContent.css("position","unset")
myContent.css("top","unset")
atTopState=false;
}
if (windowBottom <= contentTop){
myContent.css("position","unset")
myContent.css("top","unset")
atTopState=false;
}
});
CSS:
#main-wrapper{
background-image:linear-gradient(blue,red);
height:300vh;
}
#main-video{
}
Related
I've got this code which is dragging images when mouse clicks on them, but I want the images to appear in a random location every time the page is refresh. How can I do that? Thanks! :)
The code I've got so far is
<div class="photos">
<div id="connie1">
<img src="img/connieimage.jpeg"></img>
</div>
<div id="rocio1">
<img src="img/rocioimage.mp4"></img>
</div>
var connie = document.getElementById("connie1");
var rocio = document.getElementById("rocio1");
var moving = false;
connie.addEventListener("mousedown", initialClick, false);
rocio.addEventListener("mousedown", initialClick, false);
function move(e){
var newX = e.clientX - 10;
var newY = e.clientY - 10;
image.style.left = newX + "px";
image.style.top = newY + "px";
}
function initialClick(e) {
if(moving){
document.removeEventListener("mousemove", move);
moving = !moving;
return;
}
moving = !moving;
image = this;
document.addEventListener("mousemove", move, false);
}
To give the images a random positition on page load, and not let them
go out of the screen window use this code
Javascript
function onloadFunction() {
var amount = X; //The amount of loops
var arrayIDs = ["imgID1", "imgID2", "imgID3"]; //all the IDs of the images
for (i=1;i<=amount;i++) {
//First get the image height and width in a var
var element = document.getElementById(arrayIDs[i-1]);
var positionInfo = element.getBoundingClientRect();
var imgHeight = positionInfo.height;
var imgWidth = positionInfo.width;
//Then get the width and height of the screen. if the container is not the screen
//use the same code as above for the image width/height and change the imgID
//The the Id of the container element.
var screenWidth = window.innerWidth;
var screenHeight = window.innerHeight;
//Now generate a random top and left position for the image on page load
var imgLeft = Math.floor(Math.random() * (screenWidth - imgWidth));
var imgTop= Math.floor(Math.random() * (screenHeight - imgHeight));
//The reason to get the img and screen height and width is to not let the
//image
//overlap out of the screen
//Now set the image to correct position
document.getElementById(arrayIDs[i-1]).style.top = imgTop+"px";
document.getElementById(arrayIDs[i-1]).style.left = imgLeft+"px";
}
}
HTML
<body onload="onloadFunction()">
<img class="images" src="img/connieimage.jpeg" id="imgID1"></img>
<img class="images" src="img/connieimage.jpeg" id="imgID2"></img>
<img class="images" src="img/connieimage.jpeg" id="imgID3"></img>
</body>
CSS
.images {
position: absolute;
}
I need help with a particular bit of JS I'm using to make HTML5 videos play when in view.
The code:
$(document).ready(function() {
// Get media - with autoplay disabled (audio or video)
var media = $('#video1, #video2, #video3, #video4, #video5');
var tolerancePixel = 10;
function checkMedia(){
// Get current browser top and bottom
var scrollTop = $(window).scrollTop() + tolerancePixel;
var scrollBottom = $(window).scrollTop() + $(window).height() - tolerancePixel;
//if ($(window).scrollTop() > $(window).height() - 100) {
media.each(function(index, el) {
var yTopMedia = $(this).offset().top;
var yBottomMedia = $(this).height() + yTopMedia;
if(scrollTop < yBottomMedia && scrollBottom > yTopMedia){
$(this).get(0).play();
} else {
$(this).get(0).pause();
}
});
//}
}
$(document).on('scroll', checkMedia);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height:500px"></div>
<video muted id="video4" class="lightbulbs" width="100%" height="auto">
<source src="http://www.ddi.com.au/culture/img/lightbulbs.mp4" type="video/mp4">
</video>
<div style="height:500px"></div>
I obtained this code from this answer: https://stackoverflow.com/a/26508106/10213848
My issue is that once the video is finished, it can be triggered again by scrolling upward. I need the video/s to only play once and not get triggered again.
Any help would be greatly appreciated.
You can use a variable to mark whether the video had played. if it already played, do not play it again:
$(document).ready(function() {
// Get media - with autoplay disabled (audio or video)
var media = $('#video1, #video2, #video3, #video4, #video5');
var tolerancePixel = 10;
var hasPlayMap = {};
function checkMedia(){
// Get current browser top and bottom
var scrollTop = $(window).scrollTop() + tolerancePixel;
var scrollBottom = $(window).scrollTop() + $(window).height() - tolerancePixel;
//if ($(window).scrollTop() > $(window).height() - 100) {
media.each(function(index, el) {
var yTopMedia = $(this).offset().top;
var yBottomMedia = $(this).height() + yTopMedia;
if(scrollTop < yBottomMedia && scrollBottom > yTopMedia){
var thisId = $(this).attr("id");
if (hasPlayMap[thisId]){
return;
}
hasPlayMap[thisId] = true;
$(this).get(0).play();
} else {
$(this).get(0).pause();
}
});
//}
}
$(document).on('scroll', checkMedia);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height:500px"></div>
<video muted id="video4" class="lightbulbs" width="100%" height="auto">
<source src="http://www.ddi.com.au/culture/img/lightbulbs.mp4" type="video/mp4">
</video>
<div style="height:500px"></div>
Sorry, I know this looks a lot like NewToJS' answer in the comments, sadly I was thinking of the same thing.
Since this is the effect you wanted, please do not green tick this since NewToJS got the answer first (granted, that is, if you had planned to).
You can set the video's onend event to set the video's onplay event:
document.querySelector('video').forEach(function(element) {
// Set the onend event to...
element.onend = function() {
// ...set the onplay event to...
this.onplay = function() {
// ...stop playing video when the video starts playing
this.pause();
this.currentTime = 0;
};
};
});
Pure jQuery version:
$('video').each(function(ix, ele) {
ele.addEventListener('end', function() {
this.addEventListener('play', function() {
ele.pause();
ele.currentTime = 0;
});
});
});
I'm developing a one page website with Skrollr.js plugin. I need to add multiple audio tracks to specific pixel heights and stop these tracks in multiple breakpoints. How can I do that?
I tried with the script below, but I don't know how to add multiple conditions with other breakpoints, tracks, and pixel height.
var playing = false;
var audioTrack = $('#track1').get(0);
window.onscroll = function() {
var winH = $(window).height();
var scrollPage = $(window).scrollTop();
if(!playing && winH >= 768 && scrollPage > 1000 && scrollPage < 3000){
audioTrack.play();
playing = true;
}else if(scrollPage > 3000 || scrollPage < 1000 || winH < 768 ){
audioTrack.pause();
audioTrack.currentTime = 0;
playing = false;
}
}
I have to implement videos tags on my HTML page.i have included one video in video tag but if i scroll up the video should be forward how much i have scrolled and if i scroll down the video should be backward and it should play.i have tried like this.
<script type="text/javascript">
function updateVideo() {
var video = $('#one').get(0);
var videoLength = video.duration;
var scrollPosition = $(document).scrollTop();
video.currentTime = (scrollPosition / ($(document).height() - $(window).height())) * videoLength;//(scrollPosition / SCROLL_SCRUB_SPEED) % videoLength;
}
$(window).scroll(function(e) {
if(videoReady && continueUpdatingVideo) { updateVideo(); }
});
</script>
and html is
<div class="container">
<video id="one" width="480" height="600" autoplay loop controls class="hello">
<source type="video/mp4" src="https://d3mlfyygrfdi2i.cloudfront.net/fd77/team_04022013_b_v4.mp4"></source>
<source type="video/webm" src="https://d3mlfyygrfdi2i.cloudfront.net/c943/team_04022013_b_v4.webm" ></source>
You need an HTML5 capable browser to view this video.
</video>
</div>
You will probably want to use the "mousewheel" event instead of the "scroll" event. The "scroll" event only fires when the viewport actually moves.
Here's a jsFiddle to see the scrolling portion in action http://jsfiddle.net/33m33/.
I think this script should do what you're needing, though you may need to make a couple of modifications:
var video = $('#one').get(0);
var increments = 2; //steps two seconds for each scroll event
var videoReady = false; //set to true when video loads
var continueUpdatingVideo = false;
$(document).ready(function(){
$('#one').bind('DOMMouseScroll mousewheel', function(e){
e.preventDefault();
if(videoReady && continueUpdatingVideo) {
var delta = Math.max(-1, Math.min(1, (e.originalEvent.wheelDelta || -e.originalEvent.detail))); //either +1 or -1
updateVideo(delta * increments);
}
return false;
});
});
function updateVideo(delta) {
var videoLength = video.duration;
var videoPosition = (video.currentTime + delta > videoLength) ? videoLength : ((video.currentTime + delta < 0) ? 0 : video.currentTime + delta);
video.currentTime = videoPosition;
}
I am calling a function, using window.onload, which sets the style.height and style.width of video to the maximum possible in the window (while retain aspect ratio). When this is called in the onload event, the video has black bars on left and right sides, which remain when the browser is resized and seem to be part of the video (or its container?) from then on.
When i leave the "resizevid" function out of onload, and only call it in onresize, the black bars are not present.
Any ideas on how to fix this? what happens after the onload event which changes how the width of the video is interpreted? thank you so much if you can enlighten me!
url for full page:
with resizevid in onload:
http://thebeach.name/video.html
with resizevid only in onresize:
http://thebeach.name/videores.html
excerpts of code:
style:
<style>
html, body, div, video{border:0px;margin:0px;padding:0px;background-color:black;vertical-align:top;text-align:center;}
video{width:100%}
</style>
html:
<body onresize="resizevid();" align=center>
<video align=center id="myvideo" autoplay loop>
</video>
</body>
script:
window.onload = function() {
changevid();
resizevid();
}
function resizevid(){
//find out the viewport size
var viewportwidth;
var viewportheight;
if (typeof window.innerWidth != 'undefined'){
viewportwidth = window.innerWidth,
viewportheight = window.innerHeight
}
else if (typeof document.documentElement != 'undefined'
&& typeof document.documentElement.clientWidth !=
'undefined' && document.documentElement.clientWidth != 0)
{
viewportwidth = document.documentElement.clientWidth,
viewportheight = document.documentElement.clientHeight
}
// older versions of IE
else
{
viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
viewportheight = document.getElementsByTagName('body')[0].clientHeight
}
//get the aspect ratio of the video
var vidwidth = document.getElementById('myvideo').offsetWidth;
var vidheight = document.getElementById('myvideo').offsetHeight;
var aspratio = vidheight/vidwidth;
//set video to full height, find correct width
function vidTooTall(){
d=document.getElementById('myvideo');
var newheight = viewportheight+'px';
var newwidth = viewportheight/aspratio;
newwidth = newwidth+'px';
d.style.height = newheight;
d.style.width = newwidth;
}
//set video to full width, find correct height
function vidTooWide(){
d=document.getElementById('myvideo');
var newwidth = viewportwidth+'px';
var newheight = aspratio*viewportwidth;
newheight = newheight+'px';
d.style.height = newheight;
d.style.width = newwidth;
}
//if windowheight/windowwidth < vidheight/vidwidth
//video is too tall, else video is too wide
if(viewportwidth*aspratio>viewportheight){
vidTooTall();
}
else{
vidTooWide();
}
}