Different images loaded for different web screen sizes - javascript

I have this code which loads automatically a different picture from an array everytime a user loads index.html. This is the jquery code:
$(window).load(function() {
var randomImages = ['img1','img2','img3','img4','img5'];
var rndNum = Math.floor(Math.random() * randomImages.length);
var $win = $(this);
var $img = $('#background').attr('src', '_img/bg/index_rnd/' + randomImages[rndNum] + '.jpg').css({'position':'fixed','top':0,'left':0});
function resize() {
if (($win.width() / $win.height()) < ($img.width() / $img.height())) {
$img.css({'height':'100%','width':'auto'});
} else {
$img.css({'width':'100%','height':'auto'});
}
}
$win.resize(function() { resize(); }).trigger('resize');
});
I'm new with adapting images to different screen resolutions. So I thought that if somebody opens my web with for example an imac with 2560/1440px the image will be adapted correctly with this code, but I suppose it will be completely pixeled. So I think, I have to create a larger image file so those computers load the bigger file to adapt in resolution. I want to avoid that other users with a normal screen load the big file for speed reasons. What could I add to this code to make bigger screens load a bigger file so it doesnt pixalate?!?!
P.D. If you also know which is the best image resolution for different groups of screen sizes it would be VERY helpful!
Thanks!

You could always check the window size, either height or width, whatever floats your boat, and add something to the image filenames to load high res images, like having img4.jpg as a normal image and img4_big.jpg as a high res image etc.
Would look something like this :
$(window).load(function() {
var randomImages = ['img1', 'img2', 'img3', 'img4', 'img5'];
var rndNum = Math.floor(Math.random() * randomImages.length);
var $win = $(this);
//add _big to image filename if window width is over 1920px,
//like so : img4_big.jpg etc.
var isBig = $(window).width() > 1920 ? '_big' : '';
//add the string to the image filename
var $img = $('#background')
.attr('src', '_img/bg/index_rnd/' + randomImages[rndNum] + isBig + '.jpg')
.css({
'position': 'fixed',
'top': 0,
'left': 0
});
function resize() {
if (($win.width() / $win.height()) < ($img.width() / $img.height())) {
$img.css({
'height': '100%',
'width': 'auto'
});
} else {
$img.css({
'width': '100%',
'height': 'auto'
});
}
}
$win.resize(function() {
resize();
}).trigger('resize');
});​

Related

Resize images with Javascript to fit them within the viewport

I'm calling an API that returns a URL to an image, the image could be any size and it's completely random.
I'm trying to resize images to fit within the page, ensuring the content is not pushed below the fold, or that the image doesn't hit the width of the page.
I've written some Javascript below, I've been testing it and am getting some strange results - the console logs are saying that the image is one size, but the element selector in Chrome's dev tools is usually saying something completely different. I'm sure I've made some basic mistake in my code, if you could take a look that would be great.
Javascript sets viewport height and width, checks if a photo src is available. Once the image has loaded, it checks if the natural dimensions are greater than that of the viewport, if so it attempts to resize - this is where the script is failing.
//check viewport
var viewportWidth = getWidth();
var viewportHeight = getHeight();
//get the media
if (data[2] == "photo") {
var tweetImage = document.getElementById("tweetImage");
//when it loads check the size against the browser size
tweetImage.onload = function () {
console.log('image height: ' + tweetImage.naturalHeight);
console.log('viewport height: ' + viewportHeight);
//does it matter if its landscape?
if (viewportWidth - tweetImage.naturalWidth < 1) {
tweetImage.width = Math.floor(tweetImage.naturalWidth - (viewportWidth - tweetImage.naturalWidth) * 1.2);
console.log('w');
} else if (Math.floor(viewportHeight - tweetImage.naturalHeight) < 1) {
console.log('h');
console.log(viewportHeight - tweetImage.naturalHeight);
console.log('changed result: ' + Math.floor(tweetImage.naturalHeight - (Math.abs(viewportHeight - tweetImage.naturalHeight))));
tweetImage.height = Math.floor(tweetImage.naturalHeight - (Math.abs(viewportHeight - tweetImage.naturalHeight)*1.2));
} else {
tweetImage.height = Math.floor(viewportHeight / 2);
}
tweetImage.align = "center";
tweetImage.paddingBottom = "10px";
};
//tweetImage.height = Math.floor(viewportHeight / 2);
tweetImage.src = data[3];
}
One option would be to use a CSS-based solution like viewport height units.
.example {
height: 50vh; // 50% of viewport height
}
See http://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/

javascript image resize window

I have a problem with a JavaScript I'm developing for my website. I have images which opens on hovering over them.
First my script calculates if the image should be displayed on the right or on the left of my window:
$("html,body").live("mousemove", function (e) {
//console.log("mousemove: "+e.pageX)
var width_window = $(window).width();
var center = width_window / 2;
if (e.pageX < center) {
side = 'left';
} else {
side = 'right';
}
});
Then, once we know on which side of the window the image will be displayed, I have another script to resize the image, depending of the height & width of my window, including the margins:
this.resizeImg = function (img, offset) {
var d = new Date();
//console.log(d, side);
var window_height = $(window).height();
var img_height = $(img).height();
var img_top = $(img).offset().top;
var window_width = $(window).width();
var img_width = $(img).width();
var img_left;
side == 'left' ? img_left = offset.left : img_left = window_width - offset.left;
console.log(window_width, img_left)
var image_resize_height = window_height - img_top - 20;
var image_resize_width = window_width - img_left - 20;
if (img_height + img_top > window_height && img_width + img_left > window_width) {
console.log("h w")
if (image_resize_width > image_resize_height) {
$(img).css('height', image_resize_height + 'px').css("width", "auto");
} else {
$(img).css('width', image_resize_width + 'px').css("height", "auto");
}
} else if (img_height + img_top > window_height) {
//console.log("h")
$(img).css('height', image_resize_height + 'px').css("width", "auto");
} else if (img_width + img_left > window_width) {
//console.log("w")
$(img).css('width', image_resize_width + 'px').css("height", "auto");
} else {
//console.log("non")
}
};
It almost works, but sometimes my images exceed the window width or height. I can't find the solution...
Here is my CSS:
.vignette {
max-height: 800px;
max-width : 800px;
z-index : 2;
top : 25px;
}
.info{
position : relative;
}
.info img {
position : absolute;
display : none;
cursor : pointer;
}
My full script in jsFiddle: http://jsfiddle.net/CrnNZ/
Here is the link to my website : http://olivierlellouche.com/
Thanks a lot for your help !
Are you taking care of the fact that you are moving the image down 25px in:
.vignette {
top : 25px;
}
The only height adjustment I see is 20px:
var image_resize_height = window_height - img_top - 20;
You may just need to subtract few more pixels to your calculations?
Or better yet:
var img_top = $(img).offset().top;
May be top of the offset area and not the raw top of the image. In which case, you still need to subtract 25px for that.
(From your website) The other thing that may be useful is to always enable, or always disable the vertical scroll-bar on the right. Or re-size the text area to be smaller than the available area when their isn't a scroll-bar. (Unfortunately, I could not get your jsfiddle to work at all and the only error from their I could view was vertical calculation errors. I could not see any horizontal errors.)
Does the problem continue if you subtract a few more pixels off the height?
I can't tell from your code but, does it place the image then re-size it? It may be better idea to calculate the size available before trying to place the image, that way it never changes sizes once it is placed.
EDIT:
After looking at your webpage with much smaller sized window I thought of something else. $(window).height() is not the same as $(document).height(). See: $(window).height() vs $(document).height You may need to calculate the remaining page differently if they are not the same.

how to direct download button to url with showing the image

i have this code. and i want when i press download image that it will show the filtered image in my designed webpage. someone can help me how can i do this?
i know i have to change something here in the url. but its dont working and i dont really know why:
var url = canvas.toDataURL("image/png;base64;"); downloadImage.attr('href', url);
please help me.
$(function() {
/*
In this code, we are going to do the following:
1. Accept an image on drag and drop
2. Create a new canvas element (original), with a max size
of 500x500px (customizable) and keep it in memory
3. Listen for clicks on the filters. When one is selected:
3.1 Create a clone of the original canvas
3.2 Remove any canvas elements currently on the page
3.3 Append the clone to the #photo div
3.4 If the selected filter is different from the "Normal"
one, call the Caman library. Otherwise do nothing.
3.5 Mark the selected filter with the "active" class
4. Trigger the "Normal" filter
*/
var maxWidth = 500,
maxHeight = 500,
photo = $('#photo'),
originalCanvas = null,
filters = $('#filters li a'),
filterContainer = $('#filterContainer');
// Use the fileReader plugin to listen for
// file drag and drop on the photo div:
photo.fileReaderJS({
on:{
load: function(e, file){
// An image has been dropped.
var img = $('<img>').appendTo(photo),
imgWidth, newWidth,
imgHeight, newHeight,
ratio;
// Remove canvas elements left on the page
// from previous image drag/drops.
photo.find('canvas').remove();
filters.removeClass('active');
// When the image is loaded successfully,
// we can find out its width/height:
img.load(function() {
imgWidth = this.width;
imgHeight = this.height;
// Calculate the new image dimensions, so they fit
// inside the maxWidth x maxHeight bounding box
if (imgWidth >= maxWidth || imgHeight >= maxHeight) {
// The image is too large,
// resize it to fit a 500x500 square!
if (imgWidth > imgHeight) {
// Wide
ratio = imgWidth / maxWidth;
newWidth = maxWidth;
newHeight = imgHeight / ratio;
} else {
// Tall or square
ratio = imgHeight / maxHeight;
newHeight = maxHeight;
newWidth = imgWidth / ratio;
}
} else {
newHeight = imgHeight;
newWidth = imgWidth;
}
// Create the original canvas.
originalCanvas = $('<canvas>');
var originalContext = originalCanvas[0].getContext('2d');
// Set the attributes for centering the canvas
originalCanvas.attr({
width: newWidth,
height: newHeight
}).css({
marginTop: -newHeight/2,
marginLeft: -newWidth/2
});
// Draw the dropped image to the canvas
// with the new dimensions
originalContext.drawImage(this, 0, 0, newWidth, newHeight);
// We don't need this any more
img.remove();
filterContainer.fadeIn();
// Trigger the default "normal" filter
filters.first().click();
});
// Set the src of the img, which will
// trigger the load event when done:
img.attr('src', e.target.result);
},
beforestart: function(file){
// Accept only images.
// Returning false will reject the file.
return /^image/.test(file.type);
}
}
});
// Listen for clicks on the filters
filters.click(function(e){
e.preventDefault();
var f = $(this);
if(f.is('.active')){
// Apply filters only once
return false;
}
filters.removeClass('active');
f.addClass('active');
// Clone the canvas
var clone = originalCanvas.clone();
// Clone the image stored in the canvas as well
clone[0].getContext('2d').drawImage(originalCanvas[0],0,0);
// Add the clone to the page and trigger
// the Caman library on it
photo.find('canvas').remove().end().append(clone);
var effect = $.trim(f[0].id);
Caman(clone[0], function () {
// If such an effect exists, use it:
if( effect in this){
this[effect]();
this.render();
// Show the download button
showDownload(clone[0]);
}
else{
hideDownload();
}
});
});
// Use the mousewheel plugin to scroll
// scroll the div more intuitively
filterContainer.find('ul').on('mousewheel',function(e, delta){
this.scrollLeft -= (delta * 50);
e.preventDefault();
});
var downloadImage = $('a.downloadImage');
function showDownload(canvas){
downloadImage.off('click').click(function(){
// When the download link is clicked, get the
// DataURL of the image and set it as href:
var url = canvas.toDataURL("image/png;base64;");
downloadImage.attr('href', url);
}).fadeIn();
}
function hideDownload(){
downloadImage.fadeOut();
}
});
You can try this:
var downloadImage = $('a.downloadImage');
var url = canvas.toDataURL("image/png;base64;");
downloadImage.attr('href', url);

Container height based on every 2 images row

I´m working on this website
I´m doing the resize of vertical images using this script:
function Gallery(selector) {
this.add_module = function (type, image) {
var portrait_text = image.next('.portrait_text');
var container = $('<div />', {
'class': 'gallery_container'
}).append(image).append(portrait_text);
if (type == 'horizontal') {
var h_ar = image.attr('height') / image.attr('width');
var c_width = selector.width();
var c_height = selector.width() * h_ar
container.css({
'width': c_width,
'height': c_height
})
}
if (type == 'vertical') {
var c_width = v_width;
var c_height = v_height
container.css({
'width': Math.floor(v_width),
'height': v_height
})
}
container.css({
'float': 'left',
})
container.find('img').attr({
'width': '100%',
'height': '100%'
})
container.attr('ar', c_height / c_width)
container.appendTo(selector);
//container.children('img').fitToBox();
}
this.resized = function () {
//console.log(sel)
$('.gallery_container').each(function () {
if ($(this).attr('ar') >= 1) { // vertical
$(this).css({
'width': sel.width() / 2,
'height': sel.width() / 2 * $(this).attr('ar')
})
} else { // horizontal
$(this).css({
'width': sel.width(),
'height': sel.width() * $(this).attr('ar')
})
}
})
}
var _this = this;
var gutter = 0;
// start vars for counting on vertical images
var v_counter = 0;
var w_pxls = 0;
var h_pxls = 0;
var v_ar;
// iterates through images looking for verticals
selector.children('img').each(function () {
if (parseInt($(this).attr('width')) < parseInt($(this).attr('height'))) {
v_counter++;
h_pxls += $(this).attr('height');
w_pxls += $(this).attr('width');
v_ar = $(this).attr('height') / $(this).attr('width')
}
})
// calculates average ar for vertical images (anything outside from aspect ratio will be croped)
var h_avrg = Math.floor(h_pxls / v_counter);
var w_avrg = Math.floor(w_pxls / v_counter);
var v_width = Math.floor((selector.width()) / 2);
var v_height = v_width * v_ar;
var sel = selector;
selector.children('img').each(function () {
if (parseInt($(this).attr('width')) > parseInt($(this).attr('height'))) {
_this.add_module('horizontal', $(this));
} else {
_this.add_module('vertical', $(this));
}
})
$(window).bind('resize', _this.resized);
}
var gallery = new Gallery($('#gallery_images_inner'));
http://jsfiddle.net/mZ2Ks/
The problem I have is that the script makes all the container the same of height (depending on the last image on the page I think), so for example first images resizes in a bad way. If you look at the example, all 2 image rows have a height of 613px.
Is there any way how can I control each two images container to calculate it´s own height based on its images, it looks like right now it calculates the last image resize height and apply it to all other containers
Applying height: auto instead of 100% won´t work cause it will not make the images fit the height of the vertical container.
How can I fix the script?
yes, there is a easy way. but frist: your gallery-script calculates a average aspect ratio for all images inside. there is no simple way to change this behavior.
But you can do this simple workaround: put echt two images in their own gallery!
var gallery1 = new Gallery($('#gallery_images_inner1'));
var gallery2 = new Gallery($('#gallery_images_inner2'));
var gallery3 = new Gallery($('#gallery_images_inner3'));
See http://jsfiddle.net/mZ2Ks/2/ - i had to clean up your html code a little bit - you copied the "javascript affected" html code from (i assume) firebug, but you should have copied the plain html from source code direct (CTRL + U in firefox).

Resize image which uses Jcrop

I use the Jquery Jcrop for cropping my images. Now I'm implementing a slider for resizing the image. I want the cropping and resizing to happend on the same page.
I do it like this:
$(document).ready(function() {
var img = $('#cropbox')[0]; // Get my img elem
var orgwidth, orgheight;
$("<img/>") // Make in memory copy of image to avoid css issues
.attr("src", $(img).attr("src"))
.load(function() {
orgwidth = this.width; // Note: $(this).width() will not
orgheight = this.height; // work for in memory images.
});
$('#cropbox').Jcrop({
onSelect: updateCoords
});
$("#imageslider").slider({
value: 100,
max: 100,
min: 1,
slide: function(event, ui) {
//$('ul#grid li').css('font-size',ui.value+"px");
resizeImage(orgwidth, orgheight);
}
});
});
And my simple resizeImage function:
function resizeImage(orgwidth, orgheight) {
var value = $('#imageslider').slider('option', 'value');
var width = orgwidth * (value / 100);
var height = orgheight * (value / 100);
$('#cropbox').width(width);
$('#cropbox').height(height);
$('#tester').val("org: "+orgwidth+" now: "+width);
}
The problem is that, as soon I turn on Jcrop I can't resize the image. How can I use both these functions at the same time?
I ended up destroying the jCrop while resizing and putting it back on after resize. Thanks anyway. Code:
function resizeImage(orgwidth, orgheight) {
jcrop_api.destroy();
var value = $('#imageslider').slider('option', 'value');
var width = orgwidth * (value / 100);
var height = orgheight * (value / 100);
$('#cropbox').width(width);
$('#cropbox').height(height);
$('#rw').val(width);
$('#rh').val(height);
initJcrop();
}
I had the same task to accomplish: resize the image with a slider where jCrop is applied. There are some more elements you have to resize also that jCrop created, not only the image. I ended up patching the jCrop plugin and here is the patch for latest jCrop-0.9.10.
Patch your jCrop. If you don't know how to apply the patch, just put the resizeImage function to line 1578 of jCrop (unimified version ofcourse):
--- /home/dr0bz/Desktop/jquery.Jcrop.js
+++ /home/dr0bz/workspace/profile_tuning/js/lib/jquery.Jcrop.js
## -1573,6 +1573,15 ##
ui: {
holder: $div,
selection: $sel
+ },
+
+ resizeImage: function(width, height) {
+ boundx = width;
+ boundy = height;
+ $([$img2, $img, $div, $trk]).each(function(index, element)
+ {
+ element.width(width).height(height);
+ });
}
};
Get the jCrop API:
var jCropApi;
$('#photo').Jcrop({}, function()
{
jCropApi = this;
});
Calc new height and width. If your are doing it with a slider, let the slider say return the new width of the image and you calculate new height with aspect ratio of the image:
var aspectRatio = width / height;
// newWidth returned by slider
var newHeight = Math.round(width / aspectRatio);
jCropApi.resizeImage(newWidth, newHeight);
There are some other points to keep an eye on. After each resize your should look that crop area is still in the viewport of the image. If you need i could post the complete source how i've done it for me: jCrop + jquery ui slider to resize the image.
Regards
What you can also do is make use of the setImage function of Jcrop, when the slider changes, call the setImage with the Jcrop api and set new width and height values like this:
var jcrop_api;
$('#cropbox').Jcrop({
onSelect: updateCoords
}, function() {
jcrop_api = this;
});
$("#imageslider").slider({
value: 100,
max: 100,
min: 1,
slide: function(event, ui) {
var value = $('#imageslider').slider('option', 'value');
var width = orgwidth * (value / 100);
var height = orgheight * (value / 100);
jcrop_api.setImage($(img).attr("src"), function() {
this.setOptions({
boxWidth: width,
boxHeight: height
});
});
$('#tester').val("org: "+orgwidth+" now: "+width);
}
});
What I am not sure about this technique is if it is the best solution because everytime you call the setImage function, jcrop creates a new Image object.
If what you want is that the resizing should be proportional, I don't think you need the slider (since it seems to be incompatible with jCrop). You could use jCrop and in the onChange event, ensure the proportionality (that is, implement the resizeImage function, modified).
That's what I think.
As an extension to Hermann Bier answer, i have added the jquery animation.
The resizing looks way better when it's animated :)
Implemented in Jcrop version: jquery.Jcrop.js v0.9.12
Locate the code:
ui: {
holder: $div,
selection: $sel
}
in jquery.Jcrop.js around line 1573
and replace it with:
ui: {
holder: $div,
selection: $sel
},
resizeImage: function(width, height) {
animationsTid = 500;
boundx = width;
boundy = height;
$($img2).animate({
width: width,
height: height,
}, { duration: animationsTid, queue: false });
$($img).animate({
width: width,
height: height,
}, { duration: animationsTid, queue: false });
$($div).animate({
width: width,
height: height,
}, { duration: animationsTid, queue: false });
$($trk).animate({
width: width,
height: height,
}, { duration: animationsTid, queue: false });
/*
//Old way of resizing, but without animation
$([$img2, $img, $div, $trk]).each(function(index, element){
element.width(width).height(height);
});
*/
}
Call to the function will animate the resize.
Feel free to delete the code between /* */ - I just kept it as an reference
Happy Coding :)

Categories

Resources