I am using Barba.js and GSAP to create page transitions for my website. After watching a few tutorials and fiddling around a bit, I managed to create a slide-transition between two pages. Thing is I've also got other javascript content which is for other functionality elements on each page. On the first page load, everything seems to work fine.
I then click on a link to transition to the next page, the transition goes well but suddenly none of the elements I had coded in the very same JS file work anymore.
I can still transition perfectly between each page but none of the other JS content seems to be working. I'm not getting any errors in the console so I have no idea what's exactly happening here.
Here's what my Barba initialization looks like.
barba.init({
sync: true,
transitions: [{
async leave(data) {
const done = this.async();
animationLeave();
await delay(1000);
done();
},
enter(data) {
animationEnter();
},
once(data) {
animationEnter();
}
}, {
name: 'home-transition',
to: {
namespace: ['home']
},
async once(data) {
homeAnimation();
}
}]
});
The AnimationEnter, AnimationLeave and HomeAnimation methods just link to GSAP animations. For example here's what the AnimationLeave one looks like:
function animationLeave() {
var tl = gsap.timeline();
tl.to('.loading-screen', {
duration: 1,
width: '100%',
left: '0%',
ease: 'expo.easeInOut'
});
tl.to('.loading-screen', {
duration: .8,
width: '100%',
left: '100%',
ease: 'expo.easeInOut',
delay: .3
});
tl.set('.loading-screen', {
left: '-100%',
width: '0%'
});
}
Any help is appreciated!
I flipped the internet upside down looking for a solution to this very problem just a few weeks ago.
Essentially, all your JavaScript runs only once on the initial page load when you're working with BarbaJS. It doesn't get reinitialised once you transition from one page to another. This means that when you transition to another page, all JavaScript-powered animations on that new page won't work unless those animated elements existed on the first page loaded when the site is visited.
To get page-specific animations to work from one page to another after a transition, all of those animations have to be reinitialised. You can do this using global Barba hooks:
barba.hooks.beforeEnter(() => {
killEvents();
});
This code will run before the next page is shown between transitions. If you're using something like ScrollTrigger or an instance of a smooth scrolling library, you can kill those instances or else they'll just stick around and be a memory hog. If you're not, then there's no need to remove any events.
barba.hooks.afterEnter(() => {
addEvents();
});
This is the important part. After a transition, you can then re-add your animation events as shown here.
Another really important thing that helped me was initialising your DOM nodes inside the functions that returned or created your animations. If you simply initialise the DOM nodes once on the initial page load and not on each transition, your animation code will assume you're only animating the elements on the initial page even when the page has transitioned to another.
Some Greensock forum posts that helped:
https://greensock.com/forums/topic/26585-scrolltrigger-not-working-after-barba-transition/
https://greensock.com/forums/topic/24365-problem-with-killing-and-reinitialising-scrolltrigger-after-single-page-app-page-transition/
TL;DR, reinitialise your JavaScript on each page transition.
Related
I'm trying to recreate the animations when loading from this website:
https://uchuhimo.me
I think they are using velocity.js to do the animations.
I tried to recreate some of this and kind of succeeded (though not sure if doing it properly). There is one problem though, that the elements are there and then they animate (slidein), whereas correctly they should be hidden and then they slide in so they become visible (like on the website). I looked into documentation and i think that should be expected behaviour? But here in my example it does not work like that.
https://codepen.io/pokepim/pen/EpyKWR
The sequence of animation I run is the following:
And they should imitate the animation of that website im trying to imitate.
var loading = [
{ elements: $(".logo-line-before"), properties: {width: '100%'}},
{ elements: $(".logo-line-after"), properties: {width: '100%'}, options: { sequenceQueue: false }},
{ elements: $(".ttl"), properties:"transition.slideDownIn"},
{ elements: $(".ui.top.vertical.segment"), properties:"transition.slideDownBigIn"}
];
$.Velocity.RunSequence(loading);
That's all using Velocity V1 so there's limited help available (it's not supported any more), however you do need to pre-load the elements for opacity:0, there's no need for changing the display property on them as it's just a "get it visible" animation on an element that should still take up space.
I'd suggest simply adding a style="opacity:0;" on each of those elements in the HTML source and going from there.
I'm having slight troubles with the jQuery Waypoint plugin, and any information/help is appreciated.
Ok, so to define what I want to do: I have images, that are hidden prior to being in the view area. I want them to do an animation effect once in the view area. That is the final result, for now, I'm still in testing as I am generally new to jQuery but getting better.
So I started out doing the shake on a single div, and it worked great once the once it was in view. I used the following code:
HTML:
<div class="shown">Shake it</div>
jQuery
jQuery(document).ready(function($){
$(".shown").waypoint(function(direction) {
$(this).effect("shake");
}, { offset: '95%', triggerOnce: true });
});
Then I made two instances of the class='shown' in my HTML (one at top, and one at the bottom), and when I scrolled to them, they both worked great. Plus, they both worked at separate times, which is what I'm trying to gain.
Here's the trouble
When I tried to 'display:none' and then animate to show on scroll, it animates BOTH, instead of just the single at a time.
This is what I'm using
HTML
<div class="shown" style="display: none;">
jQuery
jQuery(document).ready(function($){
$(".shown").waypoint(function(direction) {
$(this).fadeIn( 10000, function() {
// Animation complete
});
}, { offset: '95%', triggerOnce: true });
});
Ok, so just to clarify one more time :D (to be safe)
I want to be able to use the same class for MULTIPLE instances, that will only display once THAT element is in view. Right now it's displaying ALL elements once 1 instance is in view.
Again, any information/help is appreciated. You guys have a great community here, I'm glad I could join!
I am building a website that has a few animations when you load the home page (for example, the main logo and a few menus slide in from the sides of the screen). Simultaneously, I am also using AJAX in the background to start to load some images that might be viewed later. The problem with this is that when the images are loading, the animations become quite choppy. Is there any way to stop this? Or maybe give the AJAX function a lower priority so that it doesn't try to do anything when an animation is running?
Here is the current script I'm using to load these images:
$('.lightbox-container.first').load('/images/first_set/', function(){
$('.lightbox-container.second').load('/images/second_set/', function(){
$('.lightbox-container.third').load('/images/third_set/', function(){
$('.lightbox-container.fourth').load('/images/fourth_set/', function(){
$('.lightbox-container.fifth').load('/images/fifth_set/', function(){
$('.lightbox-container.sixth').load('/images/sixth_set/');
});
});
});
});
});
An all of my animation function look something like:
$('.third-section').animate({ 'opacity': '1', 'height': '200px', 'padding-top': '20px', }, 500);
The problem
Since all your ajax and js animations run on the same browser thread, you are bound to have this problems. You are reaching the limits of your CPU, which causes the choppiness.
How to solve this
Use CSS3 transforms. Those are hardware accelerated in all modern browsers and run on a separate threads, so their performance is generally not affected by ajax calls. Since you said you only slide things around, I think this would be the ideal solution for you. There is a great article about it here:
http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/
Your case
So to actually make this work for you. Leave the ugly ajax calls as they are for now. Instead of using jQuery animate, you need 2 states - the initial, which positions the slide away and one with an extra class, which positions your slide in it's target place.
All you have to do is add the class to the slide and it will nicely come in place. Theory is simple.
Sample
Your initial state could be something like this:
.slide {
transform: translate(-400px, -200px);
transition: all 5s;
}
And the one to show in place:
.slide.show {
transform: translate(0px, 0px);
}
I am using Zurb Foundation to create a small website and I have a top navigation bar with four links. On clicking each link, I want to horizontally slide to a different page every time.
The content in the page should be loaded via ajax and not loading all pages on visiting index page itself. (note: content for slide-to page should be loaded not after the slide animation but somehow with the slide itself or else the empty sliding would look a little weird)
In addition, since I am using foundation to get responsive layouts, I am confused how to place the sections for the different pages horizontally. If the website wouldn't have been responsive, I probably would have placed the other pages separated by a margin property and to slide them, I could have done an animate of the margin property.
But, how do I get a horizontal page sliding effect (along with ajax loading) on my current page?
I think you want a 'single page website'? There are a lot of tutorials about this but this one is great:
http://vandelaydesign.com/blog/web-development/single-page-sliding-nav/
A live demo can be found here:
http://vandelaydesign.com/demos/single-page/
This uses jquery to scroll to the element with a specific id on the page. When you click one of the menu items it scrolls/slides automatically to that part of the page.
Just because the code is a bit long I'll only post the Jquery, to give you an idea.
<script type="text/javascript">
$(document).ready(function(){
$('#topnav').onePageNav({
currentClass: 'current',
scrollOffset: 0
});
});
</script>
$('#nav').onePageNav({
currentClass: 'current',
changeHash: false,
scrollSpeed: 750,
scrollOffset: 30,
scrollThreshold: 0.5,
filter: '',
easing: 'swing',
begin: function() {
//I get fired when the animation is starting
},
end: function() {
//I get fired when the animation is ending
},
scrollChange: function($currentListItem) {
//I get fired when you enter a section and I pass the list item of the section
}
});
Hope it helps :)
I want to fade in an entire web page after all its elements finished loading. The web page includes the background image repeated left to right, and the main content area with some text and pictures. I assume I should set body opacity to 0 in CSS, and use JavaScript code to fade in the page.
I have to use MooTools, more specifically, version 1.2.6, because that library is already linked to the page (and shouldn't be upgraded to a more recent version, for a number of reasons).
One of the StackOverflow experts suggested this MooTools snippet as a solution:
window.addEvent('load', function() {
$$('body').set('morph', {duration: 300}).morph({'opacity': '1'});
});
PROBLEM: for some reason, instead of smoothly fading in the page, the snippet makes the background appear right away, and then, a second or so later, the page pops up, without any fade-in effect. Most likely it's me who's not doing things right.
I'd appreciate a bit of advice from a knowledgeable person.
The answer to your question is to do the following.
Remove the CSS opacity:0; in the stylesheet and use this code adjusted from yours
I increased from 300 to 3000 which in seconds is from .3seconds to 3seconds.
chained:
window.addEvent('load', function () {
$$('body').fade('hide').set('morph', {
duration: 3000
}).morph({
'opacity': '1'
});
});
expanded:
window.addEvent('load', function () {
var el = $$('body');
el.fade('hide'); // hide body tag
el.set('morph', {duration: 3000});
$$('body').morph({'opacity': '1'});
});
Notice:
I do agree with LifeInTheGrey about bad practice, but i said i would answer your question.