I am currently using some Javascript to hide and show a certain div on button click.
I want the transition to be smooth, and not so jumpy. Ideally i would like to add a little bounce effect.
Any ideas on how to achieve this?
var button = document.querySelector(".button1");
button.addEventListener("click", function() {
var content = document.querySelector(".second");
content.style.display = (content.style.display === "none") ? "block" : "none";
});
.container {
display: flex;
align-items: center;
justify-content: space-around;
width: 100%; background: red;
}
.second {
display: none;
}
<div class="container">
<div class="first">
<p> Hello world</p>
</div>
<div class="second">
<p> Goodbye World</p>
</div>
</div>
<button class="button1" >Apply</button>
One of a million equally beautiful options! )))
var first = document.querySelector(".first");
var second = document.querySelector(".second");
var rectSecond = second.getBoundingClientRect();
first.style.width = `${rectSecond.width}px`;
btn.addEventListener("click", () => {
first.classList.toggle("animateFirst");
second.classList.toggle("animateSecond");
});
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100%;
height: 3rem;
background: red;
position: relative;
}
.container div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.first {
background: red;
text-align: center;
}
.animateFirst {
animation: move1 0.8s ease-out forwards;
}
#keyframes move1 {
from {
left: 50%;
}
50% {
left: 10%;
}
75% {
left: 16%;
}
to {
left: 12%;
}
}
.animateSecond {
animation: move2 0.8s ease-out forwards;
}
#keyframes move2 {
from {
left: 50%;
}
50% {
left: 82%;
}
75% {
left: 76%;
}
to {
left: 80%;
}
}
</style>
<div class="container">
<div class="second">
<p>Goodbye World</p>
</div>
<div class="first">
<p>Hello world</p>
</div>
</div>
<button class="button1" id="btn">Apply</button>
To make CSS transition to make the transition smooth and add a bounce effect. You need to some changes to your code then you can make it very easily. Here you go -
.second {
display: none;
transition: all 0.3s ease-in-out;
}
#keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-30px);
}
60% {
transform: translateY(-15px);
}
}
.second.bouncing {
animation: bounce 0.5s;
}
Please add a class bouncing to the .second div in your JavaScript code.
var button = document.querySelector(".button1");
button.addEventListener("click", function() {
var content = document.querySelector(".second");
content.style.display = (content.style.display === "none") ? "block" : "none";
content.classList.toggle("bouncing");
});
I hope this will make the transition smooth, and the div will have a bouncing effect when it's displayed. Thank you
You cannot add animation from hidden state.
You need to first add element in layout.
var button = document.querySelector(".button1");
var content = document.querySelector(".second");
button.addEventListener("click", function () {
content.hidden = !content.hidden
});
.container {
display: flex;
align-items: center;
justify-content: space-around;
width: 100%;
background: red;
}
.second {
transform-origin: center bottom;
animation: bounce 1000ms ease-out forwards;
}
#keyframes bounce {
from,
20%,
53%,
to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
transform: translate3d(0, 0, 0);
}
40%,
43% {
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
transform: translate3d(0, -30px, 0) scaleY(1.1);
}
70% {
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
transform: translate3d(0, -15px, 0) scaleY(1.05);
}
80% {
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
transform: translate3d(0, 0, 0) scaleY(0.95);
}
90% {
transform: translate3d(0, -4px, 0) scaleY(1.02);
}
}
<div class="container">
<div class="first">
<p> Hello world</p>
</div>
<div class="second" hidden>
<p> Goodbye World</p>
</div>
</div>
<button class="button1">Apply</button>
Related
I was trying to build a auto sliding bar from right to left with an array of data in Angular. Currrently, the animation wasn't working until user click on it. I tried changedetectorref, setTimeout() and trigger click event manually, but nothing work. Please help me on solving this.
The observation is that the data fetched from backend are received and shown (this.offer has its correct value) but the animation is paused. After several seconds, the shown data disappears by itself. When user click the blank sliding bar, the function of clicking on a data triggers and the animation starts. Please let me know if any further information is required.
HTML Part
<div class="ticker-wrap bg-black">
<div class="ticker py-2.5" id="bar-part-1">
<a class="ticker__item" [id]="'talent-' + o.uniqueCode" [href]="'/talent/' + o.uniqueCode" (click)="openTalentDetailDialog(o.uniqueCode)"
*ngFor="let o of offers">
<div class="flex-col content">
<strong>{{o.uniqueCode}}</strong>
</div>
</a>
</div>
<div class="ticker py-2.5" id="bar-part-2">
<a class="ticker__item" [href]="'/talent/' + o.uniqueCode" (click)="openTalentDetailDialog(o.uniqueCode)"
*ngFor="let o of offers">
<div class="flex-col content">
<strong>{{o.uniqueCode}}</strong>
</div>
</a>
</div>
</div>
CSS Part
$duration: 40s;
#-webkit-keyframes ticker {
0% {
-webkit-transform: translate3d(0%, 0, 0);
transform: translate3d(0%, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
#keyframes ticker {
0% {
-webkit-transform: translate3d(0%, 0, 0);
transform: translate3d(0%, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
.ticker-wrap {
// position: fixed;
z-index: 100;
// bottom: 0;
width: 100%;
overflow: hidden;
// height: 4rem;
// padding-left: 100%;
box-sizing: content-box;
white-space: nowrap;
min-height: 64px;
.ticker {
// display: inline-block;
display: inline-flex;
// height: 4rem;
// line-height: 4rem;
// white-space: nowrap;
// padding-right: 100%;
box-sizing: content-box;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-name: ticker;
animation-name: ticker;
-webkit-animation-duration: $duration;
animation-duration: $duration;
&__item {
display: inline-block;
padding: 0 2rem;
// font-size: 2rem;
color: white;
cursor: pointer;
.content {
max-width: 450px;
min-width: 450px;
white-space: pre-wrap;
}
&:hover {
text-decoration: underline;
}
}
}
&:hover {
.ticker {
animation-play-state: paused;
}
}
}
TypeScript part
loadRecentOffers() {
console.log('loadRecentOffer is triggered');
this._businessService.getRecentOffers().subscribe(async o => {
console.log('recent offers: ', o);
await Promise.all(o.map(oo => {
oo.time = moment(new Date(oo.createdAt)).fromNow();
}));
this.offers = o;
// this._matSnackBar.open('offer applied', 'Close');
setTimeout(() => {
this._cdr.markForCheck();
this._cdr.detectChanges();
// this._matSnackBar.open('cdr triggered', 'Close');
}, 100)
})
}
i have set animation in property on HTML element when it is displayed, i want same animation on reverse, when button is clicked it should hide with same animation.
how can i achieve that.
"Animation in" which is working:
.modal{
animation: myAnim 1s ease 0s 1 normal forwards;
}
#keyframes myAnim {
0% {
opacity: 0;
transform: translateX(-50px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
HTML:
<div id="myModal" class="modal fixed hidden z-1 w-full h-full bg-red-100 h-screen ">
<button id="myBtn" class=" p-2 bg-yellow-400 rounded m-4 absolute right-0 text-xs font-bold ">
HIDE/SHOW..
</button>
i am showing/hidding modal using JS. how can i hide modal with same animation.
Create two classes, one for making the modal appear and another for making it disappear,
Class for appearing
.modal-appr{
animation: appr 1s ease 0s 1 normal forwards;
}
#keyframes appr {
0% {
opacity: 0;
transform: translateX(-50px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
Class to make the modal disappear
.modal-disappr{
animation: disappr 1s ease 0s 1 normal forwards;
}
#keyframes disappr {
0% {
opacity: 1;
transform: translateX(0);
}
100% {
opacity: 0;
transform: translateX(-50px);
}
}
now just use Javascript to add this classes to the modal's classlist when the button toggles
const btn = document.querySelector('mybtn');
const modal = document.querySelector('#myModal');
btn.addEventListener ('click', function toggleClass () {
if(modal.classList.contains('appr')) {
modal.classList.add('disappr');
modal.classList.remove('appr');
} else {
modal.classList.add('appr');
modal.classList.remove('disappr');
}
})
You can achieve this by using toggle class and transition instead.
let btn = document.getElementById('model_btn');
let model = document.getElementById('model');
btn.addEventListener('click', function(){
model.classList.toggle('show');
})
/* Styling the markup */
#model{
width: 200px;
height: 100px;
background-color: yellow;
padding: 20px;
margin-bottom: 20px;
}
#model_btn{
border: none;
background-color: green;
padding: 10px;
color: white;
cursor: pointer;
}
/* Showing and hiding animation with transition */
#model{
position: relative;
visibility: none;
opacity: 0;
top: 0;
left: 0;
transform: translateX(-50px);
transition: all 1s ease;
}
#model.show{
visibility: visible;
opacity: 1;
transform: translateX(0px);
}
<div id="model">
Content
</div>
<button id="model_btn">Show/Hide Model</button>
Animation / Key-frame approach.
let btn = document.getElementById('model_btn');
let model = document.getElementById('model');
btn.addEventListener('click', function(){
model.classList.toggle('show');
})
/* Styling the markup */
#model{
width: 200px;
height: 100px;
background-color: yellow;
padding: 20px;
margin-bottom: 20px;
visibility: none;
opacity: 0;
transform: translateX(-50px);
}
#model_btn{
border: none;
background-color: green;
padding: 10px;
color: white;
cursor: pointer;
}
.show{
animation: myAnim 1s ease 0s 1 normal forwards;
}
#keyframes myAnim {
0% {
visibility: none;
opacity: 0;
transform: translateX(-50px);
}
100% {
visibility: visible;
opacity: 1;
transform: translateX(0);
}
}
<div id="model">
Content
</div>
<button id="model_btn">Show/Hide Model</button>
So,here i have a text animation on my page.The problem is that the animation is triggered only when the full page is loaded!so,I have this animation on the middle of my page it is almost impossible to see that it is a animated text! NEED SOLUTION please!
HTML CODE:
<div class="animated-title" id="anime" >
<div class="text-top">
<div>
<span>So! What Are You </span>
<span>Waiting For?</span>
</div>
</div>
<div class="text-bottom">
<div>Just click And LEARN!</div>
</div>
</div>
CSS CODE:
.animated-title {
color: #222;
font-family: Roboto, Arial, sans-serif;
height: 90vmin;
left: 30%;
position: absolute;
top: 156%;
transform: translate(-50%, -50%);
width: 90vmin;
}
.animated-title > div {
height: 50%;
overflow: hidden;
position: absolute;
width: 100%;
}
.animated-title > div div {
font-size: 9vmin;
padding: 3vmin 0;
position: absolute;
}
.animated-title > div div span {
display: block;
}
.animated-title > div.text-top {
border-bottom: 1.4vmin solid rgb(13, 231, 13);
top: 0;
border-radius: 20px;
}
.animated-title > div.text-top div {
animation: showTopText 1s;
animation-delay: 7s;
animation-fill-mode: forwards;
bottom: 0;
transform: translate(0, 100%);
}
.animated-title > div.text-top div span:first-child {
color: #767676;
}
.animated-title > div.text-bottom {
bottom: 0;
}
.animated-title > div.text-bottom div {
animation: showBottomText 1s;
animation-delay: 5s;
animation-fill-mode: forwards;
top: 0;
transform: translate(0, -100%);
}
Key frames:
0% { transform: translate3d(0, 100%, 0); }
40%, 60% { transform: translate3d(0, 50%, 0); }
100% { transform: translate3d(0, 0, 0); }
}
#keyframes showBottomText {
0% { transform: translate3d(0, -100%, 0); }
100% { transform: translate3d(0, 0, 0); }
}
I think I understand what your problem is.
As long as you do not have a problem with including a library in your code, you can do it this way:
https://www.youtube.com/watch?v=XtjO-OWFyfU
By the way, there are many tutorials on internet. You just need to search.
I want to show an animation of drawing an angled and straight line and to show my text from left to right when hovering over a button and I am fairly new at this. also is there a way for my text to stay and not go away after animation finishes?
Here is my code, the code is a combination of other answers from stack overflow.
.skew {
position: relative;
margin: 100px;
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(-45deg);
animation: draw 0.5s linear;
animation-fill-mode: forwards;
}
.line {
position: absolute;
left: 100%;
top: 0;
content: '';
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(45deg);
animation: drawLine 0.7s linear;
animation-delay: 0.5s;
animation-fill-mode: forwards;
}
.showText {
animation: showText 2s;
position: relative;
top: -17px;
left: 15px;
opacity: 0;
}
#keyframes showText {
0% {
opacity: 0;
transform: translateX(-20px);
}
50% {
opacity: 0;
}
100% {
opacity: 1;
transform: translateX(0);
}
}
#keyframes draw {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
#keyframes drawLine {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
<div>
<button class="menubtn">hover over me</button>
</div>
<div class="skew">
<div class="line">
<div class="showText">menu item</div>
</div>
</div>
You need to add/toggle a class on the div.skew element with Javascript, and define animation rules on that class or children of elements with that class, like so:
var button = document.querySelector("button.menubtn"); //Select the button
var skewElement = document.querySelector("div.skew"); //Select the 'skew' element
button.onmouseover = function(){
skewElement.classList.toggle("startAnimation");
}
.skew {
position: relative;
margin: 100px;
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(-45deg);
}
.skew.startAnimation {
animation: draw 0.5s linear;
animation-fill-mode: forwards;
}
.line {
position: absolute;
left: 100%;
top: 0;
content: '';
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(45deg);
}
.startAnimation .line {
animation: drawLine 0.7s linear;
animation-delay: 0.5s;
animation-fill-mode: forwards;
}
.showText {
opacity: 0;
position: relative;
top: -17px;
left: 15px;
}
.startAnimation .showText {
animation: showText 2s;
animation-fill-mode: forwards;
}
#keyframes showText {
0% {
opacity: 0;
transform: translateX(-20px);
}
50% {
opacity: 0;
}
100% {
opacity: 1;
transform: translateX(0);
}
}
#keyframes draw {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
#keyframes drawLine {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
<div>
<button class="menubtn">hover over me</button>
</div>
<div class="skew">
<div class="line">
<div class="showText">menu item</div>
</div>
</div>
In order to have the text visible even after animation's end, you have to specify animation-fill-mode: forwards on .showText, like I have done in the snippet above.
To get the animation done on hovering, first we have to create an event for hovering for that particular element using javascript
Then call a function when that event is triggered , for you it will be displaying some animations
Just for simplicity , i just made a parent div for your entire animation elements , and not displaying initially
Later on hovering , we change the css display property of that parent element to block which will display all of your animated elements
Also to make sure your text stays after animation , there is an animation property called forwards which will keep your final animation state for the later time
var hvrbtn=document.getElementById("hvrbtn");
hvrbtn.onmouseover=()=>{
var anim=document.getElementById("anim");
anim.style.display="block";
};
.animated{
display:none;
}
.skew {
position: relative;
margin: 100px;
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(-45deg);
animation: draw 0.5s linear;
animation-fill-mode: forwards;
}
.line {
position: absolute;
left: 100%;
top: 0;
content: '';
width: 0;
height: 2px;
background: #f00;
transform-origin: 0 100%;
transform: rotate(45deg);
animation: drawLine 0.7s linear;
animation-delay: 0.5s;
animation-fill-mode: forwards;
}
.showText {
animation: showText 2s forwards;
position: relative;
top: -17px;
left: 15px;
opacity: 0;
}
#keyframes showText {
0% {
opacity: 0;
transform: translateX(-20px);
}
50% {
opacity: 0;
}
100% {
opacity: 1;
transform: translateX(0);
}
}
#keyframes draw {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
#keyframes drawLine {
0% {
width: 0px;
}
100% {
width: 100px;
}
}
<div>
<button class="menubtn" id="hvrbtn">hover over me</button>
</div>
<div class="animated" id="anim">
<div class="skew">
<div class="line">
<div class="showText">menu item</div>
</div>
</div>
<div>
I'm trying to center something horizontally and vertically using flexbox as described Here ( click "Both Horizontally and Vertically" => then click "Can you use flexbox?")
.parent_test {
display: flex;
justify-content: center;
align-items: center;
}
.sk-double-bounce {
width: 40px;
height: 40px;
position: relative;
}
.sk-double-bounce .sk-child {
width: 100%;
height: 100%;
border-radius: 20%;
background-color: green;
position: absolute;
top: 0;
left: 0;
-webkit-animation: sk-doubleBounce 2s infinite ease-in-out;
animation: sk-doubleBounce 2s infinite ease-in-out; }
.sk-double-bounce .sk-double-bounce2 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s; }
#-webkit-keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
#keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0); }
50% {
-webkit-transform: scale(1);
transform: scale(1); } }
<h1>centering-css-complete-guide/#both-flexbox
<div class="parent_test">
<div class="sk-double-bounce">
<div class="sk-child sk-double-bounce1"></div>
<div class="sk-child sk-double-bounce2"></div>
</div>
</div>
But why isn't it centering vertically? JSBin
you need to specify a height for parent, in order to make it vertically aligned.
body {
margin: 0
}
.parent_test {
display: flex;
justify-content: center;
align-items: center;
height: 100vh
}
.sk-double-bounce {
width: 40px;
height: 40px;
position: relative;
}
.sk-double-bounce .sk-child {
width: 100%;
height: 100%;
border-radius: 20%;
background-color: green;
position: absolute;
top: 0;
left: 0;
-webkit-animation: sk-doubleBounce 2s infinite ease-in-out;
animation: sk-doubleBounce 2s infinite ease-in-out;
}
.sk-double-bounce .sk-double-bounce2 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
#-webkit-keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0);
}
50% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
#keyframes sk-doubleBounce {
0%, 100% {
-webkit-transform: scale(0);
transform: scale(0);
}
50% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
<div class="parent_test">
<div class="sk-double-bounce">
<div class="sk-child sk-double-bounce1"></div>
<div class="sk-child sk-double-bounce2"></div>
</div>
</div>
If you inspect the output, you'll see .sk-double-bounce is actually centered within .parent_test. The problem is that .parent_test has way lesser height. ( It only takes the amount of height required by it's content plus padding and border values).
You can now understand why the solution by #dippas works. If you want, you could remove the .parent_test wrapper, put flex rules in body, set body's height to 100vh and then put .sk-double-bounce div directly inside body. That would do the same job.