I'm using Smoothstate.js to add page transitions to my website and I'm trying to show a loading page between each page transition using the onStart, onProgress and onReady functions.
The code I have works, but every now and again it get's stuck on the loading page and the container div isn't removing the class 'is-loading'. However, it is removing the is-exiting class even though they're with the same removeClass line?
I'm so confused as to why It's not removing. Can anyone help please?
// Photoswipe
$(function(){
'use strict';
var options = {
prefetch: true,
debug:true,
cacheLength: 0,
repeatDelay: 500,
onStart: {
duration: 0, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onProgress: {
// How long this animation takes
duration: 0,
// A function that dictates the animations that take place
render: function ($container) {
setTimeout(function() {
$container.addClass('is-loading');
$('#progressBar').append('<div id="bar"></div>');
var progress = '100%';
$('#bar').animate({
width: progress
}, 400);
}, 500);
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
$container.removeClass('is-loading is-exiting');
// Inject the new content
$container.html($newContent);
},
},
onAfter: function() {
navbarAnimate();
closeMenu();
ImageSliders();
initPhotoSwipeFromDOM('.gallery');
ImageOverlay();
}
},
smoothState = $('#main').smoothState(options).data('smoothState');
});
Just a hint:
you add is-loading, 500ms after the loading process started. So may it be possible that onReady gets fired before your 500ms timeout? And therefore is-loading will be added as class again, after your removeClass call?
tl;dr: the problem is most likely the timeout here
setTimeout(function() {
$container.addClass('is-loading');
$('#progressBar').append('<div id="bar"></div>');
var progress = '100%';
$('#bar').animate({
width: progress
}, 400);
}, 500);
Related
The Issue
Smoothstate.js keeps the <head> of the page that I was just on and injects it back into the home page when I navigate back to index.html.
For example: I click a link that takes me to proj1.html Then I want to leave that page by clicking the home link which directs back to index.html. Page directs back to home but the layout is broken because the home page <head> contains the contents from <head> of proj1.html..Thus making all my styles are broken on the home page.
Smoothstate is caching the <head> and I am not sure how to prevent this from happening...
I tried using the cache clearing method they have but no success. smoothState.clear();
Here is my JS
$(function(){
'use strict';
var $page = $('#main'),
options = {
debug: true,
prefetch: true,
cacheLength: 0,
onStart: {
duration: 250, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onStart: {
duration: 0,
render: function ($container, $newContent) {
// Remove your CSS animation reversing class
$container.removeClass('is-exiting');
// Inject the new content
$container.html($newContent);
}
}
},
smoothState = $page.smoothState(options).data('smoothState');
});
Fixed. The <head> loading issue was caused by not adding the appropriate classes to $page object.
#main contains all the content I wanted to fade.
head is our <head> element that contains all styles.
body entire body of the page.
var $page = $('#main','head','body')
$(function(){
'use strict';
var $page = $('#main','head','body'),
options = {
debug: true,
prefetch: true,
cacheLength: 1,
blacklist:'.luxbar-item',
onStart: {
duration: 250, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onStart: {
duration: 0,
render: function ($container, $newContent) {
// Remove your CSS animation reversing class
$container.removeClass('is-exiting');
// Inject the new content
$container.html($newContent);
}
}
},
smoothState = $page.smoothState(options).data('smoothState');
});
I am using smoothStates default settings and I wanted to know if I can add a class to the main wrapper so I can change the background color of the site? I don't want to add another div under main as its just extra markup.
At the moment I can only add page-index and then the rest of the pages donĀ“t change as smoothState doesn't load the page again.
EDIT: So I want to add a class for each page, like: page-index, page-about and so on.
I have a div like so:
<div id="main">
// stuff here
</div>
When you click on /news:
<div id="main" class="page-news">
// stuff here
</div>
My functions:
$(function(){
'use strict';
var options = {
prefetch: true,
cacheLength: 2,
onStart: {
duration: 250, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
// Remove your CSS animation reversing class
$container.removeClass('is-exiting');
// Inject the new content
$container.html($newContent);
}
}
},
smoothState = $('#main').smoothState(options).data('smoothState');
});
To achieve what you want, you can use onAfter.
The function to run when the new content has been injected into the page and all animations are complete. This is when to re-initialize any plugins needed by the page.
Create a function:
function addClass() {
$('#main').addClass('your_class second_class');
};
Then inject this into your smoothState initialization:
$(function(){
'use strict';
var options = {
prefetch: true,
cacheLength: 2,
onStart: {
duration: 250, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
// Remove your CSS animation reversing class
$container.removeClass('is-exiting');
// Inject the new content
$container.html($newContent);
}
},
onAfter: function($container, $newContent) {
addClass();
}
},
smoothState = $('#main').smoothState(options).data('smoothState');
});
Update: How to dynamically set classes:
<!-- HTML -->
<div id="cms-classes" class="Put your classes in here">
</p>
/* CSS */
#cms-classes { display: none }
// JavaScript
function addClass() {
cmsClasses = $('#cms-classes').attr('class');
$('#main').addClass(cmsClasses);
};
Hope this helps!
Reference
I've implemented the baraja jquery plugin for a section on a 'web app' that I need to create.
Rather than the plugin spreading the cards on the click of a button, I've opted to alter the script and spread out the cards on hover. On the face of it this works but if you hover over the cards and back off quickly before the animation is finished the cards will stay open. And then when you hover over the 'deck' they close. I've created a codepen below to show this:
http://codepen.io/moy/pen/OPyGgw
I've tried using .stop(); but it doesn't seem to have an impact on the result. Can anyone help me with this?
Additionally I'd like the deck to be open on page load, then close after a second or 2. I tried this with $( document ).ready() including the baraja.fan call but that didn't trigger it - any ideas?
this one really tickled me ;) tried several things, but - as already told - the plugin doesn't expect to get the close animation call faster, then the opening animation will run.
so finally i build you the following.
- opening the fan, right at document ready
- created a timeout for the mouseleave, to wait for the opening animation duration, before closing it - you will have a 400ms delay when mouseleave the element, but it will close, even when you've been to fast...
$(document).ready(function () {
if ($("#baraja-el").length) {
var $el = $('#baraja-el');
baraja = $el.baraja();
}
//initial open
baraja.fan({
speed: 400,
easing: 'ease-in-out',
range: 80,
direction: 'right',
origin: {
x: 0,
y: 0
},
center: true
});
$('.baraja-container').addClass('open');
// navigation
$('#baraja-prev').on('click', function (event) {
baraja.previous();
$('.baraja-container li').each(function () {
if ($(this).css('z-index') === "1000") {
$(this).addClass('visited');
}
});
});
$('#baraja-next').on('click', function (event) {
baraja.next();
$('.baraja-container li').each(function () {
if ($(this).css('z-index') === "1010") {
$(this).addClass('visited');
}
});
});
$('.baraja-container').hover(function (event) {
if(!$(this).hasClass('open'))
{
$(this).addClass('open');
baraja.fan({
speed: 400,
easing: 'ease-in-out',
range: 80,
direction: 'right',
origin: {
x: 0,
y: 0
},
center: true
});
}
}, function (event) {
curBarCon = $(this);
setTimeout(function(){
curBarCon.removeClass('open');
baraja.close();
}, 400);
});
$('.baraja-container li').click(function () {
$(this).addClass('visited');
});
});
since i fiddled in your codepen, you should have the working version here: http://codepen.io/moy/pen/OPyGgw
but... it's really no perfect solution. i'd suggest to get another plugin or rework baraja to get callback functions, which would test if the animation is currently running and dequeue them if needed.
rgrds,
E
function showImage() {
var toggleImage = document.getElementById("loadingImage");
if(toggleImage.style.display == "inline") {
document.getElementById('loadingImage').style.display='none';
} else {
document.getElementById('loadingImage').style.display='inline';
document.getElementById('loadingImage2').style.display='none';
document.getElementById('loadingImage3').style.display='none';
document.getElementById('loadingImage4').style.display='none';
}
}
<img class="TeamMembersPictures" `enter code here`src="http://www.ishop247.co.uk/TeamPictures/Yvonne.jpg" onclick="showImage();"/>
<img id="loadingImage" src="http://www.ishop247.co.uk/TeamPictures/YvonneBG.jpg" style="display:none"/>
This is the code i have to display a new image on click of another image but what i want is for it to be a smooth slide down on the image that is displayed onclick
Better yet, why not use CSS animation? Check out Animate.css (I have no affiliation) which allows you to simply include the css file at the top of the page and then do something like this...
<img src="whatever.png" class="animated bounceInDown"/>
You can download the css here...
http://daneden.github.io/animate.css/
To slide an element down with jQuery, you want the slideDown function. For example:
function showImage() {
$('#loadingImage').slideDown();
}
As you can see from the link to the slideDown documentation, there are many ways you can customize the slide.
function showImage() {
$('#loadingImage').slideDown({
duration: 400,
easing: 'swing',
queue: true,
specialEasing: {/*key: value...*/},
step: function(now, tween) {
// ...
},
progress: function(animation, progress, remainingMs) {
// ...
},
complete: function() {
// ...
},
start: function(animation) {
// ...
},
done: function(animation, jumpedToEnd) {
// ...
},
fail: function(animation, jumpedToend) {
// ...
},
always: function(animation, jumpedToend) {
// ...
}
});
}
If you don't need much of that, there are a couple smaller variations on the function (all parameters are optional):
$('#loadingImage').slideDown(400, function() {
// complete...
});
$('#loadingImage').slideDown(400, 'swing', function() {
// complete...
});
Core jQuery only offers 'swing' and 'linear' for the easing values. Plugings such as jQuery UI can offer additional values. Duration can be a number (in milliseconds) or a string ('fast' = 200ms or 'slow' = 600ms).
I am trying to get an image to change opacity smoothly over a duration of time. Here's the code I have for it.
<script type="text/javascript">
pulsem(elementid){
var element = document.getElementById(elementid)
jquery(element).pulse({opacity: [0,1]},
{ duration: 100, // duration of EACH individual animation
times: 3, // Will go three times through the pulse array [0,1]
easing: 'linear', // easing function for each individual animation
complete: function() { alert("I'm done pulsing!"); }
})
</script>
<img src="waterloo.png" onmouseover="javascript:pulsem("waterloo")" border="0" class="env" id="waterloo"/>
Also, is there a way for this to happen automatically without the need of a mouseover? Thanks.
I'm assuming your code is for the jQuery pulse plugin: http://james.padolsey.com/javascript/simple-pulse-plugin-for-jquery/
If your above code is not working, then fix "jquery" to be "jQuery".
For starting it on page load, just do:
jQuery(function() {
jQuery('#yourImageId').pulse({
opacity: [0,1]
}, {
duration: 100, // duration of EACH individual animation
times: 3, // Will go three times through the pulse array [0,1]
easing: 'linear', // easing function for each individual animation
complete: function() {
alert("I'm done pulsing!");
}
});
Add an id to your image and you're golden.
});
To fire the animation of your own accord:
pulsate( $('#waterloo') );
revised code to continually pulsate (wasn't sure if this was what you're after) - the pulsate effect is relegated to it's own function so you can call it directly or in your event handler
<script type="text/javascript">
$(function() { // on document ready
$('#waterloo').hover( //hover takes an over function and out function
function() {
var $img = $(this);
$img.data('over', true); //mark the element that we're over it
pulsate(this); //pulsate it
},
function() {
$(this).data('over', false); //marked as not over
});
});
function pulsate(element) {
jquery(element).pulse({opacity: [0,1]}, // do all the cool stuff
{ duration: 100, // duration of EACH individual animation
times: 3, // Will go three times through the pulse array [0,1]
easing: 'linear', // easing function for each individual animation
complete: function() {
if( $(this).data('over') ){ // check if it's still over (out would have made this false)
pulsate(this); // still over, so pulsate again
}
}});
}
<img src="waterloo.png" border="0" class="env" id="waterloo"/>
Note - to trigger events, you can use .trigger() or the helper functions, like
$('#waterloo').mouseover() // will fire a 'mouseover' event
or
$('#waterloo').trigger('mouseover');
this might be what you're looking for.
http://www.infinitywebcreations.com/2011/01/how-to-create-a-throbbingpulsing-image-effect-with-jquery/
I personally do something like this to pulse when the mouse hovers over the image and return to full opacity on mouse out...
$(document).ready(function () {
function Pulse(Target, State) {
//Every 750ms, fade between half and full opacity
$(Target).fadeTo(750, State?1:.5, function() {Pulse(Target, !State)});
}
$("#ImageId").hover(function () {
$(this).stop()
Pulse(this);
}, function () {
$(this).stop(false, true).fadeTo(200, 1); //200ms to return to full opacity on mouse out
});
});