How do I fully stretch an image to a window via Fancybox? (Fancybox 2)
The fancybox stretches as big as the image size, but no further.
I noticed a number of CSS limits stuck in the fancybox css, like:
.fancybox-image, .fancybox-iframe {
display: block;
width: 100%;
height: 100%;
}
.fancybox-image {
max-width: 100%;
max-height: 100%;
}
Taking the max-width/height out and setting let's say width/height to 200% does stretch the image, but the containing rectangle itself (ie: the fancybox) is the same size, and it is no longer centered.
I am using the inline method with eg: jQuery(".fancybox").fancybox()
The i-pretty-much-gives-up-except-for-some-cool-but-useless-stuff approach:
.fancybox({
afterLoad : function () {
function gcd (x, y) {while (y != 0) {var z = x % y; x = y; y = z;} return x}
var body = $(document.body)
if (this.width/this.height > 1) {
// Max size is document body width.
var body_width = body.width()
var current_multiplier = gcd (this.width, body_width)
if (current_multiplier == 1) current_multiplier = body_width
} else {
// Max size is document body height.
var body_height = body.height()
var current_multiplier = gcd (this.height, body_height)
if (current_multiplier == 1) current_multiplier = body_height
}
this.width = this.width * current_multiplier
this.height = this.height * current_multiplier
}
})
Related
is there an easy way to get the final height and width of a background image with Javascript or jQuery even if a background-size property was applied?
I mean, I know I can get the background image url and load it to an Image object and then get the width and height. But it is the size of the source image. If someone scaled it with CSS then the size changed
How can I find its final size?
#edit
it is different from the question marked as similar because it doesnt say how to get the size in pixels if someone changed the background-size
Using getComputedStyle, I've created this script that returns the width and height of a given element's background, in pixels. It works with:
Dimensions (width or height) set to auto, either explicitly or because no specific value was given (width and height default to auto)
Dimensions set to percentage %
Dimensions set to pixels px
Dimensions set to a combination of any of the previous. (i.e width: 100px; height: auto or width: auto; height: 32.4% or height: 100px; width: 2% or width: 21.2%)
background-size set to cover or contain
It works if background-size is set with an external CSS file, inline CSS, inline header CSS or if it is not set at all (meaning width and height are auto).
Here's a JsFiddle (with cover example)
http://jsfiddle.net/gp4e9d3z/3/
And here's StackOverflow's code snippet (with percentage auto units)
function getBackgroundSize(elem) {
// This:
// * Gets elem computed styles:
// - CSS background-size
// - element's width and height
// * Extracts background URL
var computedStyle = getComputedStyle(elem),
image = new Image(),
src = computedStyle.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2'),
cssSize = computedStyle.backgroundSize,
elemW = parseInt(computedStyle.width.replace('px', ''), 10),
elemH = parseInt(computedStyle.height.replace('px', ''), 10),
elemDim = [elemW, elemH],
computedDim = [],
ratio;
// Load the image with the extracted URL.
// Should be in cache already.
image.src = src;
// Determine the 'ratio'
ratio = image.width > image.height ? image.width / image.height : image.height / image.width;
// Split background-size properties into array
cssSize = cssSize.split(' ');
// First property is width. It is always set to something.
computedDim[0] = cssSize[0];
// If height not set, set it to auto
computedDim[1] = cssSize.length > 1 ? cssSize[1] : 'auto';
if(cssSize[0] === 'cover') {
// Width is greater than height
if(elemDim[0] > elemDim[1]) {
// Elem's ratio greater than or equal to img ratio
if(elemDim[0] / elemDim[1] >= ratio) {
computedDim[0] = elemDim[0];
computedDim[1] = 'auto';
} else {
computedDim[0] = 'auto';
computedDim[1] = elemDim[1];
}
} else {
computedDim[0] = 'auto';
computedDim[1] = elemDim[1];
}
} else if(cssSize[0] === 'contain') {
// Width is less than height
if(elemDim[0] < elemDim[1]) {
computedDim[0] = elemDim[0];
computedDim[1] = 'auto';
} else {
// elem's ratio is greater than or equal to img ratio
if(elemDim[0] / elemDim[1] >= ratio) {
computedDim[0] = 'auto';
computedDim[1] = elemDim[1];
} else {
computedDim[1] = 'auto';
computedDim[0] = elemDim[0];
}
}
} else {
// If not 'cover' or 'contain', loop through the values
for(var i = cssSize.length; i--;) {
// Check if values are in pixels or in percentage
if (cssSize[i].indexOf('px') > -1) {
// If in pixels, just remove the 'px' to get the value
computedDim[i] = cssSize[i].replace('px', '');
} else if (cssSize[i].indexOf('%') > -1) {
// If percentage, get percentage of elem's dimension
// and assign it to the computed dimension
computedDim[i] = elemDim[i] * (cssSize[i].replace('%', '') / 100);
}
}
}
// If both values are set to auto, return image's
// original width and height
if(computedDim[0] === 'auto' && computedDim[1] === 'auto') {
computedDim[0] = image.width;
computedDim[1] = image.height;
} else {
// Depending on whether width or height is auto,
// calculate the value in pixels of auto.
// ratio in here is just getting proportions.
ratio = computedDim[0] === 'auto' ? image.height / computedDim[1] : image.width / computedDim[0];
computedDim[0] = computedDim[0] === 'auto' ? image.width / ratio : computedDim[0];
computedDim[1] = computedDim[1] === 'auto' ? image.height / ratio : computedDim[1];
}
// Finally, return an object with the width and height of the
// background image.
return {
width: computedDim[0],
height: computedDim[1]
};
}
// Stuff for debugging
function updateData() {
var background = getBackgroundSize(document.body);
document.getElementById('width').innerHTML = background.width + 'px';
document.getElementById('height').innerHTML = background.height + 'px';
document.getElementById('winWidth').innerHTML = getComputedStyle(document.body).width;
document.getElementById('winHeight').innerHTML = getComputedStyle(document.body).height;
}
// Execute onload, so that the background image is already loaded.
window.onload = window.onresize = updateData;
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
background: url('http://hdwallpapersfit.com/wp-content/uploads/2015/03/images-7.jpg');
background-size: 80% auto;
}
div {
background: rgba(0, 0, 0, 0.5);
color: #fff;
}
<div id="data">
Background width: <span id="width"></span>
<br>
Background height: <span id="height"></span>
<hr>
Body width: <span id="winWidth"></span>
<br>
Body height: <span id="winHeight"></span>
</div>
Using the JSFiddle Here, I found that changing the height or width of the container forces the image to be scaled to the largest height or width. Meaning that the measurement of one edge of the background will be equal to one of the dimension of the container. Using this and some proportions we can calculate the dimensions of the image.
// let .container represent element containing the image
var image; // the image object to the background image
var dim_h, dim_w; // the height and width of the actual image
height = $(".container").height();
width = $(".container").width();
if (height >= width)
{
dim_h = height;
dim_w = (height / image.height) * image.width;
}
else
{
dim_w = width;
dim_h = (width / image.width) * image.height;
}
// dim_w and dim_h contain the width and height of the actual
// background image after scaling
The above code uses the proportion below to calculate it.
(element_height / image_height) == (element_width / image_width)
I think it should give you the answer you want.
I am looking for simple solution to always keep aspect ratio of a video but also to always fit the video inside the browser window for both the width and the height.
So far all the solutions I have found have been fitting only by width, but I need also to fit height. :}
Bootstrap does this. The trick is that CSS padding bottom is computed based on the width of the element.
.video-container {
position: relative;
overflow: hidden;
height: 0;
padding-bottom: 56.25%; /* calculate by aspect ratio (h / w * 100%) */
}
.video-container .video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<div class="video-container">
<video class="video"></video>
</div>
See this example. It works with <embed>, <object>, <iframe>, and <video> tags. My example is just a colored <div> that keeps its' aspect ratio constant.
I wrote this for images originally for another question on SO, but it should work for just about any element. Just change the first variable to match your video element. You can also drop the for loop if you are only resizing a single element.
JS:
function resize() {
var img = document.getElementsByTagName('img');
var w = window.innerWidth;
var h = window.innerHeight;
//console.log(w);
//console.log(h);
for (i = 0; i < img.length; i++) {
var ratio = (img[i].clientHeight / img[i].clientWidth);
if (img[i].clientHeight > h && img[i].clientWidth < w) {
img[i].style.height = h + "px";
img[i].style.width = (h / ratio) + "px";
}
if (img[i].clientHeight <= h && img[i].clientWidth < w && ratio > 1) {
img[i].style.height = h + "px";
img[i].style.width = (h / ratio) + "px";
}
if (img[i].clientWidth >= w) {
img[i].style.width = w + "px";
}
if (img[i].clientHeight < h && img[i].clientWidth <= w && ratio < 1) {
img[i].style.width = w + "px";
}
}
}
resize();
window.onresize = resize;
JSFiddle: https://jsfiddle.net/hopkins_matt/k7t26sw5/
You could try the CSS only route. YouTube had the solution I was looking for which was keeping width, and height in a 16:9 ratio.
video {
width: 100%;
min-height: 480px;
height: calc((9 / 16) * 100vw);
max-height: calc(100vh - 169px);
}
With HTML5, the aspect of the video will mold to the parent no matter the video's ratio.
Try with Javascript...
function updateHeight()
{
var videoHeight = 9 * videoDom.offsetWidth / 16;
videoDom.style.height = vidoeHeight + "px";
}
window.onload = function()
{
updateHeight();
}
window.onresize = function()
{
updateHeight();
}
Assuming your video has 16:9 aspect ratio.
This code when run should resize the height and width that a image to fit the container.
This is the output from the code(from alerts):
2488: Images natural height
3264: Images natural width
450: The containers height
1063: The containers width
612: New height
844: New width
4: The number of times it was divided to get to output
**It should divide it 6 times to provide the outcome of:
New width: 544
New height: 414
**
I am almost certain that the problem is in the Java Script:
function resize(iid, eid) {
//Get the ID of the elements (ele being the container that the image is in and img being the image its self)
var img = document.getElementById('img');
var ele = document.getElementById('contaner');
//makes the var needed
var currentwidth = ele.clientWidth;
var currentheight = ele.clientHeight;
var naturalheight = img.naturalHeight;
var naturalwidth = img.naturalWidth;
var newheight = naturalheight;
var newwidth = naturalwidth;
var x = 0;
//runs a loop that should size the image
while (newheight > currentheight && newwidth > currentwidth){
x = x + 1;
newheight = naturalheight / x;
newwidth = naturalwidth / x;
}
newheight = Math.ceil(newheight);
newwidth = Math.ceil(newwidth);
//alerts out the answers
alert(naturalheight);
alert(naturalwidth);
alert(currentheight);
alert(currentwidth);
alert(newheight);
alert(newwidth);
alert(x);
}
#contaner {
height: 450px;
width: 90%;
margin: 5% auto;
position: relative;
}
#img {
height: 450px;
width: 90%;
}
<div id="contaner">
<img src = "..\..\Resorces\Images\SlideShow\img1.jpg" style="width:652px;height:489px;" id="img"/>
<div id="left_holder"><img onClick="slide(-1)" src="..\..\Resorces\Images\arrow_left.png" class="left"/></div>
<div id="right_holder"><img onClick="slide(+1)" src="..\..\Resorces\Images\arrow_right.png" class="right"/></div>
</div>
The problem is this line:
while (newheight > currentheight && newwidth > currentwidth)
It's stopping as soon as either width or height fits within the container, where as it seems like you want both to fit within the bounds of the container. Change to || and you'll get six iterations:
while (newheight > currentheight || newwidth > currentwidth)
I would like to create a function with jQuery/javascript that would fill a parent div with children divs of random sizes that add up the size of the parent.
For example, 10 child divs to fill a container div with proportions 1200px x 600px
<div class="container">
<!-- 10 child divs with random height and width. -->
</div>
You can use a function which splits a rectangle into two subrectangles, and recursivelly split these.
When splitting a rectangle into two parts, if it must contain an even number N of subrectangles, each part will have N/2 subrectangles.
When splitting a rectangle into two, if it must contain an odd number of leaf subrectangles, the bigger part will have one more child than the other.
function fillWithChilds(el, N) {
function rand(n) {
/* weight=100 means no random
weight=0 means totally random */
var weight = 50;
return Math.floor(weight*n/2+n*(100-weight)*Math.random())/100;
}
function main(N, x, y, hei, wid) {
if(N < 1) return;
if(N === 1) {
var child = document.createElement('div');
child.className = 'child';
child.style.left = x + 'px';
child.style.top = y + 'px';
child.style.width = wid + 'px';
child.style.height = hei + 'px';
el.appendChild(child);
return;
}
var halfN = Math.floor(N/2);
if(wid > hei) {
var newWid = rand(wid);
if(2*newWid > wid) halfN = N-halfN;
main(halfN, x, y, hei, newWid);
main(N-halfN, x+newWid, y, hei, wid-newWid);
} else {
var newHei = rand(hei);
if(2*newHei > hei) halfN = N-halfN;
main(halfN, x, y, newHei, wid);
main(N-halfN, x, y+newHei, hei-newHei, wid);
}
}
main(N, 0, 0, el.clientHeight, el.clientWidth);
}
fillWithChilds(document.getElementById('wrapper'), 11);
#wrapper {
background: #ccf;
position: relative;
height: 300px;
width: 400px
}
.child {
background: #cfc;
outline: 2px solid red;
position: absolute;
}
<div id="wrapper"></div>
The distributing will be a pain. I think there's a jQuery library out there that handles some of it... I'll poke around. This is a pretty fun problem, though.
Here's what I've go so far. It's a bit sparse.
http://jsfiddle.net/twPQ7/2/
The part that attempts to determine how many more components it should build is the rough part. I'm trying to keep this down to as few loops as possible:
var containerSize = getContainerSize();
var elementWidth = 0;
var elementHeight = 0;
// width
while (elementWidth < containerSize.x)
{
var size = generateElement();
elementWidth += size.x;
elementHeight += size.y;
}
// height, if not already full
while (elementHeight < containerSize.y)
{
var size = generateElement();
elementWidth += size.x;
elementHeight += size.y;
}
Cleaned it up a bit. Check the fiddle again: http://jsfiddle.net/twPQ7/2/
// determine the size of the container
var containerSize = getContainerSize();
var elementWidth = 0;
var elementHeight = 0;
// iteratively generate elements until we've hit the width of the container
while (elementWidth < containerSize.x)
{
var size = generateElement();
elementWidth += size.x;
// keep track of the tallest element.
if (size.y > elementHeight) elementHeight = size.y;
}
// iteratively generate elements until we've hit the height of the container
while (elementHeight < containerSize.y)
{
var size = generateElement();
elementHeight += size.y;
}
I have implemented a parallax scrolling effect based on a tutorial I found. The effect works great. However, when I specify the background images, I am unable to control the y (vertical) axis. This is causing problems because I'm trying to set locations on multiple layered images.
Any thoughts on what's causing the problem?
Here is one external script:
$(document).ready(function(){
$('#nav').localScroll(800);
//.parallax(xPosition, speedFactor, outerHeight) options:
//xPosition - Horizontal position of the element
//inertia - speed to move relative to vertical scroll. Example: 0.1 is one tenth the speed of scrolling, 2 is twice the speed of scrolling
//outerHeight (true/false) - Whether or not jQuery should use it's outerHeight option to determine when a section is in the viewport
$('#mainimagewrapper').parallax("50%", 1.3);
$('#secondaryimagewrapper').parallax("50%", 0.5);
$('.image2').parallax("50%", -0.1);
$('#aboutwrapper').parallax("50%", 1.7);
$('.image4').parallax("50%", 1.5);
})
This is another external script:
(function( $ ){
var $window = $(window);
var windowHeight = $window.height();
$window.resize(function () {
windowHeight = $window.height();
});
$.fn.parallax = function(xpos, speedFactor, outerHeight) {
var $this = $(this);
var getHeight;
var firstTop;
var paddingTop = 0;
//get the starting position of each element to have parallax applied to it
$this.each(function(){
firstTop = $this.offset().top;
});
if (outerHeight) {
getHeight = function(jqo) {
return jqo.outerHeight(true);
};
} else {
getHeight = function(jqo) {
return jqo.height();
};
}
// setup defaults if arguments aren't specified
if (arguments.length < 1 || xpos === null) xpos = "50%";
if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1;
if (arguments.length < 3 || outerHeight === null) outerHeight = true;
// function to be called whenever the window is scrolled or resized
function update(){
var pos = $window.scrollTop();
$this.each(function(){
var $element = $(this);
var top = $element.offset().top;
var height = getHeight($element);
// Check if totally above or totally below viewport
if (top + height < pos || top > pos + windowHeight) {
return;
}
$this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px");
});
}
$window.bind('scroll', update).resize(update);
update();
};
})(jQuery);
Here is the CSS for one section:
#aboutwrapper {
background-image: url(../images/polaroid.png);
background-position: 50% 0;
background-repeat: no-repeat;
background-attachment: fixed;
color: white;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
#aboutwrapper .image4 {
background: url(../images/polaroid2.png) 50% 0 no-repeat fixed;
height: 500px;
width: 100%;
margin: 0 auto;
padding: 0;
}
.image3{
margin: 0 auto;
min-width: 970px;
overflow: auto;
width: 970px;
}
Both of these are being called to achieve the parallax scrolling. I really just want to more specifically control the background image locations. I've tried messing with the CSS background position and I've messed with the first javascript snippet as well. No luck.
just a quick shot, have you tried actually placing the images, either in a div or just using the img src tag to actually move the element rather than manipulating the y axis of a background image?