I want to split multiple images into tiles(it must be div or similar). (With Javascript or jQuery.)
and Images should be one below the other.
Its my div;
<div class="reading-content">
<div class="page-break no-gaps">
<img id="image-0" src="image.jpg" class="some-class">
</div>
<div class="page-break no-gaps">
<img id="image-1" src="image1.jpg" class="some-class">
</div>
</div>
example jsfiddle; http://jsfiddle.net/0Lxr2tad/
var t = Date.now();
var img = new Image();
var length = 30;
var ylength = 20;
img.onload = function() {
var width = this.width,
height = this.height,
_length = -length,
i, j;
// create a <div/> with all basic characteristics, to be cloned over and over in the loops below.
var $basicDiv = jQuery('<div/>', {
class: 'splitImg',
css: {
'width': Math.floor(width/length),
'height': Math.floor(height/ylength),
'background-image': 'url(' + img.src + ')'
}
});
// Finding a node in the DOM is slow. Do it once and assign the returned jQuery collection.
// Also, #wrapper's width can be set here.
var $wrapper = $('#wrapper').width(width + length * 2);
for (i = 0; i > _length; i--) {
for (j = 0; j > _length; j--) {
$basicDiv.clone().css({'background-position': `${width/length * j}px ${height/ylength * i}px`}).appendTo($wrapper);
}
}
console.log(Date.now() - t);
}
img.src = 'http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg'; // how to do multiple this??
Anyone can help?
I don't use jquery much so I can suggest javascript option like this:
const targetElement = document.querySelector(...) // I choose the div that we are going to append newdivs
I don't know if it exists but I assume there is an array of content you use for src urls or any other data.
let arrayOfInfo = [{},{}] // this is a hypothetical array of objects that we will use
arrayOfInfo.forEach(obj => {
let newDiv = document.createElement("div");
newDiv.classList.add("page-break","no-gaps")
newDiv.innerHTML=`<img id="image-${obj.index}" src=${obj.url} class="some-class">`
targetElement.append(newDiv);
})
so with that approach you automate everything. If you need to reuse, you can make it into a function and run it wherever you need. It is also handy if you need to change some content later on, so you only change the array values and rest goes auto again.
I hope this was what you need.
I tried to do it again after a long time and I was able to do it yesterday, anyone can use it. ( You can remove .splitImg { some style } class for remove spaces. )
JSFiddle Example
let i = 0;
let seenUrls = new Set()
setInterval(() => {
let url = document.querySelectorAll('#someid p img')[i].src;
let image = document.querySelectorAll('#someid p')[i]
let gor = document.querySelectorAll('#someid p')
if (!seenUrls.has(url)) {
seenUrls.add(url)
var t = Date.now();
var img = new Image();
var length = 5;
var ylength = 5;
img.onload = function() {
var width = this.width,
height = this.height,
_length = -length,
i, j;
// create a <div/> with all basic characteristics, to be cloned over and over in the loops below.
var $basicDiv = jQuery('<div/>', {
class: 'splitImg',
css: {
'width': Math.floor(width/length),
'height': Math.floor(height/ylength),
'background-image': 'url(' + img.src + ')'
}
});
// Finding a node in the DOM is slow. Do it once and assign the returned jQuery collection.
// Also, #wrapper's width can be set here.
var $wrapper = image;
image.style.width = width + length * 2 + "px";
for (i = 0; i > _length; i--) {
for (j = 0; j > _length; j--) {
$basicDiv.clone().css({'background-position': `${width/length * j}px ${height/ylength * i}px`}).appendTo($wrapper);
}
}
console.log(Date.now() - t);
}
img.src = url
i = (i + 1) % gor.length;
}
}, 50)
#someid {
max-width: 100%;
}
#someid p {
display:flex;
flex-wrap:wrap;
margin: 0 auto;
}
#someid p img {
display: none!important;
}
.splitImg {
padding: 1px;
background-clip: content-box;
background-repeat: no-repeat;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="someid">
<p>
<img src="http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg" />
</p>
<p>
<img src="https://www.jqueryscript.net/images/Responsive-Touch-Friendly-jQuery-Gallery-Lightbox-Plugin-lightGallery.jpg" />
</p>
</div>
Related
i am getting frames from gif using Libgif.
and then i am appending those frames in the div with Id = frames.
then i am taking those frames and trying to add each frames one after the other in canvas to make a spritesheet.
in the end i am getting an image in canvas but instead of getting different frames i am getting same image in the spritesheet.
Please help me find the issue.
I had taken canvas width 10000 assuming a gif wont have frames more than 100.
c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
ctx.clearRect(0, 0, ctx.width, ctx.height);
ctx.beginPath();
var imageGiF = "";
var total = 0;
let canvasWidth = 0;
let canvasHeight = 0;
$('div.gifimage img').each(function(idx, img_tag) {
var total = 0;
if (/^.+\.gif$/.test($(img_tag).prop("src"))) {
var rub = new SuperGif({
gif: img_tag,
progressbar_height: 0
});
rub.load(function() {
for (let i = 0; i < rub.get_length(); i++) {
total += 1;
rub.move_to(i);
// var canvas = cloneCanvas(rub.get_canvas());
var canvas = rub.get_canvas().toDataURL("image/png");
img = $('<img id = "gifframe' + i + '"src= "' + canvas + '" class= frameimages>');
$("#frames").append(img);
}
var frameimages = document.getElementById("frames").querySelectorAll(".frameimages");
var totalimages = frameimages.length;
x = 0;
y = 0;
for (let i = 0; i < frameimages.length; i++) {
img = document.getElementById("gifframe" + i + "");
img.onload = function() {
ctx.drawImage(img, i * 100, 0, 100, 100);
total++;
console.log(total);
}
}
totalwidth = (total) * 100;
c.width = totalwidth;
c.height = 100;
setTimeout(() => {
imageGiF = c.toDataURL("image/png");
console.log(imageGiF);
// addBgimg(imageGiF)
}, 10);
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/buzzfeed/libgif-js/master/libgif.js"></script>
<div class="gifimage" id="placehere">
<img src="https://media1.giphy.com/media/bzUwzbxcvJ3XQlcnoi/giphy.gif" alt="">
</div>
<div id="frames" class="classGIF"></div>
<canvas id='myCanvas' width="10000" height="300"></canvas>
You were looping through the images, using img in your event handler.
However, this variable img in the outer scope was overridden by every loop, until it was finished looping through everything, then img was stuck on the last frame added.
Then when the event handler triggered, it added the last frame in every instance, because that was the value of img at that point. The loop was done before the images could load.
By adding it to it's own scope by wrapping it in a function, the variable is preserved.
I also modified your code to store the DOM img elements in an array, so you don't need expensive DOM lookups which makes your code a tad bit faster.
I added comments in the code to explain my changes.
c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
ctx.clearRect(0, 0, ctx.width, ctx.height);
ctx.beginPath();
var imageGiF = "";
var total = 0;
let canvasWidth = 0;
let canvasHeight = 0;
$('div.gifimage img').each(function(idx, img_tag) {
var total = 0;
if (/^.+\.gif$/.test($(img_tag).prop("src"))) {
var rub = new SuperGif({
gif: img_tag,
progressbar_height: 0
});
rub.load(function() {
// An array for the image references
let images = [];
// Keep the reference to save on expensive DOM lookups every iteration.
let frames = $("#frames");
for (let i = 0; i < rub.get_length(); i++) {
total += 1;
rub.move_to(i);
// var canvas = cloneCanvas(rub.get_canvas());
var canvas = rub.get_canvas().toDataURL("image/png");
img = $('<img id = "gifframe' + i + '"src= "' + canvas + '" class="frameimages">');
// Use the reference to append the image.
frames.append(img);
// Add image to images array with the current index as the array index.
// Use the jQuery get method to get the actual DOM element.
images[i] = img.get(0);
}
var frameimages = document.getElementById("frames").querySelectorAll(".frameimages");
var totalimages = frameimages.length;
x = 0;
y = 0;
// Loop through all the images in the image array
// Using a scope so the reference to img won't be overridden.
images.forEach((img, index) => {
img.onload = () => {
ctx.drawImage(img, index * 100, 0, 100, 100);
total++;
console.log(total);
}
})
totalwidth = (total) * 100;
c.width = totalwidth;
c.height = 100;
setTimeout(() => {
imageGiF = c.toDataURL("image/png");
console.log(imageGiF);
// addBgimg(imageGiF)
}, 10);
});
}
});
#frames { display:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/buzzfeed/libgif-js/master/libgif.js"></script>
<div class="gifimage" id="placehere">
<img src="https://media1.giphy.com/media/bzUwzbxcvJ3XQlcnoi/giphy.gif" alt="">
</div>
<div id="frames" class="classGIF"></div>
<canvas id='myCanvas' width="10000" height="300"></canvas>
I made this fully working image slider, and the only thing I want it to do now is resize its height to the current image's aspect ratio. I wrote a loop that calculates aspect ratio for every image in the slider, the only problem is that, when executed, the loop returns all the values at once, when I only need it to give me one after another value for adjustedHeight each click.
I tried putting i++ inside the loop, pushing all values into an array, which requires another loop to iterate between the array's values, but all of that just feels more complicated than it needs.
<div class="slider-images">
<img src="https://via.placeholder.com/1280x720.png">
<img src="https://via.placeholder.com/1280x720.png">
<img src="https://via.placeholder.com/1280x960.png">
<img src="https://via.placeholder.com/1280x720.png">
<img src="https://via.placeholder.com/1280x720.png">
<img src="https://via.placeholder.com/1280x720.png">
<img src="https://via.placeholder.com/1280x720.png">
</div>
JavaScript
const images = document.querySelector('.slider-images');
const image = document.querySelectorAll('.slider-images img');
var i;
function slideRight() {
//...
for (i = 0; i < image.length; i++) { // Calculates aspect ratio
const allImagesWidth = image[i].naturalWidth,
allImagesHeight = image[i].naturalHeight;
const aspectRatio = allImagesWidth / allImagesHeight;
adjustedHeight = Math.round(slideWidth / aspectRatio); // Final slider height required for a current shown image
}
images.style.height = adjustedHeight + 'px'; // Dynamically should add respective height calculated in the loop above
//...
}
document.querySelector('.slide-right').addEventListener('click', slideRight, false);
CSS
.slider-images {
display: flex;
transition: .5s all cubic-bezier(0.4, 0.0, 0.2, 1);
max-width: 200%;
max-height: 512px;
}
.slider-images img {
width: 50%;
z-index: -1;
}
Finally solved, works and resizes vertically as I wanted. Just needed to move the loop above the slideRight function, set new empty array variable imageArray, push everything from the loop to that array, and then set the style in the function to read from that array and change width based on already existed variable position = 0 used for the slider to work.
Also made adjustments in styles, removed max-height from .slider-images, and set .slider-images img to max-height: unset;, in case you have your img set to max-height: 100%; by default.
var position = 0;
var index = 0;
var imageArray = [];
//...
for (index; index < image.length; index++) {
const allImagesWidth = image[index].naturalWidth,
allImagesHeight = image[index].naturalHeight;
const aspectRatio = allImagesWidth / allImagesHeight;
var adjustedHeight = slideWidth / aspectRatio;
imageArray.push(adjustedHeight++);
}
images.style.height = imageArray[position] + 'px';
function slideRight() {
position--;
images.style.height = imageArray[position] + 'px';
if (position == -1) {
position = imageCount - 1;
}
images.style.transform = 'translateX(' + -(slideWidth * position) + 'px)';
}
// ...
document.querySelector('.slide-right').addEventListener('click', slideRight, false);
I need to modify a pasted image inside a contenteditable div: resize it proportionately, add borders, etc... Perhaps this can be achieved by adding a className that will alter the necessary CSS properties.
The problem is that I don't know how to reference the focused, i.e. the active, the clicked-upon image or any element for that matter.
This is the HTML that I am trying to use
<!DOCTYPE html>
<html>
<body>
<div contenteditable="true">This is a div. It is editable. Try to change this text.</div>
</body>
</html>
Using css, html and javascript
Your editable content should be inside a parent div with an id or class name, you can even have different divs for images and such.
Then it is as simple as having css like so:
#editableContentDiv img {
imgProperty: value;
}
Then you can have javascript like so:
function insertImage(){
var $img = document.querySelector("#editableContentDiv img");
$img.setAttribute('class','resize-drag');
}
Eventually if you have more than one img inside the same div you can use querySelectorAll instead of querySelector and then iterate through the img tags inside same div.
I beleive that should at least give you an idea of where to start with what you want.
Similar example
I found this gist that seems to have similar things to want you want but a bit more complicated.
function resizeMoveListener(event) {
var target = event.target,
x = (parseFloat(target.dataset.x) || 0),
y = (parseFloat(target.dataset.y) || 0);
// update the element's style
target.style.width = event.rect.width + 'px';
target.style.height = event.rect.height + 'px';
// translate when resizing from top or left edges
x += event.deltaRect.left;
y += event.deltaRect.top;
updateTranslate(target, x, y);
}
function dragMoveListener(event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.dataset.x) || 0) + event.dx,
y = (parseFloat(target.dataset.y) || 0) + event.dy;
updateTranslate(target, x, y);
}
function updateTranslate(target, x, y) {
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the position attributes
target.dataset.x = x;
target.dataset.y = y;
}
function insertImage() {
var $img = document.createElement('img');
$img.setAttribute('src', 'https://vignette.wikia.nocookie.net/googology/images/f/f3/Test.jpeg/revision/latest?cb=20180121032443');
$img.setAttribute('class', 'resize-drag');
document.querySelector(".container-wrap").appendChild($img);
var rect = document.querySelector(".container-wrap").getBoundingClientRect();
$img.style.left = rect.left;
$img.style.top = rect.top;
}
function dataTransfer() {
//cleanup
var $out = document.querySelector(".out-container-wrap");
while ($out.hasChildNodes()) {
$out.removeChild($out.lastChild);
}
//get source
var source = document.querySelector('.container-wrap')
//get data
var data = getSource(source);
//add data to target
setSource($out, data);
}
/**
* Get data from source div
*/
function getSource(source) {
var images = source.querySelectorAll('img');
var text = source.querySelector('div').textContent;
//build the js object and return it.
var data = {};
data.text = text;
data.image = [];
for (var i = 0; i < images.length; i++) {
var img = {}
img.url = images[i].src
img.x = images[i].dataset.x;
img.y = images[i].dataset.y;
img.h = images[i].height;
img.w = images[i].width;
data.image.push(img)
}
return data;
}
function setSource(target, data) {
//set the images.
for (var i = 0; i < data.image.length; i++) {
var d = data.image[i];
//build a new image
var $img = document.createElement('img');
$img.src = d.url;
$img.setAttribute('class', 'resize-drag');
$img.width = d.w;
$img.height = d.h;
$img.dataset.x = d.x;
$img.dataset.y = d.y;
var rect = target.getBoundingClientRect();
$img.style.left = parseInt(rect.left);
$img.style.top = parseInt(rect.top);
//transform: translate(82px, 52px)
$img.style.webkitTransform = $img.style.transform = 'translate(' + $img.dataset.x + 'px,' + $img.dataset.y + 'px)';
//$img.style.setProperty('-webkit-transform', 'translate('+$img.dataset.x+'px,'+$img.dataset.y+'px)');
target.appendChild($img);
}
//make a fresh div with text content
var $outContent = document.createElement('div')
$outContent.setAttribute('class', 'out-container-content');
$outContent.setAttribute('contenteditable', 'true');
$outContent.textContent = data.text;
target.appendChild($outContent);
}
interact('.resize-drag')
.draggable({
onmove: dragMoveListener,
inertia: true,
restrict: {
restriction: "parent",
endOnly: true,
elementRect: {
top: 0,
left: 0,
bottom: 1,
right: 1
}
}
})
.resizable({
edges: {
left: true,
right: true,
bottom: true,
top: true
},
onmove: resizeMoveListener
})
.resize-drag {
z-index: 200;
position: absolute;
border: 2px dashed #ccc;
}
.out-container-content,
.container-content {
background-color: #fafcaa;
height: 340px;
}
#btnInsertImage {
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="http://code.interactjs.io/interact-1.2.4.min.js"></script>
</head>
<body>
<button id="btnInsertImage" onclick="insertImage()">Insert Image</button>
<div class="container-wrap">
<div class="container-content" contenteditable="true">This is the content of the container. The content is provided along with the image. The image will be moved around and resized as required. The image can move within the boundary of the container.</div>
</div>
<button id="btnSubmit" onclick="dataTransfer()">Submit</button>
<div class="out-container-wrap">
</div>
</body>
</html>
Source
This is what I tried and it seems to be working - at least on my system, the snippet I made does not work unfortunately.
function getSelImg(){
var curObj;
window.document.execCommand('CreateLink',false, 'http://imageselectionhack/');
allLinks = window.document.getElementsByTagName('A');
for(i = 0; i < allLinks.length; i++)
{
if (allLinks[i].href == 'http://imageselectionhack/')
{
curObj = allLinks[i].firstChild;
window.document.execCommand('Undo'); // undo link
break;
}
}
if ((curObj) && (curObj.tagName=='IMG'))
{
//do what you want to...
curObj.style.border = "thick solid #0000FF";
}
}
<!DOCTYPE html>
<html>
<body>
<input type="button" onclick="getSelImg()" value="set img border">
<div contenteditable="true">This is a div.<br>
It is editable.<br>
Try to paste an image here:<br>
###########################<br>
<br>
<br>
<br>
###########################
</div>
</body>
</html>
I've tried all sorts of things to figure out why my code isn't however, I can't seem to find out why. `
var numberOfFaces = 5;
var theleftside = document.getElementById ("leftSide");
var top_position = Math.floor((Math.random() * 400) + 1);
var left_position = Math.floor((Math.random() * 400) + 1);
var theRightSide = document.getElementById("rightSide");
function generatefaces () {
for (var i = 1; i < numberOfFaces; i++) {
var img = document.createElement("img");
img.src = "smile.png";
img.style.top = top_position + "px";
img.style.left = left_position + "px";
theleftside.appendChild(img);
}
}
<style media="screen">
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 2px solid black;
}
</style>
<h1>The Matching Game</h1>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide">
</div>
<div id="rightSide">
</div>
`
I am trying to generate 5 images (smiley faces) on the lefside div at different positions, then trying to clone it to the right hand side,
I'm new with JS, so hints and tips would be much appreciated.
Because you just implemented a function but did not call it. Try adding
generatefaces();
at the end.
Two fold firstly you need to, as burkay says, call the function generatefaces().
Secondly you need to create a second element for the right side using img.cloneNode(true) this creates a duplicate so you can then append that to the right side.
Also you are generating the random position outside of the loop so the same random position is used for each img you instead need to create a random position for every img by moving it inside the loop.
Example:
var numberOfFaces = 5;
var theleftside = document.getElementById("leftSide");
var theRightSide = document.getElementById("rightSide");
// You need to call this function
generatefaces()
function generatefaces() {
for (var i = 1; i < numberOfFaces; i++) {
// Generate the new random position for each img
var top_position = Math.floor((Math.random() * 400) + 1);
var left_position = Math.floor((Math.random() * 400) + 1);
var img = document.createElement("img");
// The location of your face image
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/Emojione_1F60E.svg/64px-Emojione_1F60E.svg.png";
img.style.top = top_position + "px";
img.style.left = left_position + "px";
// Creates a duplicate version of the image
var imgright = img.cloneNode(true);
theleftside.appendChild(img);
// Appends the duplicate image to the right side
theRightSide.appendChild(imgright);
}
}
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 2px solid black;
}
<h1>The Matching Game</h1>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide">
</div>
<div id="rightSide">
</div>
Hope this helps!
i found a script that would position divs / images randomly. However, it isn't completely working the way i want/need it to.
The images are loaded each within a div (which isn't ideal i guess). I have around 30 images.
But they don't load nicely and var posy = (Math.random() * ($(document).height() - 0)).toFixed(); doesn't work nicely either. The images mostly load on top (i think that the images in the blog don't count so it gets the height without images?)
So what I want: Load the in more nicely Randomize them so they get to the bottom of the page, too
var circlePosition = document.getElementsByClassName('circle');
console.log(circlePosition);
function position() {
for (var i = 0; i < circlePosition.length; i++ ) {
//give circle a random position
var posx = (Math.random() * ($(document).width() - 0)).toFixed();
var posy = (Math.random() * ($(document).height() - 0)).toFixed();
//apply position to circle
$(circlePosition[i]).css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
})
}
} //end function position
var circleTotal = circlePosition.length;
$('.circle').click(function() {
$(this).fadeOut();
circleTotal = circleTotal - 1;
console.log(circleTotal);
if(circleTotal == 0) {
position()
$('.circle').fadeIn();
}
});
position();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="//placehold.it/1x5000"> <!-- Placeholder image to show issue -->
<div class="circle">
<img src="http://static.tumblr.com/tensqk8/k8anq0438/01.png">
</div>
<div class="circle">
<img src="http://static.tumblr.com/tensqk8/k8anq0438/01.png">
</div>
A clean and readable and solution without a jQuery dependence might be something like this. It avoids unnecessarily wrapping your images in divs by positioning the images themselves. It includes a hidden element as a sort of "poor man's" shadow DOM.
http://jsfiddle.net/sean9999/yv9otwr7/9/
;(function(window,document,undefined){
"use strict";
var init = function(){
var canvas = document.querySelector('#x');
var icon_template = document.querySelector('#template');
var icon_width = 40;
var icon_height = 30;
var the_images = [
'http://static.tumblr.com/tensqk8/k8anq0438/01.png',
'http://static.tumblr.com/tensqk8/rYanq05el/04.png',
'http://static.tumblr.com/tensqk8/SYknq05py/05.png',
'http://static.tumblr.com/tensqk8/s7inq057d/03.png'
];
var pickRandomImage = function(){
var i = Math.floor( Math.random() * the_images.length );
return the_images[i];
};
var total_number_of_images = 10;
var max_height = canvas.offsetHeight - icon_height;
var max_width = canvas.offsetWidth - icon_width;
var randomCoordinate = function(){
var r = [];
var x = Math.floor( Math.random() * max_width );
var y = Math.floor( Math.random() * max_height );
r = [x,y];
return r;
};
var createImage = function(){
var node = icon_template.cloneNode(true);
var xy = randomCoordinate();
node.removeAttribute('id');
node.removeAttribute('hidden');
node.style.top = xy[1] + 'px';
node.style.left = xy[0] + 'px';
node.setAttribute('src',pickRandomImage());
canvas.appendChild(node);
};
for (var i=0;i<total_number_of_images;i++){
createImage();
};
};
window.addEventListener('load',init);
})(window,document);
body {
background-color: #fed;
}
#x {
border: 3px solid gray;
background-color: white;
height: 400px;
position: relative;
}
#x .icon {
position: absolute;
z-index: 2;
}
<h1>Randomly distributed images</h1>
<div id="x"></div>
<img src="#" class="icon" hidden="hidden" id="template" />
try moving your position(); call inside the $(window).load function.
I think maybe the images are being positioned before all the images have loaded, so the page is shorter then.