Youtube embed dynamic sizing - javascript

I've created this script and it works pretty well except onload. On resize it works great and even on load it works great 90% of the time. I'm guessing that its due to the script running before the iframe is loaded but don't know what to do about it.
$( document ).ready(function() {
var content = $('#hero'); // top section container
var iframe = $('.videoWrapper iframe'); // iframe
var contentH = $(window).height() - 158; // set container height 100% of window minus some space for the header and sticky navbar
var contentW = $(window).width(); // set container width 100% of window
var iframeH = contentH - 150; // set iframe height to container height minus some space for margins and hgroup
content.css = ('height',contentH); // set container height
iframe.css = ('height',iframeH); // set iframe height
var iframeW = iframeH/9 * 16; // calculate iframe aspect ratio
iframe.css('width',iframeW); // set iframe width
} );
$('iframe').load(function() {
var content = $('#hero');
var iframe = $('.videoWrapper iframe');
var contentH = $(window).height() - 158;
var contentW = $(window).width();
var iframeH = contentH - 150;
content.css = ('height',contentH);
var iframeW = iframeH/9 * 16;
iframe.css = ('width',iframeW);
} );
$(window).resize(function() {
var content = $('#hero');
var iframe = $('.videoWrapper iframe');
var contentH = $(window).height() - 158;
var iframeH = contentH - 150;
content.css = ('height',contentH);
iframe.css = ('height',iframeH);
var iframeW = iframeH/9 * 16;
iframe.css('width',iframeW);
var margin = ($(window).width() - iframeW) / 2;
$('.videoWrapper').style.marginLeft = margin;
} );
<div id="hero">
<div class="container">
<div class="row-fluid">
<hgroup class="span12 text-center">
<h1></h1>
<h2></h2>
</hgroup>
<script src="https://www.youtube.com/iframe_api"></script>
<center>
<div class="videoWrapper">
<div id="player"></div>
</div>
</center>
<script>
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
videoId:'xxxxxxxxxxx',playerVars: {
disablekb:1,enablejsapi:1,iv_load_policy:3
}
} );
}
</script>
</div>
</div>
</div>

Here is the final result I ended up with..
See full gist here and live example here.
#hero { width:100%;height:100%;background:url('{$img_ps_dir}cms/how-it-works/hero.jpg') no-repeat top center; }
.videoWrapper { position:relative;padding-bottom:56.25%;padding-top:25px;max-width:100%; }
<div id="hero">
<div class="container">
<div class="row-fluid">
<script src="https://www.youtube.com/iframe_api"></script>
<center>
<div class="videoWrapper">
<div id="player"></div>
</div>
</center>
<script>
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
videoId:'xxxxxxxxxxx',playerVars: { controls:0,autoplay:0,disablekb:1,enablejsapi:1,iv_load_policy:3,modestbranding:1,showinfo:0,rel:0,theme:'light' }
} );
resizeHeroVideo();
}
</script>
</div>
</div>
</div>
var player = null;
$( document ).ready(function() {
resizeHeroVideo();
} );
$(window).resize(function() {
resizeHeroVideo();
});
function resizeHeroVideo() {
var content = $('#hero');
var contentH = viewportSize.getHeight();
contentH -= 158;
content.css('height',contentH);
if(player != null) {
var iframe = $('.videoWrapper iframe');
var iframeH = contentH - 150;
if (isMobile) {
iframeH = 163;
}
iframe.css('height',iframeH);
var iframeW = iframeH/9 * 16;
iframe.css('width',iframeW);
}
}
resizeHeroVideo is called only after the Youtube player has fully loaded (on page load does not work), and whenever the browser window is resized. When it runs, it calculates the height and width of the iframe and assigns the appropriate values maintaining the correct aspect ratio. This works whether the window is resized horizontally or vertically.

You're probably right. It's most likely not working because the browser doesn't have the iframe loaded yet.
If there's an onload event from the YouTube iframe API, you could try calling your function with that.
Or (quicker but hackier) simply put in a javascript timeout for a beat later:
setTimeout(
function()
{
/*your resize code*/
}, 5000);
Where the number is the delay in miliseconds.

Related

Image sequence animation on scroll when element is reached

I'm trying to implement an animation that switches images on scroll when it's wrapping div scrolls into the viewport. My problem is that the animation starts as soon as someone starts scrolling, so the animation is already at the end when #wrapper comes into viewport.
How to achieve that the animation starts when #wrapper scrolls into the viewport?
Unfortunately my JS/jQuery knowledge is very poor but this is what I got til now:
JSFiddle
HTML:
<div class="page_content_before_image_animation">
<p>lorem ipsum …</p>
</div>
<div id="load" data-images="19"></div>
<div id="wrapper">
<img class="sequenzbilder" src="https://twdp.de/sequence/1.jpg" width="600" height="661" />
</div>
JS:
var images = [];
for (i = 1; i <= $('#load').attr('data-images'); i++) {
images.push('https://twdp.de/sequence/' + i + '.jpg');
}
$(images).each(function() {
$('<img class="sequenzbilder" />')[0].src = this;
});
var totalImages = images.length;
var pageHeight = $(document).height() - $(window).height();
var scrollInterval = Math.floor(pageHeight / 140);
var viewport = $(window),
slowdown;
viewport.on('scroll', function() {
i = Math.floor($(this).scrollTop() / scrollInterval);
$('.sequenzbilder').attr('src', images[i]);
slowdown = Math.ceil(viewport.scrollTop() / 20);
});

Progress bar in a div

I have a progress bar on my body. When I click on a button a div appear, we can scoll on this div and I would liked to have also a progress bar for this one. I took the Jquery code of the progress bar
MY JSFIDDLE
window.onscroll = function() {
myFunction()
};
function myFunction() {
var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
var scrolled = (winScroll / height) * 100;
document.getElementById("myBar").style.height = scrolled + "%";
}
$('button').click(function() {
if ($(this).hasClass("clicked")) {
$(this).text("Open ↓");
} else {
$(this).text("Close ↑");
}
$('.blue-container').toggleClass('In');
$('body').toggleClass('hideOverflow');
$(this).toggleClass("clicked");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="progress-container">
<div class="progress-bar" id="myBar"></div>
</div>
<button> Open ↓</button>
<div class='blue-container'>
<div class='blue'>
<p>Hello ! Scroll down. I would like to have a progress bar for this div, like the body.</p>
</div>
</div>
You need to create same progress setter function like you've set on window, except this one should use blue container scrollable element for scroll position measurement.
Remember that after your blue box is closed, you don't need setting progress from this box anymore, so you should unbind setter function ($scroller.off('scroll', progressSetter)). It will be bound again after next opening of blue box.
window.onscroll = function() {myFunction()};
function myFunction() {
var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
var scrolled = (winScroll / height) * 100;
document.getElementById("myBar").style.height = scrolled + "%";
}
$('button').on('click', function() {
var $container = $('.blue-container'),
$scroller = $container.find('.blue'),
$btn = $(this),
$bar = $('#myBar'),
progressSetter = function () {
var height = $scroller[0].scrollHeight - $scroller.outerHeight();
$bar.css({
height: $scroller.scrollTop() / height * 100 + '%'
});
};
if ($btn.hasClass("clicked")) {
$btn.text("Open ↓");
$scroller.off('scroll', progressSetter)
} else {
$btn.text("Close ↑");
$scroller.on('scroll', progressSetter)
}
$container.toggleClass('In');
$('body').toggleClass('hideOverflow');
$btn.toggleClass("clicked");
});
https://jsfiddle.net/uo34ru7d/76/
As I can see, you used example code from tutorial. Try to figure out how this scrolling bound functions work (and event binding itself) and you will be able to create one function for both window and your blue container, make that your homework ;)

Javascript not responsive on resize

Newbie to Javascript here.
I'm trying to make a simple one-page site with 3 sections: the Title area, a Portfolio area, and a contact form. Each of these sections is anchor-linked, so when the link is clicked the page scrolls down to that section.
I've used javascript to ensure that each section will fill the screen, centered horizontally and vertically if space permits. However, these measurements won't update on window resize.
I can't pinpoint the issue, since my initial code, which controls the height of the header depending on the height of the viewport, did update on resize until I added in the new lines.
Here is the script:
<script type="text/javascript">//<![CDATA[
function resize()
{
var heights = window.innerHeight;
var header = document.getElementById('title').offsetHeight;
var logo = document.getElementById('logo').offsetHeight;
var portfolioHeight = document.getElementById('portfolio-buttons').offsetHeight;
var hireHeight = document.getElementById('hire-form').offsetHeight;
document.getElementById('header').style.height = heights - header - logo * 0.4 + "px";
document.getElementById('portfolio').style.padding = (heights - portfolioHeight) * 0.5 + "px 0";
document.getElementById('hire').style.padding = (heights - hireHeight) * 0.5 + 5 + "px 0";
}
resize();
window.onresize = function() {
resize();
};
//]]>
</script>
And here is the basic structure of the relevant HTML :
<div id="portfolio">
<div id="portfolio-buttons">
Content here
</div>
</div>
<div id="hire">
<div id="hire-form">
Content here
</div>
</div>
EDIT: To be extra clear, here are the lines that work as their own script:
<script type="text/javascript">//<![CDATA[
function resize()
{
var heights = window.innerHeight;
var header = document.getElementById('title').offsetHeight;
var logo = document.getElementById('logo').offsetHeight;
document.getElementById('header').style.height = heights - header - logo * 0.4 + "px";
}
resize();
window.onresize = function() {
resize();
};
//]]>
</script>
And here are those that work, but only update on refresh, not resize.
<script type="text/javascript">//<![CDATA[
function resize()
{
var heights = window.innerHeight;
var portfolioHeight = document.getElementById('portfolio-buttons').offsetHeight;
var hireHeight = document.getElementById('hire-form').offsetHeight;
document.getElementById('portfolio').style.padding = (heights - portfolioHeight) * 0.5 + "px 0";
document.getElementById('hire').style.padding = (heights - hireHeight) * 0.5 + 5 + "px 0";
}
resize();
window.onresize = function() {
resize();
};
//]]>
</script>
Try
window.onresize = function() {
resize();
return true;
};
If that doesn't work, try using window.addEventListener("resize",function(){...}) isntead. To support older versions of IE, you'll have to check if(window.addEventListener){/*standards*/window.addEventListener("resize",function(){...})}else{/*IE only*/ window.attachEvent("onresize",function(){...}

How can I resize and crop/letterbox image to completely fill div with image whatever resize

This is what I need:
The image must completely fill 100% the area the div covers - left to
right and top to bottom.
the image must not be squashed or streched - just be cropped or
must overflow.
The image must be kept as small as possible, so whatever the resize - you
can still see either the very sides OR the very top and bottom.
The div itself will be adjusting in height and width as both are a percentage of the main window.
I have found a little bit of JavaScript here that is manipulating the image just how I want when the window is resized, but is displaying it in the whole window.
<html>
<head>
<title>test</title>
<script type="text/javascript">
function resizeImage()
{
var window_height = document.body.clientHeight
var window_width = document.body.clientWidth
var image_width = document.images[0].width
var image_height = document.images[0].height
var height_ratio = image_height / window_height
var width_ratio = image_width / window_width
if (height_ratio > width_ratio)
{
document.images[0].style.width = "100%"
document.images[0].style.height = "auto"
}
else
{
document.images[0].style.width = "auto"
document.images[0].style.height = "100%"
}
}
</script>
</head>
<body onresize="resizeImage()">
<img onload="resizeImage()" src="f/a.jpg">
</body>
</html>
Here is a demo
Please don't just answer that all I need is:
<img style="width : 100%;">
This is so much more than that.
It's not too easy to explain but check the demo and drag the corner of the window around and that'll be worth 1000 words...!
Can it (or something like it) be made to work the same way within a % sized div?
I wrote a jQuery plugin that does exactly this. Check out my blog post here and the demo here
jQuery.fn.resizeToParent = function(options) {
var defaults = {
parent: 'div'
}
var options = jQuery.extend(defaults, options);
return this.each(function() {
var o = options;
var obj = jQuery(this);
// bind to load of image
obj.load(function() {
// dimensions of the parent
var parentWidth = obj.parents(o.parent).width();
var parentHeight = obj.parents(o.parent).height();
// dimensions of the image
var imageWidth = obj.width();
var imageHeight = obj.height();
// step 1 - calculate the percentage difference between image width and container width
var diff = imageWidth / parentWidth;
// step 2 - if height divided by difference is smaller than container height, resize by height. otherwise resize by width
if ((imageHeight / diff) < parentHeight) {
obj.css({'width': 'auto', 'height': parentHeight});
// set image variables to new dimensions
imageWidth = imageWidth / (imageHeight / parentHeight);
imageHeight = parentHeight;
}
else {
obj.css({'height': 'auto', 'width': parentWidth});
// set image variables to new dimensions
imageWidth = parentWidth;
imageHeight = imageHeight / diff;
}
// step 3 - center image in container
var leftOffset = (imageWidth - parentWidth) / -2;
var topOffset = (imageHeight - parentHeight) / -2;
obj.css({'left': leftOffset, 'top': topOffset});
});
// force ie to run the load function if the image is cached
if (this.complete) {
obj.trigger('load');
}
});
}
And if you want the image to resize when the window is resized, just bind a resize handler to the window:
$(window).resize(function() {
$('img').resizeToParent();
});
Ok I've been playing around with it:
<html>
<head>
<title>test</title>
<style>
#imgarea {
position:absolute;
right:0px;
height:75%;
width:70%;
top:25%;
}
</style>
<script type="text/javascript">
function resizeImage()
{
var window_height = document.body.clientHeight
var window_width = document.body.clientWidth
var image_width = document.images[0].width
var image_height = document.images[0].height
var area_width = window_width * 0.7
var area_height = window_height * 0.75
var height_ratio = image_height / area_height
var width_ratio = image_width / area_width
if (height_ratio > width_ratio)
{
document.images[0].style.width = "100%"
document.images[0].style.height = "auto"
}
else
{
document.images[0].style.width = "auto"
document.images[0].style.height = "100%"
}
}
</script>
</head>
<body onresize="resizeImage()">
<div id="imgarea">
<img onload="resizeImage()" src="f/a.jpg">
</div>
</body>
</html>
It keeps resizing as the div resizes - as mentioned the div is
resizing with the window - this one keeps working seemlesly.
It seems to be OK across IE9, Fire Fox, Oprea, Chrome, and safari
over xp and 7
so really it answers my question perfectly, its just - now i've seen Christian's centering version i wish i had the know-how to make this do it i've tried a few things but am now stuck. Any Ideas?
P.S. if you dont know the width and height % of the div when you right the script i think it could be got with GetElementById - somehow... beyond me though;)

Javascript Resize Image not working

I have JS which resize the width and height of Image which is working fine if I used Alert before assigning the actual image src to the image object and if I omit the alertbox, it is not working. Please suggest me how to fix it.
`
<html>
<head>
<script type="text/javascript" language="javascript">
function resize_image_height_weight(id, hgt, wdth)
{
//alert(id);
Obj=document.getElementById(id);
myImage = new Image();
myImage.src = Obj.src;
var heights = myImage.height;
var widths = myImage.width;
// alert("Height=>" + heights + " Width=> " + widths);
if(heights > hgt || widths > wdth)
{
if(heights > widths)
{
var temp = heights/hgt;
var new_width = widths / temp;
new_width = parseInt(new_width);
heights = hgt;
widths = new_width;
}
else
{
var temp = widths/wdth;
var new_height = heights / temp;
new_height = parseInt(new_height);
heights = new_height;
widths = wdth;
}
}
Obj.height = heights;
Obj.width = widths;
}
</script>
</head>
<body>
<div>
<center>
<img src="http://www.google.co.in/intl/en_com/images/srpr/logo1w.png" id="i" alt="Google logo" height="150" width="150">
<script type="text/javascript">
document.images[document.images.length-1].onload = resize_image_height_weight("i",150,150);
</script>
</center>
</div>
</body>
</html>`
When you set the .src on an image, you have to wait until the image is successfully loaded until you can read it's height and width. There is an onload event handler that will tell you when the image is loaded.
Here's a place in your code where this issue could occur:
Obj=document.getElementById(id);
myImage = new Image();
myImage.src = Obj.src;
var heights = myImage.height;
var widths = myImage.width;
In this case, since the image was already elsewhere in the document, you should just read the height and width off the existing element rather than the new element.
Be very careful when testing because if the image is in your browser cache, it may load immediately, but when it's not in your cache, it takes some time to load and won't be available immediately.
Putting an alert at the right place in your script can allow the image to load before the script proceeds which could explain why it works with the alert.
As RobG mentions, your onload handler is also faulty (needs to be a function, not the returned result of a function).
Here's a simpler function to scale an image to fit the bounds. This uses a trick that you only need to set one size (height or width on the image) and the other will be scaled by the browser to preserve the aspect ratio.
function resizeImage(id, maxHeight, maxWidth) {
// assumes the image is already loaded
// assume no height and width is being forced on it yet
var img = document.getElementById(id);
var height = img.height || 0;
var width = img.width || 0;
if (height > maxHeight || width > maxWidth) {
var aspect = height / width;
var maxAspect = maxHeight / maxWidth;
if (aspect > maxAspect) {
img.style.height = maxHeight + "px";
} else {
img.style.width = maxWidth + "px";
}
}
}
You can see it in action here: http://jsfiddle.net/jfriend00/BeJg4/.
In the function assigned to onload:
> document.images[document.images.length-1].onload =
> resize_image_height_weight("i",150,150);
you are assigning the result of calling resize_image_height_weight which throws an error in IE. Set it to a function instead:
document.images[document.images.length-1].onload = function() {
resize_image_height_weight("i",150,150);
};

Categories

Resources