Preloaded images flash at different rates - javascript

I'm calling images from a folder at random and putting them in HTML img tags using PHPs glob function.
I'm then using JS to read the URLs and flip the CSS background image of div#wrapper, 300ms for each image. The images should be preloaded as they have HTML img tags. They are being hidden from the user using the following CSS (which should not stop preloading as "display: none" does):
.visuallyhidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px; width: 1px;
margin: -1px; padding: 0; border: 0;
}
Nonetheless I'm experiencing the images flashing inconsistently / at different rates. It seems that larger file size images cause this to happen, but the images should be preloaded so I'm not sure why this is occurring.
My JS looks like this:
var slides = [];
$('.slide').each(function(index){
slides.push($(this).attr('id'));
});
var slide = 0;
function changeImage(){
if (slide < 10){
var currentSlide = $("#" + slides[slide]);
$('#wrapper').css('background-image', '');
$('#wrapper').css('background-image', 'url("' + currentSlide.attr('src') + '")');
slide++
} else {
$('#headline').removeClass('visuallyhidden');
$('#wrapper').css('background-image', '');
$('#wrapper').css('background-color', '#ef3308');
}
}
setInterval(changeImage, 300);
The site is http://robertirish.com.
Is there a better way to do this / can anyone explain why it's happening?

I'm going to guess it's a loading issue: either that CSS is interfering with preload or else it's being treated differently because you're loading it into the background of another element rather than using the img that you preloaded. Instead, I would load all the images inside the div, absolute-positioned on top of each other, and then just remove them one by one:
CSS:
#wrapper{
position: relative;
}
#wrapper img{
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
HTML:
<div id="wrapper">
<img src="image1.png">
<img src="image2.png">
<!--etc-->
</div>
JS:
$(document).on('ready', function(){
var images = [];
$("img", "#wrapper").each(function(){
images.push(this);
});
var timer = setInterval(function(){
if (images.length)
$(images.pop()).remove();
else
clearInterval(timer);
}, 300);
});

Related

Increment variable as .offsetTop() increments

So I am writing a custom parallaxing thing for a website I am working on.
It's very simple:
$('.bl-content').scroll(function(){
$('.prlx-image img').each(function(){
if($(this).parents('div.prlx-image').offset().top < $('.page-type--sfs .bl-content').height()){
$(this).css('bottom', $('.page-type--sfs .bl-content').scrollTop() * -.3);
}
});
});
It basically checks to see if the image is on the page and only then starts pulling the image up slightly faster slower than the page scrolls. The problem here is that the value the image is being pulled by is the same for each image. So it works fine for any images already on the page when it loads but anything further down has already "parallaxed" out of its container by the time it gets into view.
The images are just absolutely positioned within a container div.
I need to start scrollTop from zero when the image gets scrolled into view...
UPDATE:
I have been playing around with this and think I am on to something:
var offset = []
$('.prlx-image').each(function(i){
offset[i] = $(this).offset().top;
});
$('.bl-content').scroll(function(){
$('.prlx-image img').each(function(i){
if($(this).parents('div.prlx-image').offset().top < $('.page-type--sfs .bl-content').outerHeight()){
$(this).css('bottom', ($('.page-type--sfs .bl-content').scrollTop() * -.3) - offset[i]);
}
});
});
So now if I subtract the value of i from the value of scrollTop() theoretically that should work....but for some reason it is not working :(
If it helps the html each image is contained in looks like this:
<div class="prlx-image">
<img src="/assets/uploads/menncars.jpg" class="img-responsive">
</div>
And the CSS:
prlx-image{
height: 350px;
margin: 30px 0;
overflow: hidden;
position: relative;
}
.prlx-image img{
position: absolute;
left: 0;
right: 0;
bottom: 0;
width: 100%;
}

Change image opacity when using GetElementById

Part of my Uni module requires me to make a webstory that uses random elements to mix up the story. I'm using GetElementById in JS to embed one random image from an array into a div, which works perfectly fine. The image becomes the background of the div, and I then have text on top of the image - again this all works perfectly fine.
However the issue is that I want the image to be slightly transparent so that the text is easier to read, however no matter what solution I try, I can't get it to work.
I've tried making the div transparent in both CSS and JS, however then the whole div including the text is effected which defeats the point. Then when I try the RGBA style in CSS, the image isn't effected.
So what I need is the image that is loaded into the div through JS to be slightly transparent, whilst the text that is also in the div in the HTML doument to remain untouched.
This is the JS I'm using to randomly select an image:
function randomGun() {
var imgCount = 3;
var dir = 'img/';
var randomCount = Math.round(Math.random() * (imgCount - 1)) + 1;
var images = new Array
images[1] = "gun1.jpg",
images[2] = "gun2.jpg",
images[3] = "gun3.jpg",
document.getElementById("left").style.backgroundImage = "url(" + dir + images[randomCount] + ")";
}
<div id="container">
<div id="left">
<a id="message">Drive a bit closer to see if anybody is there.</a>
</div>
<script>
window.onload = randomGun()
</script>
</div>
Use a nested div with semi-transparent white background.
<div id="container">
<div id="left">
<div id="nested" style="width:100%;height:100%; background-color: rgba(255,255,255,0.5)">
<a id="message">Drive a bit closer to see if anybody is there.</a>
</div>
</div>
<script>window.onload = randomGun()</script>
</div>
In addition, I would set everything relative to style in a stylesheet, or at least inside a <style></style>.
UPDATE
Added your JS and fixed it a little. Note the adjustment to the random expression.
Perhaps this'll help you.
Use an element that'll contain 2 other elements, give the container position:relative and z-index:-2
Then the 2 elements inside should have position:absolute.
Next give the top element z-index:-1, background:url(http://image-host.com/path/to/img.jpg), and opacity:.5
Then the second element should have text and whatever else you want visible. Give this element z-index:1.
The reason why opacity wasn't working the way you expected to work is because opacity applies to everything within the element as well. Here in the Snippet, we layered an element with content and an element with a background image separately.
REFERENCE: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index
SNIPPET
function randomBG() {
var imgCount = 3;
var path = 'http://imgh.us/';
var randomCount = Math.round(Math.random() * (imgCount));
var images = ['solar_system.jpg', 'kowloon.jpg', 'transparent-map.png'];
document.getElementById("fader").style.backgroundImage = "url(" + path + images[randomCount] + ")";
}
window.onload = randomBG;
html,
body {
height: 100%;
width: 100%;
font: 400 16px/1.5 Verdana;
box-sizing: border-box;
}
* {
margin: 0;
padding: 0;
border: 0;
}
#base {
position: relative;
z-index: -2;
width: 100vw;
height: 100vh;
}
#content {
position: absolute;
z-index: 1;
padding: 20px;
margin: 0 auto;
width: 75%;
height: auto;
top: 0;
left: 0;
background: none;
}
#fader {
position: absolute;
z-index: -1;
padding: 20px;
margin: 0 auto;
min-width: 75%;
min-height: 75%;
/*background: url(http://imgh.us/Lenna.png);*/
opacity: .5;
}
<main id='base'>
<section id='fader'></section>
<article id='content'>
<h1>This is the Text</h1>
</article>
</main>

js backgroundImage() fade in on load?

I'm using javascript to display my background image because I'd like to have a random background image on each reload. Anyway, because of this my typical CSS transitions and animations won't do, because instead of fading the background it fades the text inside of my body.
Is there any way around this so that on each reload the background fades in?
This is the code I am using to display the random image:
var randomImage = Math.floor(Math.random() * 18) + 1;
document.body.style.backgroundImage = "url(images/" + randomImage + ".jpg)";
and I'm unsure how to make it fade in... any thoughts?
Using: https://css-tricks.com/snippets/css/transparent-background-images/
http://jsfiddle.net/wby2xf6f/1/
div {
width: 200px;
height: 200px;
display: block;
position: relative;
}
div:after {
transition: opacity 5s;
content: "";
background: url(http://www.wina.ugent.be/style/img/h1.png);
opacity: 0;
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
z-index: -1;
}
div.fadein:after {
opacity:1;
}
And then add the class .fadein with Javascript/JQuery.
http://jsfiddle.net/wby2xf6f/1/
On a sidenote: it might be better to select the background-image at random on the server side (using php/ruby/whatever).
Updated, but less semantic version: http://jsfiddle.net/wby2xf6f/5/
.fill {
position:absolute;
height:100%;
width:100%;
z-index:-1;
display:none;
background:url(http://www.wina.ugent.be/style/img/h1.png);
}
$('.fill').fadeIn(5000)
This example with your code above
$(document).ready(function(){
var img1 = "http://www.clarkcraft.co.uk/images/des/48040.jpg";
var img2 = "http://glamorouslymommy.com/wp-content/uploads/2013/05/small-background1.jpg";
setInterval(function(){
var randomImage = Math.floor(Math.random() * 18) + 1;
if(randomImage<=5){
$("div").css("background","url("+img2+")").show().fadeOut("slow"); $("div").css("background","url("+img1+")").show().fadeIn("slow");
}
else{
$("div").css("background","url("+img1+")").show().fadeOut("slow"); $("div").css("background","url("+img2+")").show().fadeIn("slow");
}
}, 1000);
});
div {
width:200px;
height:200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="display:none"></div>

how to i get the image to center in my gallery

I have made a simple slider gallery for my site but have found that when I click next the image updates but it does not centre until I have done a full cycle of the images
how can i get the images to align from the start?
HERE IS THE JS FIDDLE > http://jsfiddle.net/8pScd/4
HTML
<div class="view_gallery">view gallery</div>
<div class="prev control"><<</div>
<div class="next control">>></div>
<div class="gallery">
</div>
<div class="overlay"></div>
CSS
.overlay{
display: none;
position: absolute; top: 0; right: 0; bottom: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.8);
z-index: 100;
}
.gallery{
z-index: 200;
padding: 10px;
position: absolute;
left: 50%;
background: #fff;
}
.control{
position: absolute;
top: 200px;
z-index: 300;
color: #fff;
text-transform: capitalize;
font-size: 2em;
cursor: pointer;
}
.prev{left: 0;}
.next{right:0;}
JQUERY
//images
var pics = new Array();
pics[0] = "cars.jpg";
pics[1] = "cats.png";
pics[2] = "dogs.png";
pics[3] = "bus.jpg"
//total amount of pictures to display
var pictot = pics.length-1;
var nxt = $(".next"),
prv = $(".prev"),
view = $(".view_gallery"),
gal = $(".gallery"),
overlay = $(".overlay"),
num = 0;
//view gallery
view.click(function(){
overlay.show();
gal.show();
// Start gallery off on the first image
gal.html('<img src="' + pics[0] + '" />');
});
nxt.click(function(){
// If on the last image set value to 0. Else add 1
if (num == pictot){num = 0;}else{num++;};
update();
});
prv.click(function(){
// If on first image set value to last image number. Else minus 1
if (num == 0){num = pictot;}else{num--;}
update();
});
function update () {
// update image with next/previous
gal.html('<img src="' + pics[num] + '" />');
//center image (not working very well)
var x = gal.width()/2;
gal.css("marginLeft", -x);
};
//hide
overlay.click(function(){
gal.hide();
$(this).hide();
});
The problem you have is that the "update" function is called immediately after clicking on prev/next. The image has not yet been loaded, so the code does not actually know the new gal.width yet. That's why it works after a full round: the images are now in the cache, and therefore already available.
The best solution would be to use javascript Image objects to preload the pictures; an easier way but possibly problematic is to use the 'load' event (it may not work well in all browsers).
You can align your gallery div with some simple css hack.
1)first define width. (you can define dynamic width with jquery).
2)add position:absolute;
3)add left:0 , right:0;
4)add margin:0 auto;
final code looks like this.
.gallery {
background: none repeat scroll 0 0 #FFFFFF;
left: 0;
margin: 0 auto !important;
padding: 10px;
position: absolute;
right: 0;
width: 600px;
z-index: 200;
}
your math is wrong, look at this example http://jsfiddle.net/8pScd/6/
i've just need to change your math at
var x = $('body').width()/2 - gal.width()/2;
gal.css("margin-left", x + 'px');
and i removed this line at your css
left: 50%;
.gallery{
z-index: 200;
padding: 10px;
position: absolute;
background: #fff;
}
Knowing that .gallery is 920px wide, set left: 50%; margin-left: -470px. Also remove the line in javascript which updates margin-left of the gallery container - gal.css("marginLeft", -x);

How to preload a webpage before showing it?

I have created a simple webpage with several images, but when a user visits it, the browser loads the images one at a time, instead of all at once.
I want instead to first show a "loading" gif in the center of the page and then, when all the images are downloaded, show the entire webpage to the user at once..
How can I do this?
You can show a loader image by putting it somewhere im <img> tag and use below js code to hide it later on when all images are shown:
window.onload = function(){
var el = document.getElementById('elementID');
el.style.display = 'none';
};
Where elementID is supposed to be the id of loader element/tag.
The load event fires when all images/frames/external resources are loaded, so by the time that event fires, all images are loaded and we therefore hide the loading message/image here.
Edit: I defer to Keltex's answer. It's a much better solution. I'll leave mine here for posterity (unless I should delete the content and my answer entirely? I'm new here).
Another solution, which was used fairly frequently in the past, is to create a landing page that preloads all of your images. When the preloading is done, it redirects to the actual site. In order for this to work, you'd need to get the URLs to all of the images you want to load, and then do something like this:
# on index.html, our preloader
<script type='text/javascript'>
// add all of your image paths to this array
var images = [
'/images/image1.png',
'/images/image2.png',
'/images/image3.png'
];
for(var i in images) {
var img = images[i];
var e = document.createElement('img');
// this will trigger your browser loading the image (and caching it)
e.src = img;
}
// once we get here, we are pretty much done, so redirect to the actual page
window.location = '/home.html';
</script>
<body>
<h1>Loading....</h1>
<img src="loading.gif"/>
</body>
You can do this with JQuery. Say your page looks like this:
<body>
<div id='loader'>Loader graphic here</div>
<div id='pagecontent' style='display:none'>Rest of page content here</div>
</body>
You can have a JQuery function to show pagecontent when the entire page is loaded:
$(document).ready(function() {
$(window).load(function() {
$('#loader').hide();
$('#pagecontent').show();
});
});
HTML
<div id="preloader">
<div id="loading-animation"> </div>
</div>
JAVASCRIPT
<script type="text/javascript">
/* ======== Preloader ======== */
$(window).load(function() {
var preloaderDelay = 350,
preloaderFadeOutTime = 800;
function hidePreloader() {
var loadingAnimation = $('#loading-animation'),
preloader = $('#preloader');
loadingAnimation.fadeOut();
preloader.delay(preloaderDelay).fadeOut(preloaderFadeOutTime);
}
hidePreloader();
});
</script>
CSS
#preloader {
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
position: fixed;
background-color: #fff;
}
#loading-animation {
top: 50%;
left: 50%;
width: 200px;
height: 200px;
position: absolute;
margin: -100px 0 0 -100px;
background: url('loading-animation.gif') center center no-repeat;
}
Create a div with class name preloader and put a loader inside that div.
style the class preloader just like below
.preloader {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: white;
/* background-color is would hide the data before loading
text-align: center;
}
Html
<div class="preloader">
Any loader image
</div>
Jquery
$(window).load(function(){
$('.preloader').fadeOut(); // set duration in brackets
});
A simple page loader is ready....

Categories

Resources