Positioning an image based on its height/width - javascript

I'm working on a simple script that acts as a slideshow.
It's based on this script.
Background:
Most of these types of scripts (including the more advanced ones) have the issue that they work great with landscape-style images but really mess portrait-style images up. So I'm trying to build something more or less from scratch.
Problem
I want my images centered on the page. So I use position:absolute; and left:50%; and top:50%; which puts left-most and top-most edge of the image in the proper position. But to center it you would need to do left:50% - imageWidth/2 (which obviously doesn't exist in CSS)
So I need to use javascript to get the image height/width and change it's left and top positioning as needed.
Here is my HTML:
<div class="fadewrapper">
<div class="fadein">
<img src="../Content/images/samples/1.jpg">
<img src="../Content/images/samples/2.jpg">
<img src="../Content/images/samples/3.jpg">
</div>
</div>
Here is my CSS:
.fadewrapper {width:100%; height:100%;}
.fadein { display:inline-block;}
.fadein img {position:absolute; top:50%;}
My knowledge in javascript is limited, but I've found this script (on SO):
var img = new Image();
img.onload = function () {
alert(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
This script works, but I don't know how to use the images on my page and how to then adjust its positioning. Any and all help is very much appreciated.

Here you go. This will set the image in the exact center of the wrapper.
win_width = $('#fadewrapper').width();
win_height = $('#fadewrapper').height();
border = $('#framewrapper').css('borderWidth');
$('.fadein img').each(function(){
$(this).css({
'left' : (win_width - $(this).width() - border ) / 2,
'top': (win_height - $(this).height() - border ) / 2
});
})
Here's a jsFiddle working example. It reacts based on the window size. Resize the output window to see it react

This might be worth of trying:
<DIV style="position:relative;top:100px;height:300px;text-align:center;white-space:nowrap">
<IMG id="your_img_id_1" src="your_img_source" height="100%">
<IMG id="your_img_id_2" src="your_img_source" height="100%">
<IMG id="your_img_id_3" src="your_img_source" height="100%">
</DIV>
Add these positioning rules to your fadewrapper-class, and remove all others. Then make changes needed to top and height values, but don't change the height-attribute values in IMG-elements. IDs can be omitted, if you don't need them.
EDIT:
I'm sorry, I didn't notice to check window resize. Code corrected. Width's shoul'd be OK with smaller window sizes now.
I've tested this in IE, FF, Opera and Chrome. In all those browsers images appear just like I want to. But if I've missunderstood what you'd like to have?

Related

How can I control an image's size

I am a skilled database / application programmer for the PC. I am also an ignorant html / javascript / web programmer.
I am creating some documentation about some .Net assemblies for our intranet. Ideally I would like to display an image full size if the browser window can fit it. If not then I would like to reduce it and toggle between a small version and full size version by a click. It is a dependency chart and can be different sizes for different pages. I would prefer a single function to handle this but being it is for our use none of the requirements I mentioned is set in stone. I would like to make it work well but nothing is mandatory.
I read a lot of stuff but couldn't find anything that matched what I wanted. First I tried this (after a few iterations):
<img src='Dependancy Charts/RotairAORFQ.png' width='100%' onclick='this.src="Dependancy Charts/RotairAORFQ.png";this.width=this.naturalWidth;this.height=this.naturalHeight;' ondblclick='this.src="Dependancy Charts/RotairAORFQ.png";this.width="100%";'>
It has problems. First off it enlarges a small image and it looks funny. Second I would have to put the code in every page. Third it requires a double click to restore it. I was going to live with those short commings but the double click fails. I can't figure out how to restore it.
So I tried to get fancy. I couldn't figure out how to get past problem 1, but solved 2 and 3 by creating a function in a separate file. Then I ran into what appeared to be the same problem. This was my second attempt:
function ImageToggle(Image)
{
if (ImageToggle.FullSize == 'undefined')
ImageToggle.FullSize = false;
if (ImageToggle.FullSize)
{
Image.width='100%';
ImageToggle.FullSize = false;
}
else
{
Image.width=Image.naturalWidth;
ImageToggle.FullSize = true;
}
return 0
}
And in my page:
<img src='Dependancy Charts/RotairAORFQ.png' width='100%' onclick='ImageToggle(this)'>
Can what I want be done? It doesn't sound impossible. If it is a large amount of effort would be required then alternate suggestions are acceptable.
You're probably interested in the max-width: 100% CSS property, rather than a flat-out width:100%. If you have a tiny image, it'll stay tiny. If you have a huge image, it gets resized to the width of the containing element.
For example: http://jsbin.com/kabepo/1/edit uses a small and a huge image, both with max-width:100%. As you can see, the small image is untouched, the huge image is resized to something sensible.
I would recommend that you set a the max-width: 100% CSS property for the image.
This will prevent the image's width from expanding to be greater than the container's width.
You can also do the same with max-height: 100% if you are having problems with the image overflowing vertically.
Please see this JSFiddle for an example.
(Note: If you set both a width and a height attribute on the <img> tag directly or in your CSS file your image will not be scaled proportionally.)
Does it have to be a toggle or would a mouseover work for you as well?
<style>
.FullSize { width:100px; height:auto; }
.FullSize:hover { width:90%; height:auto; }
</style>
<img src="Dependancy Charts/RotairAORFQ.png" class="FullSize">
Note: when image is made larger IN the page - the surrounding content will be displaced around it - depending on how you have set up the layout.
Also if you have any body margins or table or div paddings, using image width at 100% will make the page scroll. To check just change 90% to 100% and work your way up / down.
You could also force the image to be a specific size until the browser gets made smaller by the user / has a smaller resolution.
<style>
.FullSize {width:1000px;max-width:100%;height:auto;}
</style>
<img src="Dependancy Charts/RotairAORFQ.png" class="FullSize">
A tip: the image used must be the largest one. So minimum width of lets say 1200 pixels wide (if that is the forced image size you use). That way regardless of size it is it will remain clearer than a small image becoming a large. Since it's an intranet, file size shouldn't be an issue.
Thanks all for your help. Rob and Mike both pointed me to an excellent solution. I now have my page load with an image that fits the browser window, resizes with the browser and if the user is interested they can expand the image and scrollbars appear if necessary. I got this to work in a function so minimal code is needed for each page.
To load the image:
<p style="overflow:auto;">
<img src='Dependancy Charts/RotairAORFQ.png' width="100%" onclick='ImageToggle(this)'>
</p>
And the function:
function ImageToggle(Image)
{
if (ImageToggle.FullSize == 'undefined')
ImageToggle.FullSize = false;
if (ImageToggle.FullSize)
{
Image.style="max-width: 100%";
ImageToggle.FullSize = false;
}
else
{
Image.style="max-width: none";
Image.width=Image.naturalWidth;
ImageToggle.FullSize = true;
}
return 1
}
if you want to get current browser window size and if you want to do it on a click event so try this in jquery or javascript:
<script>
$("#myButton").click(function(){
var x = window.innerHeight; // put current window size in x (ie. 400)
});
</script>

DIV above iframe

I want to place a "PLAY" div above each iframe. I want to do it automatically.
I manage to do that manually but I don't know how to do it with a script , or with css.
Here is my HTML markup :
<ul data-role="listview" id="resultat"></ul>
And my Javascript code :
$('#resultat').append('<li class="liste" ><iframe id="ytplayer" type="text/html" width="140" height="100" src="http://www.youtube.com/embed/RD98kNOBrNs?hd=1&rel=0&autohide=1&showinfo=0&wmode=opaque" frameborder="0"/></li>').listview("refresh");
I'm using z-index and position attributes to place my div manually above the iframe, but I don't think it's a good idea to do it automatically.
Thanks
In addition to Matyas his answer, I have altered his code a bit such that it is now fully implementable.
First, take a look at the demo before I will explain all the details:
SEE DEMO CODE HERE
As you can see, I 'soft coded' all the widths and the heights such that the overlayDiv is placed exactly in the middle of the iFrame.
You can change the width and the height of the overlayDiv to whatever you want and the script will automatically adjust the position of the start button.
What is very important is that you must have the following order in your HTML for this to work:
<div id="vidFrame" class="play">
<iframe id="video" class="youtube-player" type="text/html" width="520" height="330" src="http://www.youtube.com/embed/-PZLM-CmuJ0?wmode=opaque&hd=1&rel=0&autohide=1&showinfo=0&enablejsapi=1" frameborder="0"></iframe>
</div>
<div class="overlayDiv">
<img src="https://www.ameliaconcours.org/UploadedContent/Lamborghini%20Logo_Crest_4C_S.png" alt="facebook" width="90px" />
</div>
Where the width and height of vidFrame doesn't have to be established beforehand because it will become the height of the iFrame.
Also, mind the following details:
wmode=opaque is the first argument we give to the video (must be the absolute first)
we enable the enablejsapi=1 such that we gain control over playing (and pausing) the video
The jQuery that I use is the following:
$.fn.loadOverlay = function() {
$('iframe').each(function(idx, iframe){
var imageHeight = $('.overlayDiv').height();
var imageWidth = $('.overlayDiv').width();
var marginTop = $('#video').height();
var marginTop = marginTop/2-imageHeight/2;
var marginLeft = $('#video').width();
var marginLeft = marginLeft/2-imageWidth/2;
$('.overlayDiv')
.clone()
.appendTo('body')
.css({
top: marginTop,
left: marginLeft,
}).show();
});
}
Note that, eventhough it is lengthy, it explicitly calculates the middle of the iFrame. Hence, shorter methods are possible but this one will make you understand exactly what is happening.
Now another thing: yt players always have the ugly red play button in the middle of their iFrame when loading a video.
There is a little hack to make this button disappear, namely:
function onPlayerReady(event){
//THIS IS THE TRICK THAT YOU MIGH WANT TO REMOVE
player.playVideo();
player.pauseVideo();
}
So essentially we play and then immediately pause the video to make the button disappear.
But mind you: this wil not work on mobile devices. A very big advantage of this is that the video will automatically start buffering which is an advantage for the user.
Furthermore, the jsFiddle is self-explanatory so just read it through and try to understand it.
I hope this answers your question. Good luck!
$('iframe').each(function(idx, iframe){ // for each iframe
var $iframe = $(iframe); // take its jquery reference
$('.overlayDiv') // grab the overlay template you wish to place over each
.clone() // clone it
.appendTo('body') // add it to the end of your page
.css({ // resize and position the overlay
top: $iframe.offset().top, // to fit just above the iframe
left: $iframe.offset().left,
height: $iframe.height(),
width: $iframe.width(),
}).show(); // show the hidden (by CSS) overlay
});
Initially your .overlayDiv should have the following styles:
.overlayDiv {
position: absolute; /* so when we position by js it will be above the iframe*/
display: none; /* the master tempalte should be hidden */
z-index: 4953; /* make sure the overlay appears above other elements */
}
I haven't tested it out, Just written it from scratch while my build was running. But this is the idea I'd go with. You might have to tinker with the positioning.

CSS or Javascript: How to fit two portrait images side by side in a container with fluid width?

I have a flexible .container with width:100%. I want to fit two portrait images (with varying widths) side by side into this `.container``
<div class="container">
<p>Some Text</p>
<img src="this-is-a-landscape-image.jpg" alt="test"/>
<p> Some Text again</p>
<img class="portait" src="this-is-a-portrait-image.jpg" alt="test"/>
<img class="portrait" src="this-is-a-portrait-image.jpg" alt="test"/>
</div>
The problem I have:
I'm working on a responsive-layout where this .container is flexible - width:100%.
However I want to be able to fit two images (that have the class .portrait) into this container side by side.
As you can see in this sample image, the two .portrait images are not necessarily the same width? I want them to be the same height, but the width should be dynamic (if they don't have the same ratio)
Is this somehow possible with pure css (maybe flexbox)? Or a little JS?
The contents are filled dynamically via a CMS, so that's the reason I can't hardcode it.
Any creative or helpful ideas?
I don't think there is a fully dynamic solution in pure css (though I would love to be proven wrong!)
I wrote a quick jQuery solution here: http://jsfiddle.net/d2gSK/2/
You can play with the image sizes, the window size, and the width of the gutter, and your height should stay the same for both images, while the width is set to proportion.
The javascript looks like this:
// put it in a function so you can easily reuse it elsewhere
function fitImages(img1, img2, gutter) {
// turn your images into jQuery objects (so we can use .width() )
var $img1 = $(img1);
var $img2 = $(img2);
// calculate the aspect ratio to maintain proportions
var ratio1 = $img1.width() / $img1.height();
var ratio2 = $img2.width() / $img2.height();
// get the target width of the two images combined, taking the gutter into account
var targetWidth = $img1.parent().width() - gutter;
// calculate the new width of each image
var width1 = targetWidth / (ratio1+ratio2) * ratio1;
var width2 = targetWidth / (ratio1+ratio2) * ratio2;
// set width, and height in proportion
$img1.width(width1);
$img1.height(width1 / ratio1);
$img2.width(width2);
$img2.height(width2 / ratio2);
// add the gutter
$img1.css('paddingRight', gutter + 'px');
}
//when the DOM is ready
$(document).ready(function() {
// cache the image container
var $wrapper = $('.portrait-wrapper');
// set the image sizes on load
fitImages($wrapper.children().get(0), $wrapper.children().get(1), 20);
// recalculate the image sizes on resize of the window
$(window).resize(function() {
fitImages($wrapper.children().get(0), $wrapper.children().get(1), 20);
});
});
I put the explanation inside the code. Feel free to ask if you want me to explain further.
Note that i put a wrapper around your images, and gave the images a display: block and a float:left, which is required to make this work!
You could do something like this.
<div class="container">
<p>Some Text</p>
<img src="this-is-a-landscape-image.jpg" alt="test"/>
<p> Some Text again</p>
<div class="portraits">
<img style="float:left;" class="portait" src="this-is-a-portrait-image.jpg" alt="test"/>
<img style="float:right;" class="portrait" src="this-is-a-portrait-image.jpg" alt="test"/>
</div>
</div>
Just add Float on them so they get out of the "normal flow", or you could even use position absolute, if the text between the top image and them stays the same at all times...
For the width: you can simply make their width in % as well so you can say give the first one 80% and the second 20% using pseudo classes...
another possibility would be that you make different hard coded css's where you can easily define at what page width you want to use what css, for example something like this:
#media screen and (max-width: 400px) {
.portrait:first {
width: 85px;
}
.portrait:last {
width: 105px;
}
}
and so on for every step on window size.
I Hope that helps :D

jquery - stretch background image to fill document rather than window?

I'm using this plugin: https://github.com/srobbin/jquery-backstretch to stretch a background in a good way.
So the issue is that if the content of the document is long enough to cause a scrollbar, then when you scroll, the image stays in the same place (just looks like a stationary background). You can see it in his demo here: http://srobbin.com/jquery-plugins/jquery-backstretch/ (this page uses the plugin. Just scroll and notice the background doesn't move).
I'm wondering if there's a way to change the plugin to not use the window height or something and rather use the document height? I've looked, but to no avail. I know this isn't a great idea in the case that the content is long, but it's done on only a single page that doesn't have much content at all. Really the only issues are if the browser real estate (not counting the chrome) is like less than around 650px in height.
Here's the plugin code. Pretty short and well written from what I can tell:
https://github.com/srobbin/jquery-backstretch/raw/master/jquery.backstretch.js
I once had the same problem, this was my solution.
$(window).resize(bg);
function bg() {
var imgWidth = 1088,
imgHeight = 858,
imgRatio = imgWidth / imgHeight,
bgWidth = $(document).width(),
bgHeight = bgWidth / imgRatio;
$('body').css({backgroundPosition: 'top center'});
if ($(document).width() < imgWidth && $(document).height() < imgHeight && $(document).height() > bgHeight) {
$('body').css({backgroundSize: 'auto 100%'});
} else {
$('body').css({backgroundSize: '100% auto'});
}
}
bg();
$('body').css({backgroundRepeat: 'repeat-x'});
$('body').css({backgroundImage: 'url("images/bg-state/bg_static2.png")'});
Note: It do not stretch on IE due to the code uses the css3 property background-size and you need to set your own width and height of the image in the code.
Another approach with scrollable content and a fixed background would be to just use an <iframe> or fixing the <img> on a layer. Then you wouldn't need to depend on jQuery (which I think is a bit heavy) for something that could be done on the browser without it.
<body background="background.png">
<iframe src="content.html" height="600"/>
</body>
Also found another way to do it with layers:
<img src="background.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index:-1;" />
<div style="position: static;z-index: 1; ">
content
</div>
Without paying respect to the image ratio, I believe you could set bgHeight to $("body").height().

Programmatically Clip/Cut image using Javascript

Are there any documents/tutorials on how to clip or cut a large image so that the user only sees a small portion of this image? Let's say the source image is 10 frames of animation, stacked end-on-end so that it's really wide. What could I do with Javascript to only display 1 arbitrary frame of animation at a time?
I've looked into this "CSS Spriting" technique but I don't think I can use that here. The source image is produced dynamically from the server; I won't know the total length, or the size of each frame, until it comes back from the server. I'm hoping that I can do something like:
var image = getElementByID('some-id');
image.src = pathToReallyLongImage;
// Any way to do this?!
image.width = cellWidth;
image.offset = cellWidth * imageNumber;
This can be done by enclosing your image in a "viewport" div. Set a width and height on the div (according to your needs), then set position: relative and overflow: hidden on it. Absolutely position your image inside of it and change the position to change which portions are displayed.
To display a 30x40 section of an image starting at (10,20):
<style type="text/css">
div.viewport {
overflow: hidden;
position: relative;
}
img.clipped {
display: block;
position: absolute;
}
</style>
<script type="text/javascript">
function setViewport(img, x, y, width, height) {
img.style.left = "-" + x + "px";
img.style.top = "-" + y + "px";
if (width !== undefined) {
img.parentNode.style.width = width + "px";
img.parentNode.style.height = height + "px";
}
}
setViewport(document.getElementsByTagName("img")[0], 10, 20, 30, 40);
</script>
<div class="viewport">
<img class="clipped" src="/images/clipped.png" alt="Clipped image"/>
</div>
The common CSS properties are associated with classes so that you can have multiple viewports / clipped images on your page. The setViewport(…) function can be called at any time to change what part of the image is displayed.
In answer to :
Alas, JavaScript simply isn't capable of extracting the properties of the image you'd require to do something like this. However, there may be salvation in the form of the HTML element combined with a bit of server-side scripting.
...
< ? (open php)
$large_image = 'path/to/large_image';
$full_w = imagesx($large_image);
$full_h = imagesy($large_image);
(close php) ? >
This can be done in Javascript, just google a bit :
var newimage = new Image();
newimage.src = document.getElementById('background').src;
var height = newimage.height;
var width = newimage.width;
This generates a new image from an existing one and captures this way in java script the original height and width properties of the original image (not the one id'ed as background.
In answer to :
The width/height properties of the document's image object are read only. If you could change them, however, you would only squish the frames, not cut the frames up like you desire. The kind of image manipulation you want can not be done with client-side javascript. I suggest cutting the images up on the server, or overlay a div on the image to hide the parts you do not wish to display.
...
var newimage = new Image();
newimage.src = document.getElementById('background').src;
var height = newimage.height;
var width = newimage.width;
newimage.style.height = '200px';
newimage.style.width = '200px';
newimage.height = '200px';
newimage.width = '200px';
and if wanted :
newimage.setAttribute('height','200px');
The doubled newimage.style.height and newimage.height is needed in certain circumstances in order to make sure that a IE will understand in time that the image is resized (you are going to render the thing immediately after, and the internal IE processing is too slow for that.)
Thanks for the above script I altered and implemented on http://morethanvoice.net/m1/reader13.php (right click menu... mouseover zoom lent) correct even in IE , but as you will notice the on mousemove image processing is too fast for the old styled IE, renders the position but only once the image. In any case any good idea is welcome.
Thanks to all for your attention, hope that the above codes can help someone...
Claudio Klemp
http://morethanvoice.net/m1/reader13.php
CSS also defines a style for clipping. See the clip property in the CSS specs.
The width/height properties of the document's image object are read only. If you could change them, however, you would only squish the frames, not cut the frames up like you desire. The kind of image manipulation you want can not be done with client-side javascript. I suggest cutting the images up on the server, or overlay a div on the image to hide the parts you do not wish to display.
What spriting does is essentially position a absolutely-positioned DIV inside another DIV that has overflow:hidden. You can do the same, all you need to do is resize the outer DIV depending on the size of each frame of the larger image. You can do that in code easily.
You can just set the inner DIV's style:
left: (your x-position = 0 or a negative integer * frame width)px
Most JavaScript Frameworks make this quite easy.
Alas, JavaScript simply isn't capable of extracting the properties of the image you'd require to do something like this. However, there may be salvation in the form of the HTML <canvas> element combined with a bit of server-side scripting.
PHP code to go about extracting the width and height of the really large image:
<?php
$large_image = 'path/to/large_image';
$full_w = imagesx($large_image);
$full_h = imagesy($large_image);
?>
From here, you'd then load the image into a <canvas> element, an example of which is documented here. Now, my theory was that you may be able to extract pixel data from a <canvas> element; assuming that you can, you would simply make sure to have some form of definite divider between the frames of the large image and then search for it within the canvas. Let's say you found the divider 110 pixels from the left of the image; you would then know that each "frame" was 110 pixels wide, and you've already got the full width stored in a PHP variable, so deciphering how much image you're working with would be a breeze.
The only speculative aspect to this method is whether or not JavaScript is capable of extracting color data from a specified location within an image loaded into a <canvas> element; if this is possible, then what you're trying to accomplish is entirely feasible.
I suppose you want to take a thumbnail for your image. You can use ImageThumbnail.js that created from prototype library in this way:
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="ImageThumbnail.js"></script>
<input type="file" id="photo">
<img src="empty.gif" id="thumbnail" width="80" height="0">
<script type="text/javascript">
<!--
new Image.Thumbnail('thumbnail', 'photo');
//-->
</script>
for more information
try use haxcv library haxcv js by simple functions
go to https://docs.haxcv.org/Methods/cutImage to read more about his library
var Pixels = _("img").cutImage (x , y , width , height );
_("img").src (Pixels.src);
// return cut image
but try to include library first

Categories

Resources