Animation on mouse leave - javascript

I am struggling at this moment with css animations.
The problem is that I have an entrypoint div that have his own scale animation, and another div that expands and show up a text, and after few seconds collapses again (I've already achieved this).
The main problem becomes when is a requirement to do all this again when the user hovers the entrypoint, when this occurs we have 2 steps.
Hover and show the text again.
When the mouse leaves, collapse the text again after few seconds.
This is my code https://codepen.io/Arm144/pen/JjRWoXQ
HTML:
<div id="chatbotEntryPoint">
<i>
<img class="entry_point_icon" alt="" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNjJweCIgaGVpZ2h0PSI2MnB4IiB2aWV3Qm94PSIwIDAgNjIgNjIiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+CiAgICA8dGl0bGU+RW50cnktcG9pbnQtcm91bmRAM3g8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz4KICAgICAgICA8Y2lyY2xlIGlkPSJwYXRoLTEiIGN4PSIyOCIgY3k9IjI4IiByPSIyOCI+PC9jaXJjbGU+CiAgICAgICAgPGZpbHRlciB4PSItOS44JSIgeT0iLTYuMiUiIHdpZHRoPSIxMTkuNiUiIGhlaWdodD0iMTE5LjYlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMiI+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiPjwvZmVPZmZzZXQ+CiAgICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEuNSIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlR2F1c3NpYW5CbHVyPgogICAgICAgICAgICA8ZmVDb2xvck1hdHJpeCB2YWx1ZXM9IjAgMCAwIDAgMC40NjI3NDUwOTggICAwIDAgMCAwIDAuNDYyNzQ1MDk4ICAgMCAwIDAgMCAwLjQ2Mjc0NTA5OCAgMCAwIDAgMC43IDAiIHR5cGU9Im1hdHJpeCIgaW49InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4KICAgICAgICA8L2ZpbHRlcj4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSI1Li0tRW50cnktUG9pbnQiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJ3ZWJfRW50cnlQb2ludC0vY29tcHJlc3NlZCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEzNDkuMDAwMDAwLCAtNTg2LjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0iRW50cnktcG9pbnQtcm91bmQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEzNTIuMDAwMDAwLCA1ODcuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iT3ZhbC1Db3B5LTMiPgogICAgICAgICAgICAgICAgICAgIDx1c2UgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMSIgZmlsdGVyPSJ1cmwoI2ZpbHRlci0yKSIgeGxpbms6aHJlZj0iI3BhdGgtMSI+PC91c2U+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsPSIjMUJCM0JDIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTM1Ljk2NDg0MzcsMTkgTDIwLjAzODQxMTUsMTkgQzE3LjgxMTg0ODksMTkgMTYsMjAuNzgyODk3OSAxNiwyMi45NzQ2NzA0IEwxNiwzMi4wODc4Mjk2IEMxNiwzNC4yNjY3ODQ2IDE3Ljc5MTAxNTYsMzYuMDQxOTkyMiAyMCwzNi4wNjI1IEwyMCwzOS4zNDM3NSBDMjAsMzkuNjA5MDY5OCAyMC4xNjIxMDkzLDM5Ljg0ODc1NDkgMjAuNDExNDU4NCwzOS45NTAwMTIzIEMyMC40OTQxNDA3LDM5Ljk4MzMzNzQgMjAuNTgwNzI5Miw0MCAyMC42NjY2NjY3LDQwIEMyMC44Mzk4NDM3LDQwIDIxLjAxMDQxNjcsMzkuOTMzMzQ5NyAyMS4xMzgwMjA4LDM5LjgwNzczOTIgTDI0Ljk0MjcwODMsMzYuMDYyNSBMMzUuOTYxNTg4NSwzNi4wNjI1IEMzOC4xODgxNTExLDM2LjA2MjUgNDAsMzQuMjc5NjAyMSA0MCwzMi4wODc4Mjk2IEw0MCwyMi45NzIxMDcgQzQwLDIwLjc4MTYxNjIgMzguMTkwMTA0MSwxOSAzNS45NjQ4NDM3LDE5IFogTTM4LjY2NjY2NjcsMzIuMDg3ODI5NiBDMzguNjY2NjY2NywzMy41NTU0MiAzNy40NTMxMjUxLDM0Ljc1IDM1Ljk2MTU4ODUsMzQuNzUgTDI0LjY2NjY2NjcsMzQuNzUgQzI0LjQ4OTU4MzMsMzQuNzUgMjQuMzIwMzEyNSwzNC44MTkyMTM5IDI0LjE5NTMxMjUsMzQuOTQyMjYwOCBMMjEuMzMzMzMzMywzNy43NTk1MjE2IEwyMS4zMzMzMzMzLDM1LjQwNjI1IEMyMS4zMzMzMzMzLDM1LjA0MzUxODEgMjEuMDM1MTU2MywzNC43NSAyMC42NjY2NjY3LDM0Ljc1IEwyMC4wMzg0MTE1LDM0Ljc1IEMxOC41NDY4NzQ5LDM0Ljc1IDE3LjMzMzMzMzMsMzMuNTU1NDIgMTcuMzMzMzMzMywzMi4wODc4Mjk2IEwxNy4zMzMzMzMzLDIyLjk3NDY3MDQgQzE3LjMzMzMzMzMsMjEuNTA3MDggMTguNTQ2ODc0OSwyMC4zMTI1IDIwLjAzODQxMTUsMjAuMzEyNSBMMzUuOTY0ODQzNywyMC4zMTI1IEMzNy40NTQ0MjcxLDIwLjMxMjUgMzguNjY2NjY2NywyMS41MDU3OTg0IDM4LjY2NjY2NjcsMjIuOTcyMTA3IEwzOC42NjY2NjY3LDMyLjA4NzgyOTYgWiIgaWQ9IlNoYXBlLUNvcHktMyIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=" />
</i>
<span class="entry_point_text">Some text to show</span>
</div>
SCSS:
#chatbotEntryPoint {
display: block;
position: fixed;
width: 60px;
height: 60px;
z-index: 1200;
border-radius: 50px;
background-color: purple;
cursor: pointer;
line-height: 1.4;
i {
float: right;
display: block;
.entry_point_icon {
width: 60px;
height: 60px;
}
}
.entry_point_text {
color: #fff;
font-size: 15px;
padding: 20px;
width: 300px;
display: inline-block;
overflow: hidden;
vertical-align: middle;
}
&.reveal_text{
animation: text_expand .3s linear .5s forwards,
text_expand .3s linear 3s reverse forwards;
.entry_point_icon {
animation: reveal .2s linear forwards, reveal_resize .2s linear 1s reverse forwards, reveal_resize .2s linear 3s forwards;
}
}
&.reveal_text_hover{
animation: text_expand .3s linear .5s forwards;
.entry_point_icon {
animation: reveal_resize .2s linear 1s reverse forwards;
}
}
&.reveal_text_leave{
animation: text_expand .3s linear .5s reverse forwards;
.entry_point_icon {
animation: reveal_resize .2s linear 3s forwards;
}
.entry_point_text {
opacity: 1;
}
}
}
#keyframes reveal {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#keyframes text_expand {
0% {
width: 60px;
}
100% {
width: 400px;
}
}
#keyframes reveal_resize {
0% {
transform: scale(0.8);
}
100% {
transform: scale(1);
}
}
JS
var initEntryPoint = function(){
var entryPoint = document.getElementById('chatbotEntryPoint');
entryPoint.classList.add('reveal_text');
entryPoint.addEventListener('mouseenter', function(){
if( entryPoint.classList.contains('reveal_text')){
entryPoint.classList.remove('reveal_text');
} else {
entryPoint.classList.remove('reveal_text_leave');
}
setTimeout(function(){
entryPoint.classList.add('reveal_text_hover');
},10);
});
entryPoint.addEventListener('mouseleave', function(){
setTimeout(function(){
entryPoint.classList.remove('reveal_text_hover');
entryPoint.classList.add('reveal_text_leave');
}, 3000);
});
};
setTimeout(function(){
initEntryPoint();
}, 1000);
If anyone has any clue about how to make the text collapse again smoothly, and when hover again redo all this, I would really apreciate it.
Thank you so much for your time.

Related

Keyframe animation :hover doesn't obey the "ease-out" part of the animation on mouse-out

I have a 3 chevron animation sequence set up for a back button I designed. The animation triggers on hover exactly the way I want it to but it doesn't respect the ease-out part of the animation property when I hover off of the button. I know that typically with CSS animations you fix this by putting the animation on the actual element and not the :hover state but the problem with that is that the keyframe animation triggers on page load and gets a little wonky on :hover. Is there a mouse-out or hover-out-like state that I could use so that when the user moves away from the button the animation eases out or even reverses? I tried adding animation-direction: reverse; property to the base elements but that doesn't do anything, probably because it doesn't know what animation I'm referring to because it's not present in the base elements for the reasons above. Do I possibly need some CSS or javascript to prevent the animation from triggering until the :hover state actually occurs and then I could place the animation in the base elements instead of the :hover state?
https://jsfiddle.net/astombaugh/L7k1r63f/54/
<body style="background-color: #214365">
<div class="backBtn">
<div class="chevronContainer">
<div class="backBtnChevronTop"></div>
<div class="backBtnChevronMid"></div>
<div class="backBtnChevronFar"></div>
</div>
Back
</div>
</body>
#import url('https://fonts.googleapis.com/css2?family=Oswald:wght#700&display=swap');
.backBtn {
font-family: Oswald, Univers, Helvetica Neue, Helvetica, Arial;
display: inline-block;
position: absolute;
left: 4rem;
font-weight: 700;
width: auto;
height: auto;
color: white;
background-color: transparent;
padding: 0.2rem 0em 0.1rem 0em;
margin: 0rem 0rem 0rem 0rem;
text-align: center;
text-decoration: none;
font-size: 1.6em;
word-spacing: normal;
cursor: pointer;
}
.chevronContainer {
display: inline-block;
position: relative;
transform: translateY(-1.3rem) translateX(-1rem);
}
.backBtnChevronTop {
content: url(https://i.imgur.com/YHZi17i.png);
filter: invert(1);
position: absolute;
opacity: 1;
height: 1.33rem;
width: 1.33rem;
}
.backBtnChevronMid {
content: url(https://i.imgur.com/YHZi17i.png);
filter: invert(1);
position: absolute;
opacity: 0;
height: 1.33rem;
width: 1.33rem;
animation-direction: reverse;
}
.backBtnChevronFar {
content: url(https://i.imgur.com/YHZi17i.png);
filter: invert(1);
position: absolute;
opacity: 0;
height: 1.33rem;
width: 1.33rem;
animation-direction: reverse;
}
.backBtn:hover .backBtnChevronMid {
animation: animateChevronMid 0.6s ease-in-out;
animation-fill-mode: forwards;
}
.backBtn:hover .backBtnChevronFar {
animation: animateChevronFar 0.6s ease-in-out;
animation-fill-mode: forwards;
}
#keyframes animateChevronTop {
0% {
transform: translateX(0rem);
opacity: 0;
}
70%,
100% {
transform: translateX(0);
opacity: 1;
}
}
#keyframes animateChevronMid {
0% {
transform: translateX(0);
opacity: 0;
}
70%,
100% {
transform: translateX(-0.7rem);
opacity: 1;
}
}
#keyframes animateChevronFar {
0% {
transform: translateX(0);
opacity: 0;
}
70%,
100% {
transform: translateX(-1.4rem);
opacity: 1;
}
}
You can probably resolve this by adding the transition on element when there is no hover at the moment and tweak a little the keyframes. Like this:
.backBtn .backBtnChevronMid {
animation: animateChevronMid2 0.6s ease-in-out;
animation-fill-mode: forwards;
}
.backBtn .backBtnChevronFar {
animation: animateChevronFar2 0.6s ease-in-out;
animation-fill-mode: forwards;
}
#keyframes animateChevronMid2 {
0% {
transform: translateX(-0.7rem);
opacity: 1;
}
70%,
100% {
transform: translateX(0);
opacity: 0;
}
}
#keyframes animateChevronFar2 {
0% {
transform: translateX(-1.4rem);
opacity: 1;
}
70%,
100% {
transform: translateX(0);
opacity: 0;
}
}
this additional keyframes are exact opposite of the keyframes that you have done. And they do apply when you move your cursor from the element (so on hover off so to speak).
Jacck is right and beat me to it.
You can use that, and add a fadeIn transition to the back button itself. It's hacky but put this on the back button:
animation: fadeIn 0.6s ease-in-out;
And tweak the animation accordingly. It'll run once. If you don't want a fade just move the "stop" close to the end and this controls the container that holds the other animations so your whole effect won't show until it has loaded:
#keyframes fadeIn {
0% {opacity:0;}
95% {opacity: 0}
100% {opacity:1;}
}

Why does my div only animate when i add an attribute of isopen=true but not when i change the value to false

When I click on a button I want my div to animate. It seems only the show animation is working, but not the hide. The hide animation doesn't work at all even though the attribute values change.
$("#divShow").click(function() {
$('.parent').attr('isopen', 'true');
});
$("#divHide").click(function() {
$('.parent').attr('isopen', 'false');
});
.parent {
display: none; //hidden by default
width: 40px;
height: 40px;
background: blue;
}
#keyframes show {
50% {
transform: scale(1.03);
}
}
#keyframes hide {
50% {
transform: scale(0.97);
}
100% {
opacity: 0;
transform: scale(0.90);
}
}
[isopen="true"] {
display: block;
-webkit-animation: show .3s;
-moz-animation: show .3s;
-ms-animation: show .3s;
animation: show .3s;
}
[isopen="false"] {
-webkit-animation: hide .3s;
-moz-animation: hide .3s;
-ms-animation: hide .3s;
animation: hide .3s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="divShow">Show</button>
<button id="divHide">Hide</button>
<div class="parent">
</div>
I think I got it working as you wanted. See here code snippet below.
Your show class has display block but when you remove it it gets right back to none. Just add the display none at the end of your hide animation.
Like this:
#keyframes hide {
50% {
transform: scale(0.97);
}
100% {
opacity: 0;
transform: scale(0.90);
display: none;
}
}
[isopen="false"] {
display: block;
animation: hide .3s forwards;
}
Code snippet:
$("#divShow").click(function() {
$('.parent').attr('isopen', 'true');
});
$("#divHide").click(function() {
$('.parent').attr('isopen', 'false');
});
.parent {
display: none; //hidden by default
width: 40px;
height: 40px;
background: blue;
}
#keyframes show {
50% {
transform: scale(1.03);
}
}
#keyframes hide {
50% {
transform: scale(0.97);
}
100% {
opacity: 0;
transform: scale(0.90);
display: none;
}
}
[isopen="true"] {
display: block;
-webkit-animation: show .3s;
-moz-animation: show .3s;
-ms-animation: show .3s;
animation: show .3s;
}
[isopen="false"] {
display: block;
-webkit-animation: hide .3s forwards;
-moz-animation: hide .3s forwards;
-ms-animation: hide .3s forwards;
animation: hide .3s forwards;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="divShow">Show</button>
<button id="divHide">Hide</button>
<div class="parent">
</div>
With the help of this answer: https://stackoverflow.com/a/15407098/2181514
you can add forwards to your animations so that they keep the last (100%) keyframe.
Add display:block to [isopen=false] to ensure it doesn't hide immediately then:
animation: hide .3s forwards;
Updated snippet:
$("#divShow").click(function() {
$('.parent').attr('isopen', 'true');
});
$("#divHide").click(function() {
$('.parent').attr('isopen', 'false');
});
.parent {
display: none;
width: 40px;
height: 40px;
background: blue;
}
#keyframes show {
50% {
transform: scale(1.03);
}
}
#keyframes hide {
50% {
transform: scale(0.97);
}
100% {
opacity: 0;
transform: scale(0.90);
}
}
[isopen="true"] {
display: block;
-webkit-animation: show .3s;
-moz-animation: show .3s;
-ms-animation: show .3s;
animation: show .3s;
}
[isopen="false"] {
display: block;
-webkit-animation: hide .3s forwards;
-moz-animation: hide .3s forwards;
-ms-animation: hide .3s forwards;
animation: hide .3s forwards;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="divShow">Show</button>
<button id="divHide">Hide</button>
<div class="parent">
</div>
Can be done simply, efficiently with less line of code using transition
$("#divShow").click(function() {
$('.parent').addClass('show');
});
$("#divHide").click(function() {
$('.parent').removeClass('show');
});
.parent {
width: 40px;
height: 40px;background: blue;
transform: scale(0.97);
transition: all 0.3s;
opacity:0;
}
.show {
opacity:1;
transform: scale(1.03);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="divShow">Show</button>
<button id="divHide">Hide</button>
<div class="parent">
</div>

Getting Top/Right values ​from a css-animated element

I'm trying to get the Top and Right values from an element being rotated by a CSS animation, for this I am using the following code:
HTML:
<div id="ball1"> </div>
CSS:
#keyframes spin {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
#ball1 {
transform-origin: center right;
animation: spin 2.5s linear 0s infinite forwards;
position: relative;
background-color: #7883f7;
width: 10;
height: 10;
border-radius: 10px;
}
Javascript:
console.log(window.getComputedStyle(document.getElementById("ball1"), null).top);
console.log(window.getComputedStyle(document.getElementById("ball1"), null).right);
However it returns a value of 0px, I wanted to get the value from Right and Top as if I was manually setting them (and not by the transform animation).
If this is not possible, is there a way to simulate a "circle" rotation and return the right/top values without using the transform?
ie:
https://66.media.tumblr.com/fb22b61bcbca3785a515e86c2276451b/tumblr_inline_pmimnjEvbK1v6q8wn_1280.gif?fbclid=IwAR2zjgE0hfB8emWOg0f6TOcQb8DWGbEvu9IQOr92fMq4HmMKjiAQRQzLmI0
Use getBoundingClientRect():
const ball = document.getElementById("ball");
setInterval(() => {
const rect = ball.getBoundingClientRect();
console.log(rect.top, rect.right);
}, 300);
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#ball {
transform-origin: center right;
animation: spin 2.5s linear 0s infinite forwards;
position: relative;
background-color: #7883f7;
width: 10px;
height: 10px;
border-radius: 10px;
}
<div id="ball"></div>
Here is an approximation using top/left. The trick is to animate each property individually alternating the ease function to simulate the circular path:
.box {
width:100px;
height:100px;
position:relative;
}
#ball1 {
animation:
Atop 2.5s infinite,
Aleft 2.5s infinite;
position: absolute;
background-color: #7883f7;
width: 10px;
height: 10px;
border-radius: 10px;
}
#keyframes Atop {
0%,50%,100% {
top:50%;
animation-timing-function: ease-out;
}
25% {
top:0%;
animation-timing-function: ease-in;
}
75% {
top:100%;
animation-timing-function: ease-in;
}
}
#keyframes Aleft {
0%,100% {
left:0;
animation-timing-function: ease-in;
}
25%,75% {
left:50%;
animation-timing-function: ease-out;
}
50% {
left:100%;
animation-timing-function: ease-in;
}
}
<div class="box">
<div id="ball1"> </div>
</div>

How to apply a hover effect on an element which has already been handled by an forward animation?

I have a text and block in an animation of an SVG element.
Here in my example i simplified everything.
I want to have one initial animation and afterwards a hover animation on the block element. The initial animation is fine as it is. (use chrome to have equals measurements). But after the initial animation the user should be able to hover the block and the block itself should resize (which is also working already) and the text should get an opacity of 1. But this won't work since the opacity is already set by the keyframe animation.
Any suggestions on how to work around on this one?
I don't mind if i use JS or CSS or any frameworks. I don't rely on CSS animations. Just used them because i thought i'd be cleaner.
Important Edit: I forgot a simple but very important thing. Before the animation there are some other animations on different elements. So i have a delay of let's say 2 seconds. Before the animation starts, the opacity should be 0 so the text is not visible until the animation starts. Sorry, forgot about that!
.text{
font-weight: bold;
opacity: 0;
transition: all .8s;
animation: showText 3s ease-in-out forwards;
animation-delay: 2s;
}
.text:hover{
opacity: 1;
transition: all .8s;
}
.block{
top: 50px;
left: 50px;
position: absolute;
height: 20px;
width: 20px;
background-color: red;
transition: all .8s;
animation: popup 3s ease-in-out;
animation-delay: 2s;
}
.block:hover{
transform: scale(2);
transition: all .8s;
}
#keyframes showText {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0.3;
}
}
#keyframes popup {
0% {
transform: scale(1);
}
50% {
transform: scale(2);
}
100% {
transform: scale(1);
}
}
<div class='text'>
Foo Bar!
</div>
<div class='block'>
</div>
codepen.io link (same code as above): https://codepen.io/jdickel/pen/xJbQrY
Instead of a forwards animation, you can simply set the initial opacity to 0.3.
EDIT:
I'm fairly confident that forwards animation styles can't be easily overridden (though I'm unable to find it in documentation for some reason), so you could do similarly to what was originally suggested and just extend the time of the animation like so:
.text{
font-weight: bold;
/* Start out at 0.3 */
opacity: 0.3;
transition: all .8s;
/* 2s + 3s = 5s */
animation: showText 5s ease-in-out; /* no forwards */
}
.text:hover{
opacity: 1;
transition: all .8s;
}
.block{
top: 50px;
left: 50px;
position: absolute;
height: 20px;
width: 20px;
background-color: red;
transition: all .8s;
animation: popup 3s ease-in-out;
}
.block:hover{
transform: scale(2);
transition: all .8s;
}
#keyframes showText {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
/* Note the new animation keyframe locations */
70% {
opacity: 1;
}
100% {
opacity: 0.3;
}
}
#keyframes popup {
0% {
transform: scale(1);
}
50% {
transform: scale(2);
}
100% {
transform: scale(1);
}
}
<div class='text'>
Foo Bar!
</div>
<div class='block'>
</div>
First, you need to remove forwards from the .text animation. You can use Javascript's mouseenter and mouseleave events to set the text's opacity when .block is hovered over.
.text{
font-weight: bold;
opacity: 0;
transition: all .8s;
animation: showText 3s ease-in-out;
animation-delay: 2s;
}
.text:hover{
opacity: 1;
transition: all .8s;
}
.block{
top: 50px;
left: 50px;
position: absolute;
height: 20px;
width: 20px;
background-color: red;
transition: all .8s;
animation: popup 3s ease-in-out;
animation-delay: 2s;
}
.block:hover{
transform: scale(2);
transition: all .8s;
}
#keyframes showText {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0.3;
}
}
#keyframes popup {
0% {
transform: scale(1);
}
50% {
transform: scale(2);
}
100% {
transform: scale(1);
}
}
<div class='text' id="text" onmouseenter="function1()" onmouseleave="function2()">
Foo Bar!
</div>
<div class='block' onmouseenter="function1()" onmouseleave="function2()">
</div>
<script>
setTimeout(function(){
document.getElementById("text").style.opacity = "0.3";
}, 3000)
function function1(){
document.getElementById("text").style.opacity = "1";
}
function function2(){
document.getElementById("text").style.opacity = "0.3";
}
</script>

How to have an element fade out and another element fade in in its place on window load?

I am trying to create a splash screen for my website and I have made a progress bar to make it look nicer. I also have some links for the user to login or register.
What I want to achieve is, right after the window loads, have the progress bar do its thing for 4 seconds then have it fade out in .5 seconds and then have the links fade in in its place in .5s for a total of 5 seconds before the user can proceed.
I have put together some code to make this work using mainly:
setTimeout();
but despite having no errors as far as both I and the Google Chrome console can tell, no visible result is produced.
How can I fix my code to work properly? Any suggestions would be greatly appreciated. I would prefer a solution in plain JavaScript, but if there's no other way, I would be satisfied with a jQuery one too.
To help you, I have assembled a demo for you here.
No doubt to switch to jquery. FadeIn and fadeOut do it easily:
$(window).load(function(){
var t=setTimeout(function(){
$("#progressbar").fadeOut(500);
$("#splashscreen-links").fadeIn(500);
},4000)
})
#-webkit-keyframes greenglow {
from {
left:-120px;
}
to {
left:100%;
}
}
#-moz-keyframes greenglow {
from {
left: -120px;
}
to {
left: 100%;
}
}
#-ms-keyframes greenglow {
from {
left: -120px;
}
to {
left: 100%;
}
}
#-o-keyframes greenglow {
from {
left: -120px;
}
to {
left: 100%;
}
}
#keyframes greenglow {
from {
left: -120px;
}
to {
left: 100%;
}
}
#progressbar {
/* Dimensions */
width: 250px;
height: 16px;
overflow: hidden;
/* Positioning */
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
margin: 5px;
padding-top: 4px;
padding-left: 17px;
/* Styling */
background: #E6E6E6;
border:1px solid #bbb;
border-radius:0px;
}
#progressbar:after {
content: " ";
display: block;
width: 120px;
top: -50%;
height: 250%;
position: absolute;
animation: greenglow 2s linear infinite;
-webkit-animation: greenglow 2s linear infinite;
z-index: 2;
background: #1CAE30;
}
#splashscreen-links {
/* Text */
color: #999999;
font-family: "Arial";
text-decoration: none;
/* Positioning */
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
margin: 5px;
padding-top: 4px;
padding-left: 17px;
/* Visibility */
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="progressbar"></div>
<p id = "splashscreen-links"><a>Login</a> • <a>Register</a></p>
You are already using CSS animations. Just keep going down that path!
#keyframes progresshide {
0% {opacity: 1; display:block; }
80% { opacity: 1; }
100% { opacity: 0; display:none; }
}
#keyframes linksshow {
0% {opacity: 0; }
80% { opacity: 0; }
100% { opacity: 1; }
}
#progressbar {
animation: progresshide 5s linear forwards;
}
#splashscreen-links {
animation: linksshow 5s linear forwards;
}
https://jsfiddle.net/bcwtz8rr/3/
In the case that you'd rather go JS than JQuery, it is still possible using .className to switch the class, setting up classes with transitions of the .5s you mentioned, and using setTimeout appropriately.
First, we start by introducing another two rather simple classes:
.showObject {
transition: all .5s ease-in-out;
-o-transition: all .5s ease-in-out;
-ms-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
-webkit-transition: all .5s ease-in-out;
opacity: 1;
}
.hideObject {
transition: all .5s ease-in-out;
-o-transition: all .5s ease-in-out;
-ms-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
-webkit-transition: all .5s ease-in-out;
opacity: 0;
}
Then, JS with appropriate setTimeout usage:
window.onload = function SwitchProgress() {
// Declaration
'use strict';
// Fade in
document.getElementById('progressbar').setAttribute('style', 'display: block;');
document.getElementById('progressbar').className = 'showObject';
// Waiting 4s for bar animation, then fading it out
setTimeout(function () {
document.getElementById('progressbar').className = 'HideObject';
// .5s while the bar fades out, removing bar, displaying links
setTimeout(function () {
document.getElementById('progressbar').setAttribute('style', 'display: none;');
document.getElementById('splashscreen-links').setAttribute('style', 'display: block;');
// .01s for display change, links fade in
setTimeout(function () {
document.getElementById('splashscreen-links').className = 'showObject';
}, 10);
}, 990);
}, 4000);
};
Just wanted to note: I got this to work on Codecademy (codebits), which refreshes the file every time you make a change. JSFiddle didn't work as well. Should be fine for usage on a page that's actually going to experience proper onload execution.

Categories