Slidein element is visible before the animation - javascript

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.

Related

JS content not working after a page transition using Barba.JS

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.

d3.ease fade image in

I am calling the following function and passing it the location of an image:
function show_image(source) {
var img = d3.select("#right-section").append("img").attr("src",source)
img.transition().duration(5000).easeLinear;
}
Here is the function that uses some JQuery to empty the relevant HTML div object (right-section) and then show the image:
function Con1aaRight(div) {
$("#right-section").empty();
show_image("images/netflix.jpg");
}
The problem is the image is showing but not fading in like I would like it to (with d3.ease in the show_image function). I probably should be using JQuery but I would like to incorporate d3. Similar transition/animation ideas welcome. I am building a scrolling webpage tutorial on a data science topic with text on the left and images on the right.
The problem here is understanding what is a D3 transition and how it works.
A D3 transition, as the name implies, transitions from one state, or value, to another state.
That being said, you can, for example, transition...
A position: from x = 10 to x = 60.
A color: from green to blue.
A font size: from 10px to 18px.
An opacity: from 0.2 to 0.9.
A stroke width: from 1px to 5px.
... and several other attributes/styles.
However, you cannot transition this:
non-existence ➔ existence
As Bostock, creator of D3, once said (emphasis mine):
When modifying the DOM, use selections for any changes that cannot be interpolated; only use transitions for animation. For example, it is impossible to interpolate the creation of an element: it either exists or it doesn’t. (source)
Solution: transition the opacity of the image:
var body = d3.select("body");
show_image("http://www.defenders.org/sites/default/files/styles/large/public/tiger-dirk-freder-isp.jpg")
function show_image(source) {
var img = body.append("img").attr("src", source).style("opacity", 0)
img.transition().duration(5000).ease(d3.easeLinear).style("opacity", 1)
}
<script src="https://d3js.org/d3.v4.min.js"></script>
PS: get rid of that jQuery code. You don't need jQuery when using D3. Mixing jQuery and D3 is not only unnecessary but also, in some cases, it will make things silently break.

jQuery Waypoint Plugin troubles

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!

Mouseenter and Mouseleave giving undesired results

Im having an absolute nightmare with a plugin im trying to integrate.
Im trying to make X elements on my page flip on hover, and then on mouseout revert back.
Im using the flip function, and it works fine if i hover over an element, wait a few seconds for the flip to finsih animating, and then move my cursor. If i hover quickly however, my flip happens but messes up completely, and you cant quickly move your mouse across multiple elements.
I've tried using stop() to no avail so thought I'd ask on here, I've attached a fiddle, when looking at my fiddle, quickly run your mouse across all elements and you will see what I mean
http://jsfiddle.net/5JyVC/
$('.sec-con').prepend('<div class="target" style="width:100%; height:100%; z-index:999999; cursor:pointer;top:0; left:0; display:block; position:absolute; "></div>');
$('body').on({
mouseenter:
function () {
$(this).stop(true, true).next('.sector').flip({
direction:'rl',
color:'#2d6995',
speed: 200,
content:'<span class="all-vacancies">View all Vacancies <br />in this sector.</span><span class="read-more">Click here to read more.</span>'
});
},
mouseleave: function () {
$(this).next('.sector').revertFlip();
}
}, '.target');
It's something to do with the flipLock data attribute. If you mouseout too soon flipLock is true and the revert flip wont happen causing the next mouseover to start with the wrong content. So from then on you're flipping back and forth between the same content.
If you remove the flipLock detection and return false and add stop to the animation call in flip it will revert properly.
The animation looks a bit wonky though, I'm not sure what can be done about that.
This works for me: http://jsfiddle.net/5JyVC/5/ If you move fast enough it will still mess up, not sure why that is, maybe multiple mouseover events? This is what the original flipLock intended to prevent I guess.
Maybe flipLock should be more complex, when flipped, only allow flip backs and vice versa. The current implemenation of flip and revertFlip doesn't allow for this though.
Here is an alternative way in pure css (as requested)
the javascript is here just to add the elements faster
Anyway i modified the function sothat you can add HTMLElements direct to the function that adds the various divs that needs to be flipped.
A & B, where A is the front and B is the back.
in this example i add 6 elements to the page.
here is the javascript to test the elements
var D,
flip=function(A,B){// HTMLElement,HTMLElement - no text
var box=D.createElement('div');
box.appendChild(D.createElement('div')).appendChild(A);
box.appendChild(D.createElement('div')).appendChild(B);
return box;
},
init=function(){
D=window.document;
for(var i=0,f=D.createDocumentFragment();i<6;i++){
var a=D.createTextNode('Front '+i),
b=D.createTextNode('Back '+i);
f.appendChild(flip(a,b));
}
D.getElementsByClassName('flip')[0].appendChild(f);
}
window.onload=init;
As you can see no eventlisteners or complex code as if you use css3 you totally can put the :hover on the divs without the need of javascript (mouseenter,mouseleave).
to add this animation to every element i added a class for the container of the elements.
html,body{width:100%;height:100%;margin:0;padding:0;} /* important */
.flip{
width:100%;height:100%; /* in this case the perspective center */
-webkit-perspective:1200; /* is in the page center */
}
.flip>div{
width:200px;height:160px; /* width && height of the flip box */
float:left;
margin:16px;
-webkit-transform-style:preserve-3d;
-webkit-transition:all 600ms ease;/* animation speed is 600ms */
}
.flip>div>div{
width:100%;height:100%; /*to fit the flip container*/
-webkit-backface-visibility:hidden;/* hide the back side */
line-height:160px;text-align:center;/*center the text*/
background-color:grey;/* both sides color */
}
.flip>div>:nth-child(2){
-webkit-transform:rotateY(180deg);
margin-top:-160px;/* hack so no need for position absolute*/
}
.flip>div:hover{
/*-webkit-transition:all 1000ms ease 1000ms;
want to close it slowly with a delay? */
-webkit-transform:rotateY(180deg);
}
/* no position relative or absolute which slows down ios */
this is writtenfor webkit browsers (chrom, safari, android, ios)
i made it for my ipad.
to use it with firefox and the latest ie's that support css3 you need to duplicate this -webkit styles with the -moz,-ms,-o prefixes and check the support.
this example is based on 3d so the container has also a perspective value.
and the elements flip in real 3d and so you trigger the HW GPU acceleration on the various browsers.
the html just needs that container with the class flip
using classallows you to add multiple containers with multiple flipping elements.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>flip</title>
//add here the links to css3 or the <style>
//add here the the script or link to the script
</head>
<body><div class="flip"></div></body>
</html>
so this is very simple as you can see but from this base you can create veri impressive animations just changind the flip css.
if you need some more advanced features you can handler that with javascript event
transitionend
if you want to add the boxes manually this is all you need to write.
<div class="flip">
<div>
<div>Element1 Front</div>
<div>Element1 Back</div>
</div>
<div>
<div>Element2 Front</div>
<div>Element2 Back</div>
</div>
</div>
Want to triggerthe animation on click/mouseevent/dragevent/scrollevent whatever?
replace .flip>div:hover with .flip>div.flipped
and in javascript on event
this.parentNode.classList.toggle('flipped')
or
this.parentNode.classList.add('flipped') & this.classList.remove('flipped')
Now this is all about modern browsers and uses modern javascript&&css3 but as you want to flip something you anyway need a modern browser.
also jQuery can't flip something in ie6
like always
javascript handle the events or adds multiple elements
css to create the style of the page
html just for a basic structure.
for any other questions just ask
fiddle (test with chrome)
http://jsfiddle.net/gNB3z/2/

Why are style assignments performed immediately after creation not animated?

Opening this fiddle on Webkit will show what I'm talking about.
How can I specify an element's style when it is first specified, and then its final state?
It should be possible to specify a single step animation fully this way (without having to start using #keyframes) but it seems like there is a lot of implementation specific strangeness I must deal with at this point. Note how in Firefox no animation is performed...
Seems to be the same issue as described here: CSS3 transitions to dynamically created elements
so
$("#one").on('click',function(){
var word = $("<div style='opacity: 0; height:0'>word</div>");
$('body').prepend(word);
window.getComputedStyle(word[0]).getPropertyValue("top");
word.css({height: 100, opacity: 1});
});
also works in this case: http://jsfiddle.net/wWnnH/3/
Alternatively, you can use jQuery.animate()
word.animate({height: 100, opacity: 1}, 5000);
Will work without the CSS, and on both webkit and mozilla. Although this defeats the purpose of trying to use CSS3 I guess.

Categories

Resources