Loading Icon While Images Load - javascript

How would I program a loading icon or graphic that appears while images on a page load. An example would be http://landerapp.com/?
My goal is to prevent the user from seeing this images on screen until they are ready to animate (see the problem at http://tsawebmaster1.hhstsa.com/index.html).

Let's begin with a visible loading image that is fixed in the exact middle of the screen. Then, when the page is fully loaded, we'll add a "page_loaded" class on the <body> which:
[1] begins the fade out of the loading image
[2] begins the fade in and translation of offscreen images to the screen
window.onload = function() {
document.body.classList.add("page_loaded");
}
.loader {
opacity: 1;
transition: 2s opacity;
height: 300px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.right,
.left {
height: 100px;
position: absolute;
transition: 1s 2s;
opacity: 0;
}
.left {
left: 0;
transform: translateX(-50em);
}
.right {
right: 0;
transform: translateX(50em);
}
.page_loaded .loader {
opacity: 0;
}
.page_loaded .right,
.page_loaded .left {
opacity: 1;
transform: translateX(0);
}
<img class="loader" src="https://d13yacurqjgara.cloudfront.net/users/82092/screenshots/1073359/spinner.gif" alt="" />
<img src="https://www.petfinder.com/wp-content/uploads/2012/11/140272627-grooming-needs-senior-cat-632x475.jpg" alt="" class="right" />
<img src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTS704tVMgbKCry10AhT09VE8wBY5S9v-PWxTBOa7o52JU0TsjH" alt="" class="left" />

If you are using Vanilla or jQuery I'd suggest you to use imagesLoaded which is meant to achieve exactly what you want.
I'd go with something like this:
$(function(){
$('.img-container img').imagesLoaded().done(function(){
console.log('images loaded');
$('.img-container .loader').remove();
$('.img-container img.hide').removeClass('hide');
}).fail(function(){
console.log('FAILED TO LOAD IMAGES');
});
});
.img-responsive {
max-width : 100%;
}
.hide {
display : none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/3.2.0/imagesloaded.pkgd.min.js"></script>
<div class="img-container">
<div class="loader">
Loading image....
</div>
<img src="http://mascotafiel.com/wp-content/uploads/2015/10/perros-Husky-Siberiano_opt-compressor-1.jpg" alt="PrettyCoolImage" class="img-responsive hide">
</div>

Related

opacity-based image transition functions really bad

How can i make a better image transition?
Opacity method is not ok because it causes the images to blink
or im doing something wrong. if so, please help :)
<img class="image" id="image1">
<img class="image hidden" id="image2">
.image {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
pointer-events: all;
border-radius: 12px;
background: black;
height: 90vh;
transition: opacity 0.5s linear;
}
.hidden {
opacity: 0;
}
var cycled = false;
function getActiveImage() {
return document.getElementById(cycled ? "image1" : "image2");
}
function displayImage(img) {
getActiveImage().src = img;
document.getElementById("image1").classList.toggle("hidden");
document.getElementById("image2").classList.toggle("hidden");
cycled = !cycled;
}
issue resolved. turns out images aren't blending properly
so i made one image an overlay; same code, but without toggling image1 class

HTML - Second IMG hover issue

I have 2 semicircles stuck next to each other forming a circle. When I hover on the left semicircle, the right one lowers it's opacity (which is what is supposed to do) but when I hover on the right one, the opacity doesn't change at all.
HTML:
<div id="animation-components">
<img src="leftball.svg" alt="" class="animation-item-01">
<img src="rightball.svg" alt="" class="animation-item-02">
</div>
CSS:
#animation-components {}
.animation-item-01 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-02 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-01:hover + .animation-item-02{
opacity: 50%;
}
.animation-item-02:hover + .animation-item-01{
opacity: 50%;
}
What can I alter to make this work?
The issue is that you can only select the next sibling with the adjacent sibling selector.
.element-1 + .element-2 /* good */
.element-2 + .element-1 /* not so good */
Since .animation-item-02 comes after .animation-item-01, there is no way to select the previous .animation-item-01 from .animation-item-02
Doing the following will fix the issue:
#animation-components:hover > div {
opacity: 50%;
}
#animation-components > div:hover {
opacity: 100%;
}
CSS Combinators can't be used to apply styles to elements before target element.
The adjacent sibling selector (+) will aply to all adjacent elements, not to it's opposite elements.
CSS It's in the name: Cascading Style Sheets only supports styling in cascading direction, not up.
To achieve the desired, you can do the folowwing:
#animation-components:hover img {
opacity: .5;
}
#animation-components img:hover{
opacity: 1;
}
<div id="animation-components">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-01">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-02">
</div>
It might just be me but I find it heaps easier to throw in just a little bit of javascript and avoid messy css combinators. Heres my fix, script goes anywhere in your html file, I put it after the closing body tag.
<script>
function fadeOut(obj) {
document.getElementById(obj).style.animationName = "fadeOut";
}
function fadeIn(obj) {
document.getElementById(obj).style.animationName = "fadeIn";
}
</script>
#item1 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#item2 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#keyframes fadeOut {
0%{opacity: 1;}
100%{opacity: 0.5;}
}
#keyframes fadeIn {
0%{opacity: 0.5;}
100%{opacity: 1;}
}
<div id="animation-components">
<img src="leftball.svg" alt="" id="item1" onmouseover="fadeOut('item1')" onmouseout="fadeIn('item1')">
<img src="rightball.svg" alt="" id="item2" onmouseover="fadeOut('item2')" onmouseout="fadeIn('item2')">
</div>
Also its just a me thing, but you have class attributes where id attributes should be. If your applying seperate styles to two completely seperate elements its a good idea to use id, but if your applying same style to two elements

Jimdo: Create rotating clipped disk on button click

I'm trying to create a rotating CD/Disk effect when the play button is clicked. I managed to come up with an example, see the code below. This is partially the state of the player when it is in play mode.
What I would like to create is have a square image with a play button on top. When the user clicks the button, the pause button appears and the middle part of the image starts rotating like a spinning CD/Disk.
I have tried a few things but my skills in JavaScript are lacking to create such an effect.
Any help is appreciated.
NOTE: The code answer should be able to work on the Jimdo site builder.
$(function() {
var activePlayerStartBtn;
function stopOtherPlayerSetNewAsActive(element) {
var toShow = $(element).parent().find('.btn.hide')[0];
$(element).addClass('hide');
$(toShow).removeClass('hide');
if (activePlayerStartBtn) {
var stopButton = $(activePlayerStartBtn).parent().find('.btn').not('.hide')[0];
$(stopButton).addClass('hide');
$(activePlayerStartBtn).removeClass('hide');
}
activePlayerStartBtn = element;
}
function stopPlayer(element) {
$(element).addClass('hide');
$(activePlayerStartBtn).removeClass('hide');
activePlayerStartBtn = null;
}
var widget1 = SC.Widget("so");
$("#playSound").click(function() {
widget1.play();
stopOtherPlayerSetNewAsActive("#playSound");
});
$("#stopSound").click(function() {
widget1.pause();
stopPlayer('#stopSound');
});
});
.button-wrapper {
position: relative;
width: 100%;
max-width: 300px;
}
.img-circle {
clip-path: circle(30% at 50% 50%);
-webkit-clip-path: circle(30% at 50% 50%);
animation: loading 10s linear infinite;
width: 100%;
max-width: 300px;
}
#keyframes loading {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
.btn {
position: absolute;
width: 100%;
max-width: 70px;
cursor: pointer;
transform: translate(-50%, -53%);
top: 50%;
left: 50%;
opacity: .7;
clip-path: circle(33% at 50% 50%);
-webkit-clip-path: circle(33% at 50% 50%);
}
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<script type="text/javascript" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/js/api.js">
</script>
<div class="button-wrapper">
<img src="https://i1.sndcdn.com/artworks-000281899403-n7tdjo-t500x500.jpg" alt="img" class="img-circle">
<img id="playSound" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-playbtn.svg" alt="play" title="play" class="btn" name="playSound">
<img id="stopSound" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-pausebtn.svg" alt="pause" title="pause" class="btn hide" name="stopSound">
</div>
<iframe id="so" width="0%" height="0" scrolling="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/380167502&color=%23ff5500&auto_play=false&hide_related=true&show_comments=false&show_user=false&show_reposts=false&show_teaser=false"
frameborder="0" name="so" style="display: none;"></iframe>
I think this might be what you are looking for.
jsFiddle with rotating Disk example
Let me explain what is happening so you understand what the code and styles do.
I've added the album image twice, one is the background, one is used to create the rotating disk. It looks like this.
<img src="https://i1.sndcdn.com/artworks-000281899403-n7tdjo-t500x500.jpg" alt="img" class="img-circle -clipped">
<img src="https://i1.sndcdn.com/artworks-000281899403-n7tdjo-t500x500.jpg" alt="img" class="img-circle">
You don't see the clipped image, it only is noticed when the animation starts.
When a player is clicked, the -rotating class is added to start the animation.
// Find the clippedImg and add the class -rotating to start the animation
var clippedImg = $(element).parent().find('.-clipped')[0];
$(clippedImg).addClass('-rotating');
When the pause button is clicked, the -rotating class is removed.
Let me know if that's what you are looking for.
I believe you should be able to utilize the css property animation-play-state: paused;
$(function() {
var activePlayerStartBtn;
function stopOtherPlayerSetNewAsActive(element) {
var toShow = $(element).parent().find('.btn.hide')[0];
$(element).addClass('hide');
$(toShow).removeClass('hide');
$('.img-circle').removeClass('paused');
if (activePlayerStartBtn) {
var stopButton = $(activePlayerStartBtn).parent().find('.btn').not('.hide')[0];
$(stopButton).addClass('hide');
$(activePlayerStartBtn).removeClass('hide');
}
activePlayerStartBtn = element;
}
function stopPlayer(element) {
$(element).addClass('hide');
$(activePlayerStartBtn).removeClass('hide');
$('.img-circle').addClass('paused');
activePlayerStartBtn = null;
}
var widget1 = SC.Widget("so");
$("#playSound").click(function() {
widget1.play();
stopOtherPlayerSetNewAsActive("#playSound");
});
$("#stopSound").click(function() {
widget1.pause();
stopPlayer('#stopSound');
});
});
.button-wrapper {
position: relative;
width: 100%;
max-width: 300px;
}
.img-circle {
clip-path: circle(30% at 50% 50%);
-webkit-clip-path: circle(30% at 50% 50%);
animation: loading 10s linear infinite;
width: 100%;
max-width: 300px;
}
.paused {
animation-play-state: paused;
}
#keyframes loading {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
.btn {
position: absolute;
width: 100%;
max-width: 70px;
cursor: pointer;
transform: translate(-50%, -53%);
top: 50%;
left: 50%;
opacity: .7;
clip-path: circle(33% at 50% 50%);
-webkit-clip-path: circle(33% at 50% 50%);
}
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<script type="text/javascript" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/js/api.js">
</script>
<div class="button-wrapper">
<img src="https://i1.sndcdn.com/artworks-000281899403-n7tdjo-t500x500.jpg" alt="img" class="img-circle paused">
<img id="playSound" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-playbtn.svg" alt="play" title="play" class="btn" name="playSound">
<img id="stopSound" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-pausebtn.svg" alt="pause" title="pause" class="btn hide" name="stopSound">
</div>
<iframe id="so" width="0%" height="0" scrolling="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/380167502&color=%23ff5500&auto_play=false&hide_related=true&show_comments=false&show_user=false&show_reposts=false&show_teaser=false"
frameborder="0" name="so" style="display: none;"></iframe>

a tag showing image on hover with transition

I'm trying to display an image on the hover of an a tag which I have got complete and fully working, now I'm facing a problem...
I want the image to 'fade' in and out of the page when it is hovered rather than just appearing in order to give it a more satisfying finish.
My code at the minute is...
a.top-row:hover:after {
transition: .5s;
-webkit-transition: .5s;
-moz-transition: .5s;
display: block;
position: absolute;
z-index: 10;
top: -295px;
left: -30px; }
and to display the image I have seperate id's for each of the a tags so it's done like this..
a#a1:hover:after {
content: url(../images/cars/audi/a1.png); }
HTML -
<a class="top-row" id="a1">A1</a>
Like this? (background fixed, animating opacity)
a.top-row {
position: relative;
}
a.top-row:after {
transition: .5s;
-webkit-transition: .5s;
-moz-transition: .5s;
display: block;
position: absolute;
top: 100%;
left: 100%;
z-index: 10;
width: 70px;
height: 50px;
opacity: 0;
content: ' ';
pointer-events: none;
}
#a1:after {
background: url(https://placehold.it/70x50);
}
#r8:after {
background: url(https://placehold.it/70x50/ff00ff);
}
a.top-row:hover:after {
opacity: 1;
}
<a class="top-row" id="a1">A1</a><br/>
<a class="top-row" id="r8">R8</a>
Having images fade-in using only CSS would only make it complicated. Instead you can use the jQuery fadeIn() and fadeOut() method to achieve the same.
HTML
<div>
<a link="" id="showme">abcd</a>
<img src="image.jpg" height="200" width="300" alt="button" id="btn">
</div>
jQuery
$('#showme').hover(
function() {
$('#btn').fadeIn('slow');
},function() {
$('#btn').fadeOut('slow');
});
CSS
div {
width:305px;
height:229px;
}
#btn {
display:none;
}

Load images before showing a div

I have never asked anything on this forum before so I'll try to be as clear as possible.
I am trying to show a loading screen while the contents of a div is loading in my website.
I tried to use jQuery .load() function but it seems not to work.
It works when i use the .ready() function but i want to load all the images before to show the div.
So the div is hidden (style="display:none;")
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loading"> // loading screen </div>
<div id="divtoshow" style="display:none;"> //images and text </div>
<script>
$("#divtoshow").load(function(){
$("#loading").fadeOut(200);
$("#divtoshow").fadeIn(200);
});
//if i replace load with ready it works
</script>
You want to do stuff specifically when all the images on the page have loaded.Try this custom jQuery event...
/**
* Exposes an event called "imagesLoaded" which is triggered
* when all images on the page have fully loaded.
*/
(function($) {
var loadImages = new Promise(function(done) {
var loading = $("img").length;
$("img").each(function() {
$("<img/>")
.on('load', function() {
loading--;
if (!loading) done();
})
.on('error', function() {
loading--;
if (!loading) done();
})
.attr("src", $(this).attr("src"))
});
});
loadImages.then(function() {
$(document).trigger({
type: "imagesLoaded"
});
});
})(jQuery);
It works by copying each image (in the event they are already loaded, this is necessary to catch the load event) and listening for the load on the copy. I got the idea from here.
Here is a fiddle.
If you want to use the .load() method you need to bind it to the img element not to the container:
$("#divtoshow img").on('load', function(){
$("#loading").fadeOut(200, function(){
$("#divtoshow").fadeIn(200)
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loading">Loading</div>
<div id="divtoshow" style="display:none;"><img src="http://lorempixel.com/350/150"><h1>My Text</h1></div>
If you want the page contents to load before transitioning to display the main page div then you want to us the fundamental document.ready pattern:
<div id="loading"> // loading screen </div>
<div id="divtoshow" style="display:none;"> //images and text
<img src='...a path to a large file....'/>
</div>
and then
<script>
$(document).ready(function() {
$("#loading").fadeOut(200);
$("#divtoshow").fadeIn(200);
});
</script>
In general, if you are doing any element (DOM) manipulation using JQuery and you do NOT havethe document.ready() pattern in place then you should ask yourself if you should maybe add it in. Particularly if you develop with local assets because when you shift to production and network latency has an impact you may find timing issues cause odd bugs in code that worked perfectly when all assets were local.
CSS
#loading {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: fixed;
display: block;
opacity: 0.7;
background-color: #fff;
z-index: 99;
text-align: center;
}
#loading-image {
position: absolute;
top: 100px;
left: 240px;
z-index: 100;
}
HTML
<div id="loading">
<img id="loading-image" src="images/ajax-loader.gif" alt="Loading..." />
</div>
JAVASCRIPT
<script language="javascript" type="text/javascript">
$(window).load(function() {
$('#loading').hide();
});
</script>
The load() method was deprecated in jQuery version 1.8 and removed in version 3.0. you can use window on.load function OR you can also follow the DaniP answer. Here is an example with preloader.
One more problem you are trying to load the #divtoshow which is already display none. So you need to load something that inside on that div
$(window).on('load', function() {
$("#loading").fadeOut();
$("#divtoshow").fadeIn(300);
});
#divtoshow {
display: none;
text-align: center;
}
#loading{
position: absolute;
left: 50%;
top: 50%;
z-index: 1;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Add animation to "page content" */
.animate-bottom {
position: relative;
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 1s;
animation-name: animatebottom;
animation-duration: 1s
}
#-webkit-keyframes animatebottom {
from { bottom:-100px; opacity:0 }
to { bottom:0px; opacity:1 }
}
#keyframes animatebottom {
from{ bottom:-100px; opacity:0 }
to{ bottom:0; opacity:1 }
}
.img-responsive{
width:100%;
height:auto;
display:block;
margin:0 auto;
}
<div id="loading"></div>
<div id="divtoshow" class="animate-bottom">
<img src="http://orig10.deviantart.net/f6bf/f/2007/054/1/9/website_banner_landscape_by_kandiart.jpg" class="img-responsive" alt="banner "/>
<h2> loaded Title!</h2>
<p>Some text and Image in my newly loaded page..</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Categories