Resizing image while printing html - javascript

I want to print a div of a html page which has texts and images. To do that I used a javascript function with window.print(). Upto now it prints that div with large images.
I need to resize the images keeping proportion.
As I am not from this (html,css,javascript) field, I have no idea how to do.
I searched on internet but didn't get any link with help in resizing image while printing.
Can you give any sort of idea?

You can control the layout of the print document by using mediaqueries. An example would be
#media print {
img {
max-width : 300px;
height : auto;
}
}
more information about this and some examples can be found here

You want to do something like this:
var images = document.getElementsByTagName('img')
for(var i = 0; i<images.length; i++) {
if (images[i].width > screen.width) {
// Reduce the width so image fits.
var factor = (screen.width-50)/img.width;
images[i].width *= factor;
images[i].height *= factor;
}
if (images[i].height > screen.height) {
// Reduce the height so it fits.
var factor = (screen.height-50)/images[i].height;
images[i].width *= factor;
images[i].height *= factor;
}
}
Does this help?

you can just set the image's width() and height() like below:
$('.imgClass').width(700); // Units are assumed to be pixels
$('.imgClass').height(700);
//.imgClass is a common class on multiple images
Hope this will helps you.

Or you can just use inline css for defining the dimensions of the image
<img style="width:150px;float: right" src="image_path.png">

Related

JS/jQuery fit all images inside div (without whitespace)

I have a div call it #container,
Inside this #container I have n amount of img tags call it images
n can be 2, 10, 40 and so on.
I am wondering how I can fit n amount of images inside a #container to close all white spaces stretch the images. Quality doesn't matter
This is what I tried until now:
var amount = $("#container > img").length;
var amount_w = amount*200; //200 width of 1 image
var amount_h = amount*130; //120 height image
var refH = $("#container").height();
var refW = $("#container").width();
var refRatio = refW/refH;
$("#container img").each(function(){
$(this).height((amount_h-130)-refH);
$(this).width((amount_w-230)-refW);
});
First of all, it IS possible to achieve what you need even while maintaining the aspect ratio of the images - however the row height will be calculated, but it is not a trivial task (well, at least not as trivial as a single line formula).
There is a jQuery plugin called jPictura which I have developed. I believe the plugin does exactly what you need.
Here is a working fiddle.
You can find the plugin source codes and documentation on GitHub.
Simple example how to use the plugin:
$(document).ready(function () {
$('#my-gallery').jpictura({
layout: { itemSpacing: 0, justifyLastRow: true, idealRowHeight: 200}
});
});
itemSpacing - amount of space between the images in pixels
justifyLastRow - if true, the images in last row will be stretched to take the full width of the row
idealRowHeight - The desired height of the rows in pixels. The plugin will do its best to arrange the items so the row heights are as close as possible to this value.
there are a lot more options documented on GitHub
Beside the JS stuff that calculates the correct widths and heights of the images, there is one more thing to be considered regarding the blank space between images. Images are by default inline-blocks which means they behave like words and words do have some white space inbetween, right? Make them display: block; float: left; or use the flex box layout to get rid of the blank space. The plugin uses float: left; by default.
I created something that might interest you
var container = $('#container');
var height = container.outerHeight();
var width = container.outerWidth();
function populate(n){
var rem_items = n;
var rows = Math.round(Math.sqrt(n));
var row_items = Math.ceil(n/rows);
for (var i=0; i<rows; i++){
// this prevents us from generating a lonely single box in a row
if( (rem_items%(rows-i))===0 ){
row_items = rem_items/(rows-i);
}
if(rem_items<row_items){
row_items = rem_items;
}
rem_items = rem_items-row_items;
for (var j=0; j<row_items; j++){
var img_height = height/rows;
var img_width = width/row_items;
var img_left = j*img_width;
var img_top = i*img_height;
var img = $('<div class="cell"></div>');
img.css({
width: img_width,
height: img_height,
left: img_left,
top: img_top
});
container.append(img);
}
}
}
populate(40);
https://jsfiddle.net/jLq4hgaa/1/
Basically, it calculates the "most balanced" distribution of the images horizontally and vertically.
It does what you're asking for in the plainest sense. It distributes images/containers inside a container evenly regardless of aspect ratio.
$(document).on("pageload",function(){
$('.container').addClass('stretch');
});
Then make a css element called "stretch" defining width:100%
Height:100% and if need be define layout, i.e relative

'Media-queries' for javascript - different code for different viewport height/widths

The problem
I'm using javascript to calculate widths of elements to achieve the layout I'm after. The problem is, I don't want to load the code on smaller screen sizes (when the screen width is less than 480px for example). I'd like this to work on load and on browser/viewport resize.
I'd consider small screen devices 'the default' and working up from there. So, none of the following script is called by default, then if the browser width is greater than 480px (for example), the following script would be called:
The code
$(document).ready(function() {
//Get the figures width
var figure_width = $(".project-index figure").css("width").replace("px", "");
//Get num figures
var num_figures = $(".project-index figure").length;
//Work out how manay figures per row
var num_row_figures = Math.ceil(num_figures / 2);
//Get the total width
var row_width = figure_width * num_row_figures;
//Set container width to half the total
$(".project-index").width(row_width);
x = null;
y = null;
$(".project-index div").mousedown(function(e) {
x = e.clientX;
y = e.clientY;
});
$(".project-index div").mouseup(function(e) {
if (x == e.clientX && y == e.clientY) {
//alert($(this).next().attr("href"));
window.location.assign($(this).next().attr("href"));
}
x = y = null;
});
});
// Drag-on content
jQuery(document).ready(function() {
jQuery('#main').dragOn();
});
The extra bit
The slight difference on larger screens is to do with the browser/viewport height. This is in regards to the line:
var num_row_figures = Math.ceil(num_figures / 2);
You can see once the calculation has a value, it divides it by 2. I only want this to happen when the browser/viewport height is above a certain amount - say 600px.
I'd be happy with this being the 1st state and then the value is divided by 2 if the height is greater than 600px if it's easier.
Can anyone help me/shed some light on how to manage my script this way. I know there's media queries for managing CSS but I can't seem to find any resources for how to manage javascript this way - hope someone can help.
Cheers,
Steve
You can use window.matchMedia, which is the javascript equivalent of media queries. The matchMedia call creates a mediaQueryList object. We can query the mediaQueryList object matches property to get the state, and attach an event handler using mediaQueryList.addListener to track changes.
I've added an example on fiddle of using matchMedia on load and on resize. Change the bottom left pane height and width (using the borders), and see the states of the two queries.
This is the code I've used:
<div>Min width 400: <span id="minWidth400"></span></div>
<div>Min height 600: <span id="minHeight600"></span></div>
var matchMinWidth400 = window.matchMedia("(min-width: 400px)"); // create a MediaQueryList
var matchMinHeight600 = window.matchMedia("(min-height: 600px)"); // create a MediaQueryList
var minWidth400Status = document.getElementById('minWidth400');
var minHeight600Status = document.getElementById('minHeight600');
function updateMinWidth400(state) {
minWidth400Status.innerText = state;
}
function updateMinHeight600(state) {
minHeight600Status.innerText = state;
}
updateMinWidth400(matchMinWidth400.matches); // check match on load
updateMinHeight600(matchMinHeight600.matches); // check match on load
matchMinWidth400.addListener(function(MediaQueryListEvent) { // check match on resize
updateMinWidth400(MediaQueryListEvent.matches);
});
matchMinHeight600.addListener(function(MediaQueryListEvent) { // check match on resize
updateMinHeight600(MediaQueryListEvent.matches);
});
#media screen and (max-width: 300px) {
body {
background-color: lightblue;
}
}
So i searched a bit and came up with this example from w3 schools .http://www.w3schools.com/cssref/tryit.asp?filename=trycss3_media_example1
i think this is something you are trying to achieve.
For pure js , you can get the screen width by screen.width

Changing Div Width via Javascript

I'm making a website for my art gallery. Part of what I need to do is display images to the viewers in a way in which they can view them. And I want to do this without reducing the quality of the images, or having to save all of my images in many different sizes to cater to every user.
So, I've made a Javascript function to resize my images to fit completely on the viewer's screen. My code looks like
<img src="[image.png]" onload="setGoodHeight(this);">
where the function setGoodHeight(element) is defined as:
function setGoodHeight (element) {
if(window.innerHeight-50 < element.height) {
var h = element.height;
var w = element.width;
element.height = window.innerHeight - 50;
element.width = w * element.height / h;
}
if (window.innerWidth-100 < element.width) {
var h = element.height;
var w = element.width;
element.width = window.innerWidth - 100;
element.height = h * element.width / w;
}
}
In shorthand, this first checks whether the image is higher than the screen it's trying to be displayed on, and if it is (it usually is) the image is resized to fit comfortably on the screen. Then it checks if, after this, the image is wider than the screen, and if so it shrinks it further. I have verified that this code works.
However, the image is contained within a class called .post I want the post area to wrap to that of the image, at least in width, and so at the end of my javascript function, I added this code:
element.parentNode.width = element.width + 40;
But the post doesn't resize itself. For reference, the code on the actual webpage concerning this can be boiled down to
<div class="post">
<img src="[image.jpg]" onload="setGoodHeight(this);">
</div>
and if you need to look around it a little more it can be found at this link.
How about a pure CSS solution, it will also update magically if the user resizes their browser.
html, body, #fullscreen {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#fullscreen {
background: url('http://www.nathanrouse.org/wp-content/uploads/2014/01/CrashTestDummy.jpg') center center no-repeat;
background-size: cover;
}
<div id="fullscreen"></div>
Check the doc for background-size. There are other values like "contain" that might suit you better.
I think you're looking for
item.naturalHeight
item.naturalWidth
I was using these in a function to set the max-height & max-width
function imageLoad(item) {
$(item).attr("max-height", item.naturalHeight);
$(item).attr("max-width", item.naturalWidth);
}

how to center and make various images sizes fit in a container

I'm using bxslider to have a carousel of images. The thing is though, the images it receives to display are of somewhat unpredictable sizes. The container size is 243x243. And we know that no image will have a side smaller than 243. So...I'd like to center the image in the container. And either zoom in until the shorter of the two dimensions (L vs W) fills the container at 243, and the longer dimension overflow is hidden.
For the images I'm working with, doing this will be perfect for getting the important details of the picture in the frame.
But I'm having trouble...
I've tried the following to center the picture in the frame:
jQuery(".bx-container").each(function() {
var img_w = jQuery(this).children("img").width();
var img_h = jQuery(this).children("img").height();
var pos_top = (img_h - containerHeight) / 2;
var pos_left = (img_w - containerWidth) / 2;
var pos_top = (243 - img_h) / 2;
var pos_left = (243 - img_w) / 2;
jQuery(this).children("img").css({
'top' : pos_top + 'px',
'left' : pos_left + 'px'
});
});
And I've tried this to position not square images into the frame:
jQuery(".bx-container").each(function(){
var refRatio = 1;
var imgH = jQuery(this).children("img").height();
var imgW = jQuery(this).children("img").width();
if ( (imgW/imgH) < refRatio ) {
jQuery(this).addClass("bx-portrait");
} else {
jQuery(this).addClass("bx-landscape");
}
});
});
I've messed with both scripts and the css but I just can't seem to get it work. It either centers but doesn't resize right. Or resizes but centers wrong. Or does both wrong.
Here's the jsfiddle: http://jsfiddle.net/vgJ9X/298/
Could someone help me out?
Thanks!
EDIT:
New jsfiddle...the portrait ones work right. The landscape images still squish. :(
http://jsfiddle.net/vgJ9X/307/
EDIT:
I THINK it has something to do with relatively positioned elements not being allowed to overlap. Trying to find a fix. If anyone knows, edit the last fiddle I posted.
jQuery(".bx-container img").each(function () {
var w = jQuery(this).width();
var h = jQuery(this).height();
if (w > h) $(this).addClass('bx-landscape');
else $(this).addClass('bx-portrait');
});
Check this Updated JSFiddle
Update
jQuery(".bx-container img").each(function () {
var w = jQuery(this).width();
var h = jQuery(this).height();
if (w > h){
$(this).addClass('bx-landscape');
var trans= -243/2;
$(this).css('-webkit-transform','translateZ('+trans+'px)');
}
else if(h > w){
$(this).addClass('bx-portrait');
var trans= -243/2;
$(this).css('-webkit-transform','translateY('+trans+'px)');
}
});
check this JSFiddle
Update of Update
Found the issue with landscape, the plugin is setting max-width:100%; overriding it with max-width:none; fixes the issue...
Update Of Updated Fiddle
Try this:
img{
position:relative;
height:100%;
width:300px;
}
Simple an clean.
Demo: http://jsfiddle.net/vgJ9X/302/
I did a couple things to your jsfiddle.
First I changed the order of your resize and center functions, so the resize comes first. This way, the smaller images get resized, then centered. I also uncommented the first portion of your code.
You also had a couple of errors in your css. There was an extra closing bracket after img style declaration. Your .bx-portrait img and .bx-landscape img declarations were set to 100%px;.
Update:
Change the css in your two .bx classes to:
.bx-portrait img {
height: 100%;
width: auto;
}
.bx-landscape img {
height: auto;
width: 100%;
}
And add a clearfix to your ul:
.bxslider:after {
content: '';
clear: both;
display: table;
padding: 0;
margin: 0;
}
The height is clipping because .bx-viewport has a set height of 243px but also has a 5px border, which makes the actual internal height 233px. You'll need to make the height 253px to account for the 10px of border. This is why they don't look centered vertically.
DEMO
Why don't you just use background images instead and center them. Here is a demo from your original code
http://jsfiddle.net/8y8df/
If you want to show the full size image, just remove the background-size:contain; from the css.

Animation starts moving out of position after some time

I am trying to create a sort of slideshow animation. I have the codes here: jsFiddle.
These tablets would rotate around.
The problem is that, at random times, the animation will move out of line. The wrong tablets undergo wrong animations. Here are the screenshots:
And this is how it looks like when the animations goes wrong
The main problem is I don't understand why the animation would go wrong random times. In my computer it will run properly for hours, but in other cases (especially on Safari).
You could store the expected final css values for each animated el and then in the animate callback set these values, so for each animated el something like
var el = $(selector);
el.data("finalCSS", { your expected final CSS values })
$("selector").animate({animation properties}, function() {
el.css(el.data("finalCSS")).data("finalCSS", undefined);
})
This doesn't help with figuring out why it's happening (but I can't recreate the issue myself), but provides a failsafe to make sure the layout doesn't break;
I believe this happens when you try to animate before the previous animation has ended. Use jQuery stop() just before you animate. For example:
$('#animatingDiv').stop(false, true).animate({height:300}, 200, callback);
The first param(false) will empty the animation queue on that element and the second param(true) will jumps to the end of current animation before starting a new animation.
You can do this with far less code and far fewer headaches.
1. Store your tablet position attributes in classes
.tablet1{
height:100px;
width:140px;
margin-left:-540px;
top: 200px;
z-index:10;
}
2. Use a general function to handle all your transitions.
JQuery UI will do all the work for you if you use switchClass
switchTabletsRight = function(){
var i, next, max = 5;
for(i = 1; i <= max; i++){
next = (i < max)? i + 1 : 1;
$(".tablet" + i).switchClass("tablet" + i, "tablet" + next);
}
};​
Here's the JSfiddle proof of concept: http://jsfiddle.net/nRHag/4/
You are setting CSS positions to decimal values.
img_w = $("#tablet"+num+" img").width();
img_w = img_w *140 / 600;
img_h = $("#tablet"+num+" img").height();
img_h = img_h *140 /600;
...
var new_width = $(this).width() * 140 / 600;
$(this).css('width', new_width);
var new_height = $(this).height() * 140 / 600;
$(this).css('height', new_height);
Your division could be cause decimal results which have different effects in different browsers. Sub pixel CSS positioning may be creating your unintended errors.

Categories