Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a red box as the element to animate.
Here is a simple representation of how I want to animate the red box.
Here is a try but as you see the anchor point of the movement is at the left of the box no the center as I wish to be:
.yo-yo {
display: block;
position: absolute;
height: 50px;
width: 200px;
background: red;
transform-origin: 50% 50%;
animation: yo-yo 0.5s infinite alternate; /* Animation speed and type */
}
/* Animation beginning and ending */
#keyframes yo-yo {
from { left: 0 }
to { left: 20px }
}
<span class="yo-yo"></span>
Here is the script tag of that specific version of TweenMax:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js" integrity="sha512-DkPsH9LzNzZaZjCszwKrooKwgjArJDiEjA5tTgr3YX4E6TYv93ICS8T41yFHJnnSmGpnf0Mvb5NhScYbwvhn2w==" crossorigin="anonymous"></script>
Your making it too complicated. Just use the percentages in #keyframes, and use transform: translateX(number) like so:
#keyframes yo-yo {
0% {transform: translateX(0); }
25% { transform: translateX(-20px); }
75% { transform: translateX(20px); }
100% { transform: translateX(0px); }
}
You should try to use transform instead of giving positions. For a better understanding, checkout this link CSS translation vs changing absolute positioning values.
You need to use the progress instead of just simply declaring a from and to in the keyframes rule
Something like this would suffice. If you want a repeating animation then just add a infinite before linear
html,
body {
padding: 0;
margin: 0;
outline: none;
border: 0;
}
.yo-yo {
display: block;
position: absolute;
height: 50px;
width: 200px;
background: red;
transform-origin: 50% 50%;
animation: yo-yo 2s linear;
/* Animation speed and type */
animation-timing-function: ease-in-out;
}
/* Animation beginning and ending */
#keyframes yo-yo {
0% {
left: 0px;
}
25% {
left: -100px;
}
50% {
left: 0px;
}
75% {
left: 100px;
}
100% {
left: 0px;
}
}
<span class="yo-yo"></span>
You can use animation with infinite normal linear. If you remove infinite from animation then it will stop after one iteration. Your animation is divided into 5 parts. 0, all the way right, 0, all the way left, 0. So start changing the left position from 0%, 25%, 50%, 75% and 100%.
.yoyo-container{
background-color: #DEEBF7;
padding:12px;
position: relative;
width: 200px;
height: 16px;
margin: 0 auto;
}
.yo-yo {
display: block;
position: absolute;
height: 16px;
width: 200px;
background: red;
transform-origin: 50% 50%;
animation: yo-yo 2s infinite normal linear; /* Animation speed and type */
}
/* Animation beginning and ending */
#keyframes yo-yo {
0% {transform: translateX(0); }
25% { transform: translateX(50%); }
50% { transform: translateX(0); }
75% { transform: translateX(-50%); }
100% { transform: translateX(0); }
}
<div class="yoyo-container">
<span class="yo-yo"></span>
</div>
Related
just a quick question regarding animated elements in React.js - I have noticed that when trying to make use of the animation-delay property in CSS, that React does not seem to apply this rule at all for some reason.
For example, I am trying to make a basic loading component, which just has a series of basic circles moving about in sequence, the CSS for which is below:
.--loaderContainer {
position: relative;
left: 50%;
top: 50%;
transform: translateX(-50%), translateY(-50%);
width: 4rem;
height: 4rem;
}
.--loaderContainer:nth-child(n) {
width: 1rem;
height: 1rem;
border-radius: 9999px;
margin: 0;
padding: 0;
position: absolute;
animation-name: spin;
animation-duration: 2s;
animation-timing-function: ease;
animation-iteration-count: infinite;
animation-fill-mode: both;
}
.--loaderContainer:first-child {
background-color: red;
transform: rotate(270deg);
animation-delay: -1.5s;
}
.--loaderContainer:nth-child(2) {
background-color: blue;
transform: rotate(180deg);
animation-delay: -1s;
}
.--loaderContainer:nth-child(3) {
background-color: green;
transform: rotate(90deg);
animation-delay: -0.5s;
}
.--loaderContainer:nth-child(4) {
background-color: yellow;
}
#keyframes spin {
0%,
100% {
transform: translate(0);
}
25% {
transform: translate(160%);
}
50% {
transform: translate(160%, 160%);
}
75% {
transform: translate(0, 160%);
}
}
As far as I can tell, this should stagger each of the child elements in sequence, performing the same animation but at different times. However, for some reason, React simply plays the animation, with no delay whatsoever and has all four elements animate at the exact same time.
It seems like a really basic issue to be having and while I have looked up a variety of answers, I just can't seem to find any concrete solutions, so would be super appreciative for any help. Thanks!
If all four circles are seen, I think this animation should be working properly.
The negative animation-delay values ensures that four circles start at different points of the animation, rather than putting an actual delay.
More about animation-delay
Without it, they will start at same point and move together while stacking with each other, resulting in only one circle is seen (the last yellow circle since it's on top of stack).
Here is a basic example for testing the effect of animation-delay by toggling it on and off for all the circles, it can run with the "run code snippet" button below.
Hope it will help.
const btn = document.querySelector("button");
const loaders = document.querySelectorAll(".--loaderContainer");
btn.addEventListener("click", () => {
loaders.forEach((loader) => loader.classList.toggle("no-delay"));
btn.textContent = loaders[0].classList.contains("no-delay")
? "turn delay on"
: "turn delay off";
});
.--loaderContainer {
position: relative;
left: 50%;
top: 50%;
transform: translateX(-50%), translateY(-50%);
width: 4rem;
height: 4rem;
}
.--loaderContainer:nth-child(n) {
width: 1rem;
height: 1rem;
border-radius: 9999px;
margin: 0;
padding: 0;
position: absolute;
animation-name: spin;
animation-duration: 2s;
animation-timing-function: ease;
animation-iteration-count: infinite;
animation-fill-mode: both;
}
.--loaderContainer:first-child {
background-color: red;
transform: rotate(270deg);
animation-delay: -1.5s;
}
.--loaderContainer:nth-child(2) {
background-color: blue;
transform: rotate(180deg);
animation-delay: -1s;
}
.--loaderContainer:nth-child(3) {
background-color: green;
transform: rotate(90deg);
animation-delay: -0.5s;
}
.--loaderContainer:nth-child(4) {
background-color: yellow;
}
#keyframes spin {
0%,
100% {
transform: translate(0);
}
25% {
transform: translate(160%);
}
50% {
transform: translate(160%, 160%);
}
75% {
transform: translate(0, 160%);
}
}
button {
text-transform: uppercase;
padding: 6px;
}
section {
width: 100px;
height: 100px;
position: relative;
}
div.--loaderContainer.no-delay:nth-child(n) {
animation-delay: 0s;
opacity: 0.8;
}
body {
background-color: #aaa;
}
<button>turn delay off</button>
<section>
<div class="--loaderContainer"></div>
<div class="--loaderContainer"></div>
<div class="--loaderContainer"></div>
<div class="--loaderContainer"></div>
</section>
hello I have a text which has fade-in and transform(translate) animation so after the fade-in and transform animation I want a moving text like up and down a lite, not too much in an infinite loop like you are waiting for loading of something
.imgContaner {
width: 100%;
height: 86.6vh;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/8/85/Sky-3.jpg");
background-size: cover;
background-repeat: no-repeat;
position: relative;
overflow: hidden;
}
.imgContaner p {
color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 3em;
text-align: center;
text-shadow: -1px 0 #000000, 1px 0 #000000, 0 1px #000000, 0 -1px #000000;
animation: 4s ease-in-out test ;
opacity: 1;
}
#keyframes test {
from {
transform: translate(-50% , 400%);
opacity: 0;
}
to {
transform: translate(-50%, -50%);
opacity: 1;
}
}
<div className={classes.imgContaner}>
<p>Make Your Dreams Come True</p>
</div>
You can do this in two ways with css.
First way: Add more frames in your #keyframes definition. Instead of using from and to properties, use percentages. For example:
#keyframes test {
0% {
transform: translate(-50% , 400%);
opacity: 0;
}
50% {
transform: translate(-50%, -50%);
opacity: 1;
}
75% {
Do other stuff...
}
100% {
Do other stuff...
}
}
Second way: Chain animations to play after the other one. By adding delay to the second animation equal to the duration of first animation. Like:
animation: test 4s ease-in-out, otherAnim 2s ease-in-out 4s;
Note that you can't do it this way:
animation: test 4s ease-in-out;
animation: otherAnim 2s ease-in-out 4s;
This way first one will be overwriten by second one. Which is not what you want.
I am using Python and Django to modify a website, I'm using bootstrap 4 as well.
I am attempting to change the pre-loaded spinner currently in use (the typical circle spinner).
I have entered the preloader within my html file, my css file, and made a custom.js file to support the loader yet when I refresh the page the loader shows the standard circle. (I have deleted the previous spinner files and style code but for some reason it still shows when I use "div id=preloader"
Here is my preloader css style.
#preloader {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #f5f5f5;
/* change if the mask should be a color other than white */
z-index: 1000;
/* makes sure it stays on top */
}
.pre-container {
position: absolute;
left: 50%;
top: 50%;
bottom: auto;
right: auto;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
text-align: center;
}
.spinner {
width: 40px;
height: 40px;
position: relative;
margin: 100px auto;
}
.double-bounce1,
.double-bounce2 {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #53dd6c;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
-webkit-animation: bounce 2.0s infinite ease-in-out;
animation: bounce 2.0s infinite ease-in-out;
}
.double-bounce2 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
#-webkit-keyframes bounce {
0%,
100% {
-webkit-transform: scale(0.0)
}
50% {
-webkit-transform: scale(1.0)
}
}
#keyframes bounce {
0%,
100% {
transform: scale(0.0);
-webkit-transform: scale(0.0);
}
50% {
transform: scale(1.0);
-webkit-transform: scale(1.0);
}
}
Here is the custom js file
$(window).load(function () {
// preloader
$('#status').fadeOut(); // will first fade out the loading animation
$('#preloader').delay(550).fadeOut('slow'); // will fade out the white DIV that covers the website.
$('body').delay(550).css({
'overflow': 'visible'
});
});
here is my preloader tag in my html file
<div id="preloader">
<div class="pre-container">
<div class="spinner">
<div class="double-bounce1"></div>
<div class="double-bounce2"></div>
</div>
</div>
</div>
There are no error message but I want the bounce to show.
I have two divs which has one circle along with one smily where innercircle1 div is rotating with given animation.
What i want is when i hover on innercircle1 div it should stop but with their current transform origin position,
Currently when i hover over innercircle1 div it goes to their starting point i.e. their given transform origin and stop.
body {
background: #000;
color: #fff;
}
#keyframes circle {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#keyframes inner-circle {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-360deg);
}
}
.outercircle {
border: 1px solid red;
border-radius: 50%;
width: 310px;
margin: 64px auto;
height: 310px;
position: Relative;
}
.innercircle {
width: 100px;
height: 100px;
margin: 20px auto 0;
color: orange;
font-size: 100px;
line-height: 1;
animation: circle 5s linear infinite;
transform-origin: 50% 200px;
position: ABSOLUTE;
top: -70px;
left: 109px;
}
.innercircle1 {
animation: inner-circle 5s linear infinite;
}
<div class="outercircle"><div class="innercircle"><div class="innercircle1">☻</div></div></div>
You can pause animation using JQUERY as well as CSS.
A very simple solution to use animation-play-state property.
Try these lines:
.innercircle1 {
animation: inner-circle 5s linear infinite;
animation-play-state: play;
}
.innercircle1:hover{
animation-play-state: paused;
}
I have the following page (see image)
When I click the red button, I want a div to animate when it shows to the user. However, I want the animation to come from the button. Right now the animation comes from the center of the page.
Here's the code I have
#keyframes fadeInScale {
0%{
opacity:0;
transform: scale(0.5);
}
100%{
opacity:1;
transform: scale(1);
}
}
#keyframes fadeOutScale {
0%{
opacity:1;
transform: scale(1);
}
100%{
opacity:0;
transform: scale(0.5);
}
}
.overlay {
position: absolute;
top: 0;
z-index: 500;
width: 100%;
height: 100%;
left: 0;
right: 0;
bottom: 0;
}
.fade-scale-in {
display: block;
animation: fadeInScale 0.3s 1 ease-out;
}
.fade-scale-out {
display: block;
animation: fadeOutScale 0.3s 1 ease-out;
}
When I click on the red circle, the user sees an overlay page (which is actually a div with class overlay that is absolutely positioned). I add fade-scale-in class to the div (with class overlay). The div then transitions from the center of the screen and grows to fit the user's screen. I want it so that the div transitions from the red circle. Can I use transforms to make this happen?
Here's the code. As you notice, when you click on the yellow circle, the div animates from the center and not from the yellow circle:
https://jsfiddle.net/e4g71y4m/3/
You can do this by adding transform-origin: top left; to the .overlay element. (Don't forget the prefixes (-webkit, -moz etc.)
var overlay$ = $('.overlay');
overlay$.bind('animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd', function(e) {
console.debug('test');
if (e.animationName !== undefined && e.animationName == "fadeOutScale") {
overlay$.addClass('hide');
} else if (e.originalEvent.animationName !== undefined && e.originalEvent.animationName == "fadeOutScale") {
overlay$.addClass('hide');
}
});
$('.click').on('click', function() {
overlay$.removeClass('hide').addClass('fade-scale-in');
});
$('.click-again').on('click', function() {
overlay$.removeClass('hide').addClass('fade-scale-out');
});
#keyframes fadeInScale {
0% {
opacity: 0;
transform: scale(0.5);
}
100% {
opacity: 1;
transform: scale(1);
}
}
#keyframes fadeOutScale {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}
.hide {
display: none;
}
.overlay {
position: absolute;
top: 0;
z-index: 500;
width: 100%;
height: 100%;
left: 0;
right: 0;
bottom: 0;
background: red;
transform-origin: top left;
}
.click {
background: yellow;
border-radius: 50%;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
cursor: pointer;
}
.fade-scale-in {
display: block;
animation: fadeInScale 0.3s 1 ease-out;
}
.fade-scale-out {
display: block;
animation: fadeOutScale 0.3s 1 ease-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="click">Click me</div>
<div class="overlay hide">
Test
<div class="click-again">Click me again</div>
</div>