I'm having some div boxes where there is an image inside. What I want it to do, is to add a class to the image if the image height is smaller than the div box its inside.
But I have set the image to be a 100% width of the div box, so when I use jquery's .Height() on the image, it gives me the original size. Any suggestions?
<div class="boxe">
<asp:Literal ID="imgProjekt1" runat="server" />
<asp:Literal ID="litProjekt1" runat="server"/>
</div>
<div class="boxe forsideboxMiddle">
<asp:Literal ID="imgProjekt2" runat="server" />
<asp:Literal ID="litProjekt2" runat="server"/>
</div>
The literal with the ID imgProjekt1 and ImgProjekt2 makes a normal img tag from codebehind.
$(function() {
var myImage = $('img'),
originalHeight = myImage.height();
getImgSize(myImage, originalHeight, myImage[0].src);
});
/* http://stackoverflow.com/questions/1944280/determine-original-size-of-image-cross-browser */
function getImgSize(myImage, currentHeight, imgSrc) {
var newImg = new Image();
newImg.onload = function() {
if(newImg.height > currentHeight) {
myImage.addClass('smaller');
alert(newImg.height + ' > ' + currentHeight);
}
}
newImg.src = imgSrc;
}
DEMO
EDIT:
The class should only be added to the image when it's smaller than it's parent div in height. Bigger images shouldn't get the class, even if they are smaller than the source image.
Time for the code:
$(function() {
var myImage = $('img');
getImgSize(myImage);
});
/* http://stackoverflow.com/questions/1944280/determine-original-size-of-image-cross-browser */
function getImgSize(myImage) {
myImage.each(function() {
var that = $(this),
parent = that.parent(),
originalHeight = that.height(),
parentHeight = parent.height(),
newImg = new Image();
newImg.onload = function() {
if(
newImg.height > originalHeight &&
parentHeight > originalHeight
) {
that.addClass('smaller');
}
}
newImg.src = that[0].src;
});
}
DEMO2
Related
I want to change the size of an image with an input and buttons.
I have an input, to which i insert the desired size, an image and 2 buttons.
One for making the image size change according to the input ( for example, if the user typed 300 in the input, the image width and height, will both change to 300px).
And one for making the image size double itself, by clicking the other button.
javascript :
var myImg = document.getElementById("myImg")
var input = document.getElementById("insert")
function increaseSize()
{
input.value = myImg.size.width
input.value = myImg.size.height
}
function doubleSize()
{
myImg.style.width * 2
myImg.style.height * 2
}
It didn't work.
You've got errors in your code. The first thing I can see is in the increaseSize() function, you are assigning the value to the input, not the image.
input.value = myImg.size.width
This line means that you have taken the width of the image and inserted that value into your input, which is the opposite of what you want to do. You want to take the value in your input and inject it into the images style.width property. So for starters, change that function (also there is no .size property, you wanted .style:
// option 1 create within function
function increaseSize() {
var myImg = document.getElementById( "myImg" );
myImg.style.width = input.value;
myImg.style.height = input.value;
}
// option 2 pass as parameters
var myImg = document.getElementById( "myImg" ); // assign the variables
var input = document.getElementById( "size" );
function increaseSize( img, input ) { // create the function
img.style.width = input.value + 'px'; // assign a unit type to it, as it is a css value
img.style.height = input.value + 'px';
}
increaseSize( myImg ); // run the function, passing in our variables
You have to use style to assign width and height using CSS, please find below example, where I have used the button to change the size, you can do it with input field as well:
document.getElementById("go").addEventListener("click", function() {
var img = document.querySelectorAll("#container .image img")[0];
img.style.height = "200px";
img.style.width = "200px";
});
div#container {
width: 100%;
height: 100%;
}
div.image img {
position:fixed;
width: 100px;
height: 100px;
}
<button id="go">Increase</button>
<div id="container">
<div class="image"><img src="http://libcom.org/files/images/library/black-square.jpg"/></div>
</div>
The width and height properties return string with px appended to it so remove the px part convert it to number and multiply it by 2.
var myImg = document.getElementById("myImg")
var input = document.getElementById("insert")
function increaseSize() {
myImg.style.width = input.value + 'px';
myImg.style.height = input.value + 'px';
}
function doubleSize() {
myImg.style.width = Number(myImg.style.width.slice(0,-2)) * 2 + 'px';
myImg.style.height = Number(myImg.style.height.slice(0,-2)) * 2 + 'px';
}
Try this
function changeSize(){
console.log('Clikced change size!');
var size=parseInt(document.querySelector('#img_size').value);
var img=document.querySelector('#img');
img.width=size;
img.height=size;
}
function doubleSize(){
console.log('Clikced double size!');
var img=document.querySelector('#img');
var size=parseInt(img.width)*2;
img.width=size;
img.height=size;
}
<img src='http://placehold.it/120x120&text=image1' width='200px' height="200px" id="img">
<input type="number" id='img_size' >
<button id="change_size" onclick="changeSize()"> Change Size</button>
<button id="double_size" onclick="doubleSize()">Double Size</button>
What I'm trying to achieve: clicking on any image should either reveal a clear image if image is blurred or blur the image if image is clear
What's happening: clicking on blurred image clears the image, but clicking on it again does nothing. so, clicking on a clear image does not blur it (as it should).
Here's my code:
<script>
window.onload = init;
function init(e) {
var img = document.getElementsByTagName("img");
//var img = document.getElementById('pics');
img[0].onclick = unblur; // <- why not just img.onclick = unblur ??
img[1].onclick = unblur;
img[2].onclick = unblur;
console.log(img);
/*
var imageId = e.target.id; //zero
var img = document.getElementById(imageId);
*/
//img.onclick = unblur;
}
function unblur(e) {
var imageId = e.target.id; //zero
var img = document.getElementById(imageId);
var imageSource = img.src; //zeroblur.jpg
var clearImg = imageSource.substring(0, imageSource.length - 8);
var unblurredImg = imageId.concat('.jpg'); // zero.jpg
var blurredImg = imageId.concat('blur.jpg'); // zeroblur.jpg
console.log(imageSource);
console.log(img.src);
//console.log(imageSource);
if (img.src == unblurredImg) {
img.src = blurredImg;
} else {
img.src = unblurredImg; // image is clear, so hide the pic
}
/*
if (img.src == blurredImg) {
img.src = unblurredImg;
}
} */
//}
}
/*
//if (!(imageId instanceof img)) {
if (imageId !== "pics") {
if (img.src == blurredImg) {
img.src = unblurredImg;
} else if (img.src == unblurredImg) {
img.src = blurredImg;
} // image is blurred, so reveal the pic
else {
console.log("hi");
}
//debugger;
}
}
*/
/*
var img = document.getElementById('zero');
img.src = "zero.jpg";
*/
</script>
</head>
<body>
<div id="pics">
<img id="zero" src="zeroblur.jpg">
<img id="one" src="oneblur.jpg">
<img id="two" src="two.jpg">
</div>
</body>
</html>
I also noticed that if I switch the conditions in the function, unblur(e), to the following...
if (img.src == unblurredImg) {
img.src = blurredImg;
} else {
img.src = unblurredImg;
}
there's no response at all if a user clicks on a blurred image, whereas before (code above) the blurred image will at least reveal the cleared image.
Why is this happening? I see no difference between the two, besides just switching the order of the conditions.
There are various mistakes in your example. Take a look at the Code Snippet for a working example of what you are trying to achieve.
As for your comment:
// <- why not just img.onclick = unblur ??
Because document.getElementsByTagName returns an array of elements. Therefore, you must iterate through the elements to apply the onclick handlers to each one.
(function(document) {
var array = document.getElementsByTagName("img");
for (var i = 0; i < array.length; i++) {
array[i].onclick = toggleBlur;
}
function toggleBlur(event) {
var img = event.target;
var oldSrc = img.src; // Save to display in the console
if (img.src.endsWith("blur.jpg")) {
img.src = img.id + ".jpg";
} else {
img.src = img.id + "blur.jpg"
}
console.log(oldSrc + " -> " + img.src + " on element.id=" + img.id);
}
})(document);
<body>
<div id="pics">
<img id="zero" src="zero.jpg">
<img id="one" src="one.jpg">
<img id="two" src="twoblur.jpg">
</div>
</body>
I'm trying to get the width of two images based on their URLs (so, actual image size). I'm able to do that in such a way so as to pop up an alert based on the results, but anything outside of the actual function results in an undefined value for the widths of the two images.
var w1 = "";
var w2 = "";
var img1 = new Image();
img1.onload = function() { w1 = this.width;};
img1.src = "URL1";
var img2 = new Image();
img2.onload = function() { w2 = this.width;};
img2.src = "URL2";
alert (w1 + " and " + w2);
How do I use w1 and w2 outside of the functions that set them to this.width?
Ideally I'd like to compare them and later on use the larger one. But I can't even get them to show with their correct values in the alert (above).
Thanks in advance!
Adendum:
var img1 = new Image();
var img2 = new Image();
var one, two;
img1.src = "img1.jpg";
img2.src = "img2.jpg";
img1.onload = function() {img2.onload = function() {compareWidth(img1.width, img2.width);}}
var finalchoice;
var compareWidth = function (width1 ,width2){
if(width1 > width2){
finalchoice = img1.src;
alert(finalchoice);
return finalchoice;
}
else{
finalchoice = img2.src;
alert(finalchoice);
return finalchoice;
}
}
Idea being then to use final choice later in the .js file.
The alert (w1 + " and " + w2);
statment is executed before the image is loaded that's why the result is displaying undefined.
To compare the width of two images you can use this code.
<!DOCTYPE html>
<html>
<head>
<body>
</body>
<script>
var img1 = new Image();
img1.src = "w3javascript.gif";
img1.onload = function() {
document.body.appendChild(img1); //this is optional you can remove it
compareWidth(this.width);
}
var img2 = new Image();
img2.src = "author.jpg";
img2.onload = function() {
document.body.appendChild(img2); //this is optional you can remove it
compareWidth(this.width);
}
var w1;
var compareWidth = function (width){
//here you can do operation with width and height
if(typeof w1 == 'undefined'){
w1 = width;
}else{
if(w1 < width){
alert('do one thing');
}else{
alert('do other thing');
}
}
}
</script>
</html>
i would recommend using jQuery...
Just load jQuery ... > like <script src="{jquery-lib-path}"></script>
and do something like
var imgWidth = img.width():
So my goal is to have an image slideshow with 3 clickable hot spots at the bottom. I have the basic functionality of this down now, but my content div doesn't size itself properly until it loops through the images for the first time. I need everything to be sized and positioned correctly immediately when the page loads.
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#image").attr("src", images[0]);
});
//Click tracking
var badClicks = 0;
var skipClicks = 0;
var goodClicks = 0;
//Counter to keep track of images
var iCount = 0;
var images = [];
images[0] = "images/document.png";
images[1] = "images/document2.png";
images[2] = "images/document3.png";
function nextImage(){
iCount++;
//If there are no more images in the array, go back to the first image
if (images[iCount]==null) {
iCount = 0;
};
//Change image source to new image
$("#image").attr("src", images[iCount]);
//Set content wrapper width & height to current image's width & height
$("#content").css("width", $("#image").css("width"));
$("#content").css("height", $("#image").css("height"));
//Store content wrapper's new width and height into variables
var h = parseInt($("#content").css("height"));
var w = parseInt($("#content").css("width"));
//Move hotspot-wrapper to the bottom of the new image
//Height of content wrapper - height of hotspot wrapper = new top
$("#hotspot-wrapper").css("top", h - parseInt($("#hotspot-wrapper").css("height")));
console.log(images[iCount] + " h " + h + " w " + w);
}
//Do something with data for "bad" hotspot
function bad(){
badClicks++;
}
//Do something with data for "skip" hotspot
function skip(){
skipClicks++;
nextImage();
}
//Do something with data for "good" hotspot
function good(){
goodClicks++;
}
//Show the collected data
function displayResults(){
$("#results").append("<br />Bad: " + badClicks
+ " Skip: " + skipClicks
+ " Good: " + goodClicks);
}
</script>
</head>
<body>
<div id="content">
<img id="image" />
<div id="hotspot-wrapper">
<div id="hotspot-a" class="hotspot" onclick="bad();"></div>
<div id="hotspot-b" class="hotspot" onclick="skip();"></div>
<div id="hotspot-c" class="hotspot" onclick="good();"></div>
</div>
</div>
<br />
<div id="results" style="clear:both">
<button onclick="displayResults();" style="text-align: center">Show results</button>
</div>
Any help, tips or advice would be greatly appreciated!
Thanks!
First of all i prefer this way to init images array:
var images = [];
var image = new Image();
image.src = '/some/image/url.jpg';
/* while you doing this image already load in background - so its faster way*/
images.push(image);
You can display this images with jQuery this way:
$('#parend_of_image_div').html(images[iCount]);
And inside your nextImage function use this code:
var img = images[iCount];
$(img).load(function(){
var width = $(this).width()
var height = $(this).height();
/* do other stuff */
});
This is your problem
$("#image").css("width")
However, you havent set #image's width with css. You need to use
$('#image').width()
Also, to be safe, you should only continue with this part of the code AFTER your image has triggered a load event:
//Change image source to new image
$("#image").attr("src", images[iCount]).load(function(){
//Set content wrapper width & height to current image's width & height
$("#content").css("width", $("#image").width());
$("#content").css("height", $("#image").height());
//And then the rest...
I've got a little problem here. I've been trying to do an image gallery with JavaScript but there's something that I got a problem with. I can get the image to resize when the first image load, but as soon as I load another image, it won't resize anymore! Since the user will be able to upload a lot of different size pictures, I really need to make it work.
I've checked for ready-to-use image gallery and such and nothing was doing what I need to do.
Here's my javascript:
function changeCurrentImage(conteneur)
{
var img = conteneur.getElementsByTagName("img");
var imgUrl = img[0].src;
var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9);
var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.'));
var currentImg = document.getElementById('currentImage');
currentImg.src = imgFirstPart + "borne" + imgLastPart;
resize(document.getElementById('currentImage'), 375, 655);
}
function resize(img, maxh, maxw) {
var ratio = maxh/maxw;
if (img.height/img.width > ratio){
// height is the problem
if (img.height > maxh){
img.width = Math.round(img.width*(maxh/img.height));
img.height = maxh;
}
} else {
// width is the problem
if (img.width > maxw){
img.height = Math.round(img.height*(maxw/img.width));
img.width = maxw;
}
}
};
Here's the HTML (using ASP.Net Repeater):
<asp:Repeater ID="rptImages" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<a href="#">
<div id="thumbnailImageContainer1" onclick="changeCurrentImage(this)">
<div id="thumbnailImageContainer2">
<img id="thumbnailImage" src="<%# SiteUrl + Eval("ImageThumbnailPath")%>?rn=<%=Random()%>" alt="Photo" onload="resize(this, 60, 105)" />
</div>
</div>
</a>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
Most likely the image is not yet downloaded so img.height and img.width are not yet there. Technically you don't need to wait till the whole image is downloaded, you can poll the image in a timer until width and height are non-zero. This sounds messy but can be done nicely if you take the time to do it right. (I have an ImageLoader utility I made for this purpose....has only one timer even if it is handling multiple images at once, and calls a callback function when it has the sizes) I have to disagree with Marcel....client side works great for this sort of thing, and can work even if the images are from a source other than your server.
Edit: add ImageLoader utility:
var ImageLoader = {
maxChecks: 1000,
list: [],
intervalHandle : null,
loadImage : function (callback, url, userdata) {
var img = new Image ();
img.src = url;
if (img.width && img.height) {
callback (img.width, img.height, url, 0, userdata);
}
else {
var obj = {image: img, url: url, callback: callback,
checks: 1, userdata: userdata};
var i;
for (i=0; i < this.list.length; i++) {
if (this.list[i] == null)
break;
}
this.list[i] = obj;
if (!this.intervalHandle)
this.intervalHandle = setInterval(this.interval, 30);
}
},
// called by setInterval
interval : function () {
var count = 0;
var list = ImageLoader.list, item;
for (var i=0; i<list.length; i++) {
item = list[i];
if (item != null) {
if (item.image.width && item.image.height) {
item.callback (item.image.width, item.image.height,
item.url, item.checks, item.userdata);
ImageLoader.list[i] = null;
}
else if (item.checks > ImageLoader.maxChecks) {
item.callback (0, 0, item.url, item.checks, item.userdata);
ImageLoader.list[i] = null;
}
else {
count++;
item.checks++;
}
}
}
if (count == 0) {
ImageLoader.list = [];
clearInterval (ImageLoader.intervalHandle);
delete ImageLoader.intervalHandle;
}
}
};
Example usage:
var callback = function (width, height, url, checks, userdata) {
// show stuff in the title
document.title = "w: " + width + ", h:" + height +
", url:" + url + ", checks:" + checks + ", userdata: " + userdata;
var img = document.createElement("IMG");
img.src = url;
// size it to be 100 px wide, and the correct
// height for its aspect ratio
img.style.width = "100px";
img.style.height = ((height/width)*100) + "px";
document.body.appendChild (img);
};
ImageLoader.loadImage (callback,
"http://upload.wikimedia.org/wikipedia/commons/thumb/" +
"1/19/Caerulea3_crop.jpg/800px-Caerulea3_crop.jpg", 1);
ImageLoader.loadImage (callback,
"http://upload.wikimedia.org/wikipedia/commons/thumb/" +
"8/85/Calliphora_sp_Portrait.jpg/402px-Calliphora_sp_Portrait.jpg", 2);
With the way you have your code setup, I would try and call your resize function from an onload event.
function resize() {
var img = document.getElementById('currentImage');
var maxh = 375;
var maxw = 655;
var ratio = maxh/maxw;
if (img.height/img.width > ratio){
// height is the problem
if (img.height > maxh){
img.width = Math.round(img.width*(maxh/img.height));
img.height = maxh;
}
} else {
// width is the problem
if (img.width > maxw){
img.height = Math.round(img.height*(maxw/img.width));
img.width = maxw;
}
}
};
function changeCurrentImage(conteneur)
{
var img = conteneur.getElementsByTagName("img");
img.onload = resize;
var imgUrl = img[0].src;
var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9);
var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.'));
var currentImg = document.getElementById('currentImage');
currentImg.src = imgFirstPart + "borne" + imgLastPart;
}
I would play around with that. Maybe use global variables for your maxH/W and image ID(s);
#Comments: No, I can't do that server side since it would refresh the page everytime someone click on a new image. That would be way too bothersome and annoying for the users.
As for the thumbnails, those image are already saved in the appropriate size. Only the big image that shows is about 33% of its size. Since we already have 3 images PER uploaded images, I didn't want to upload a 4th one for each upload, that would take too much server space!
As for the "currentImage", I forgot to add it, so that might be helful lol:
<div id="currentImageContainer">
<div id="currentImageContainer1">
<div id="currentImageContainer2">
<img id="currentImage" src="#" alt="" onload="resize(this, 375, 655)" />
</div>
</div>
</div>
#rob: I'll try the ImageLoader class, that might do the trick.
I found an alternative that is working really well. Instead of changing that IMG width and height, I delete it and create a new one:
function changeCurrentImage(conteneur)
{
var thumbnailImg = conteneur.getElementsByTagName("img");
var thumbnailImgUrl = thumbnailImg[0].src;
var newImgUrl = thumbnailImgUrl.replace("thumbnail", "borne");
var currentImgDiv = document.getElementById('currentImageContainer2');
var currentImg = currentImgDiv.getElementById("currentImage");
if (currentImg != null)
{
currentImgDiv.removeChild(currentImg);
}
var newImg = document.createElement("img");
newImageDiv = document.getElementById('currentImageContainer2');
newImg.id = "currentImage";
newImg.onload = function() {
Resize(newImg, 375, 655);
newImageDiv.appendChild(newImg);
}
newImg.src = newImgUrl;
}
Also, in case people wonder, you MUST put the .onload before the .src when assigning an a new source for an image!