I'm setting up some predefined animation classes to animate on scroll. They all work, except one I've called slideUp, which seems to behave exactly like slideDown. The animations look exactly like they sound, and are using transforms like so:
#keyframes slideUp {
from {
-webkit-transform: translateY(10%);
transform: translateY(10%);
}
to {
-webkit-transform: translateY(0%);
transform: translateY(0%);
}
}
#keyframes slideDown {
from {
-webkit-transform: translateY(-10%);
transform: translateY(-10%);
}
to {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
Seems that no matter what, calling slideUp generates an animation that looks like slideDown, and I can't see any error in my keyframes, nor in execution.
Example of execution:
animation: slideUp 600ms $transition-ease-in 1 forwards, fadeIn 500ms linear 1 forwards;
Thanks!
Edit: I changed the name slideUp to slideup and it started working. This is a from-scratch project, so I can guarantee no conflicts in my code that would have caused that. Any ideas?
Here is an example that may help you. I made it with your animation. Hope this will help. https://jsfiddle.net/ssr3axtr/2/
html :
<div class="box box--1">
</div>
<div class="box box--2">
</div>
CSS :
#keyframes slideUp {
from {
-webkit-transform: translateY(10%);
transform: translateY(10%);
}
to {
-webkit-transform: translateY(0%);
transform: translateY(0%);
}
}
#keyframes slideDown {
from {
-webkit-transform: translateY(-10%);
transform: translateY(-10%);
}
to {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
.box{
display:inline-block;
width:50px;
height:50px;
background:blue;
transform:translateY(0);
}
.box--1{
animation: slideUp 1s linear 0s infinite forwards;
}
.box--2{
animation: slideDown 1s linear 0s infinite forwards;
}
I think your animation shorthand lists properties in the wrong order. Try this:
#keyframes slideUp {
from {
-webkit-transform: translateY(10%);
transform: translateY(10%);
}
to {
-webkit-transform: translateY(0%);
transform: translateY(0%);
}
}
#keyframes slideDown {
from {
-webkit-transform: translateY(-10%);
transform: translateY(-10%);
}
to {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
.btn {
background: green;
color: white;
padding: 2em;
display: inline-block;
animation: 600ms cubic-bezier(0.1, 0.7, 1.0, 0.1) 1 forwards slideUp;
}
<div class="btn">button</div>
Related
I am trying to make an Oscillatory animation using css as shown below:
Here's how I have created my animation:
#keyframes rotateFeather {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(-180deg);
}
50% {
transform: rotate(-90deg);
}
75% {
transform: rotate(90deg);
}
100% {
transform: rotate(180deg);
}
}
Here is my class: (Using sccs)
.logo {
height: 5rem;
transition: all 0.3s ease;
&box {
position: absolute;
top: 4rem;
left: 4rem;
}
&:hover {
animation-name: rotateFeather;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
}
Here I am facing this problem: When it reaches 180deg at 100% it abruptly resets to 0 which I want to make smooth.
How is it possible to do the same?
To ensure smooth transition, We need to make sure that transformation at 0 and 100% must match with the original state:
#keyframes rotateFeather {
0% {
transform: rotate(0deg); //-30
transform-origin: bottom;
}
20% {
transform: rotate(-30deg); //-60
transform-origin: bottom;
}
40% {
transform: rotate(0deg); //-30
transform-origin: bottom;
}
60% {
transform: rotate(30deg); // 0
transform-origin: bottom;
}
80% {
transform: rotate(60deg); //30
transform-origin: bottom;
}
100% {
transform: rotate(0deg); //30
transform-origin: bottom;
}
}
This helped me to solve my issue. I am not sure, if I need to add transform-origin in every stage, if someone can elaborate better on that, that would be helpful.
Here's a simplified version of your latest animation code (with a Codepen to see it in action):
#keyframes rotateFeather {
0% {
transform: rotate(0deg);
}
20% {
transform: rotate(-30deg);
}
80% {
transform: rotate(60deg);
}
100% {
transform: rotate(0deg);
}
}
.logo {
transform-origin: bottom;
&:hover {
animation: rotateFeather 1s linear infinite;
}
}
Some points about the above tweaks:
You don't need transform-origin at every keyframe. You can set it globally.
You can roll all of your animation properties into a single shorthand rule.
You can skip keyframes that are mathematically interpolating where the animation would be going anyway (notice I omitted 40% and 60% above and it looks the same).
You don't need any transition rules on elements that you are animating with keyframes. Unless you're using it for something else, but you want to be careful to avoid attempting to animate the same property on the same element with both animation and transition simultaneously, as it will break the animation in question.
EDIT: So, for some reason, the effect did not work/apply when running it locally. But, it works fine when I deployed it to GH pages. Does anyone know why this is?
I have text laid out in a circle that I want to rotate about itself. On plain HTML/CSS/Javascript, it works just fine and I get the desired result. Also, when I tried it out separately on this Codepen it works as well.
However, when I try to run this on the .rotating-circle div every style gets applied except for the animation. Not sure if this is relevant but I am using the CircleType js library to create this circular text.
import React, {useEffect, useRef} from 'react'
import CircleType from 'circletype'
function RotatingCircle() {
const rotatingCircle = useRef();
useEffect(()=> {
new CircleType(rotatingCircle.current).radius(100)
}, [])
return (
<div className="rotating-circle">
<p className="circle" id="rounded-text" ref={rotatingCircle}>
AND THE WORLD KEEPS GOING AROUND AND AROUND AND AROUND
</p>
</div>
)
}
export default RotatingCircle
Here is the SCSS:
.some-class{
.rotating-circle{
font-size: 1rem;
z-index: -999;
font-weight: bold;
color:$secondary;
display: block;
// background: #000;
max-width: 100%;
max-height: 300px;
// border-radius: 50%;
margin-top: -250px;
-webkit-animation: spin1 30s infinite linear;
-moz-animation: spin1 30s infinite linear;
-o-animation: spin1 30s infinite linear;
-ms-animation: spin1 30s infinite linear;
animation: spin1 30s infinite linear;
-webkit-transform-origin: 50% 0%;
-moz-transform-origin: 50% 0%;
-o-transform-origin: 50% 0%;
transform-origin: 50% 80%;
}
}
#-webkit-keyframes spin1 {
0% { -webkit-transform: rotate(0deg);}
100% { -webkit-transform: rotate(360deg);}
}
#-moz-keyframes spin1 {
0% { -moz-transform: rotate(0deg);}
100% { -moz-transform: rotate(360deg);}
}
#-o-keyframes spin1 {
0% { -o-transform: rotate(0deg);}
100% { -o-transform: rotate(360deg);}
}
#-ms-keyframes spin1 {
0% { -ms-transform: rotate(0deg);}
100% { -ms-transform: rotate(360deg);}
}
#-keyframes spin1 {
0% { transform: rotate(0deg);}
100% { transform: rotate(360deg);}
}
Also, just wanted to add that the .some-class class is applied to an element that this component is nested in.
I'm trying to loop a css3 animation between 3 elements, after the 3rd element ends, I want to restart the animation and so on...
Here's my code:
.oferta-prods.run-animation img{
animation-name:fadeIn;
animation-duration:4s;
animation-timing-function:ease-in-out;
opacity:0;
}
.oferta-prods.run-animation img:nth-child(1){animation-delay:0s;}
.oferta-prods.run-animation img:nth-child(2){animation-delay:4s;}
.oferta-prods.run-animation img:nth-child(3){animation-delay:8s;}
#keyframes fadeIn{
0%{
opacity:0;
}
10%{
opacity:1;
}
90%{
opacity:1;
}
100%{
opacity:0;
}
}
<div class="oferta-prods run-animation">
<img src="assets/House.svg">
<img src="assets/Car.svg">
<img src="assets/Beach.svg">
</div>
So, the idea is, element 1 starts animation then ends, element 2 starts animation then ends, then element 3 starts animation then ends. After this, I want to automatically begin a new cycle after the 3 elements end the animation.
Thank you
You can do this by defining 3 diferent animations with different execution timers.
Following my coding example bellow, we divide 100% / 3, and that gives us around 33%, meaning, that every image should run the animation for 33% of the animation total time.
Take a look at this example:
ody {
margin: 0;
padding: 0;
box-sizing: border-box;
height: 100vh;
}
.animation-wrapper div {
width: 20px;
height: 50px;
margin: 10px;
}
.animation-wrapper .anim-1 {
background-color: red;
animation: animation1 4s infinite ease-in-out;
}
.animation-wrapper .anim-2 {
background-color: blue;
animation: animation2 4s infinite ease-in-out;
}
.animation-wrapper .anim-3 {
background-color: green;
animation: animation3 4s infinite ease-in-out;
}
#keyframes animation1{
0%{
transform: translateX(0);
}
16.5%{
transform: translateX(20px);
}
33%{
transform: translateX(0);
}
100%{
transform: translateX(0);
}
}
#keyframes animation2{
0%{
transform: translateX(0);
}
33%{
transform: translateX(0);
}
49.5%{
transform: translateX(20px);
}
66%{
transform: translateX(0);
}
100%{
transform: translateX(0);
}
}
#keyframes animation3{
0%{
transform: translateX(0);
}
66%{
transform: translateX(0);
}
82.5%{
transform: translateX(20px);
}
99%{
transform: translateX(0);
}
100%{
transform: translateX(0);
}
}
<div class="animation-wrapper">
<div class="anim-1"></div>
<div class="anim-2"></div>
<div class="anim-3"></div>
</div>
One way is to use Javascript to restart the animation. It involves triggering a DOM reflow, so it may not be the best way on a heavy page.
const lastImage = document.querySelector(".oferta-prods.run-animation img:nth-child(3)");
lastImage.addEventListener("animationend", () => {
lastImage.parentNode.classList.remove("run-animation");
void lastImage.offsetWidth; // trigger DOM reflow
lastImage.parentNode.classList.add("run-animation");
});
.oferta-prods.run-animation img {
animation: 4s ease-in-out fadeIn;
opacity: 0;
}
.oferta-prods.run-animation img:nth-child(1) { animation-delay: 0s; }
.oferta-prods.run-animation img:nth-child(2) { animation-delay: 4s; }
.oferta-prods.run-animation img:nth-child(3) { animation-delay: 8s; }
#keyframes fadeIn {
0% { opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% {opacity: 0; }
}
<div class="oferta-prods run-animation">
<img src="assets/House.svg">
<img src="assets/Car.svg">
<img src="assets/Beach.svg">
</div>
Is there a way to pulsate opacity from 0 to 1 (repeat) slowly with a CSS3 keyframes transformation, infinitely? Or does this require jQuery or Javascript with a transition opacity inside a class that is toggled on an interval?
I'm trying to work it into my orbit transformations (below). (I'm working on a live wallpaper background effect with multiple opaque images floating in a sidebar image on an installer application I'm building in Objective C.)
.orbit1
{
animation: myOrbit 200s linear infinite;
}
.orbit2
{
animation: myOrbit2 200s linear infinite;
}
#keyframes myOrbit1
{
from { transform: rotate(0deg) translateX(150px) rotate(0deg) }
to { transform: rotate(360deg) translateX(150px) rotate(-360deg) }
}
#keyframes myOrbit2
{
from { transform: rotate(360deg) translateX(250px) rotate(-360deg) }
to { transform: rotate(0deg) translateX(250px) rotate(0deg) }
}
You can do it by adding multiple animations to the element, for example:
.orbit1
{
/* added for example reasons */
position :absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -100px;
width: 200px;
height: 200px;
background: red;
/* ---------- */
animation: myOrbit1 20s linear infinite, Pulsate 4s linear infinite;
}
#keyframes myOrbit1
{
from { transform: rotate(0deg) translateX(150px) rotate(0deg) }
to { transform: rotate(360deg) translateX(150px) rotate(-360deg) }
}
#keyframes Pulsate {
from { opacity: 1; }
50% { opacity: 0; }
to { opacity: 1; }
}
<div class="orbit1"></div>
I'ved modified some of your parameters (like the speed of the animation and the opacity minimum) and added some spoof styling for the element for the purpose of the example.
Edit
I had originally thought that the multiple rotate() declarations were in error, but #vals informed me why it was there (to create a counter rotation on the object). I've updated the answer, and learned something new.
I'm trying to grow a circular image on hover, but can't get this code to work.
I can get the circle to grow using the CSS transform but it grows immediately and is a bit ugly. Ideally I'd want there to be a 2-3000ms delay with linear growth both on hover and mouse out.
I know I can do this with JS/D3 but need to do it with CSS if possible.
Have tried
.wpb_single_image .vc_single_image-wrapper.vc_box_circle:hover
{
animation: mymove 3s normal;
}
#-webkit-keyframes mymove {
0%
{
width:250px;}
25%
{
width:260px;}
75%
{
width:270px;}
100%
{
width:280px;
}
}
and
.wpb_single_image .vc_single_image-wrapper.vc_box_circle:hover
{
animation: mymove 3s normal;
}
#-webkit-keyframes mymove {
0%
{
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);}
}
25%
{
-webkit-transform: scale(1.033);
-ms-transform: scale(1.033);
transform: scale(1.033);}
75%
{
-webkit-transform: scale(1.066);
-ms-transform: scale(1.066);
transform: scale(1.066);}
100%
{
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
But neither are working.
Is there a better way to do this?
I've created a pen based on your code
Using transform: scale is a better method since it increases both width and height.
The key thing you missed out on for creating a smooth animation is the transition attribute, this needs to be applied to the element in it's normal state not it's :hover state.
I've added this transition styling:
transition: 3s ease-in-out;
Note that it's the same length as your animation timing. ease-in-out is a standard easing function, if you'd like to get more in-depth try playing around with cubic-bezier
Animation delay can be added easily with this attribute:
animation-delay:2s
Another thing which makes keyframe animations smoother is having the 0% and 100% stylings the same, so in this example the circle returns to the original scale by the time it reaches 100% which creates a nice, smooth, repeatable animation.
I've also created an alternative animation which looks even smoother, this is done by simply setting scale for the 0% and 100% points in the animation:
0%{transform: scale(1)}
100%{transform: scale(2)}
Another thing you can do is change your animation loop setting from normal to infinite alternate, checkout my second example this is using infinite alternate which makes the circle grow and shrink with no sudden snaps.
You can delay the start of an animation with animation-delay
Such as
.delay {
animation-delay:2s
}
Reference # MDN
Demo showing the difference below
.circle {
border-radius: 50%;
display: block;
}
.circle:hover {
animation: mymove 3s normal;
}
.delay:hover {
animation-delay: 2s
}
#-webkit-keyframes mymove {
0% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
}
25% {
-webkit-transform: scale(1.033);
-ms-transform: scale(1.033);
transform: scale(1.033);
}
75% {
-webkit-transform: scale(1.066);
-ms-transform: scale(1.066);
transform: scale(1.066);
}
100% {
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
#-webkit-keyframes mymove {
0% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
25% {
-webkit-transform: scale(1.033);
-ms-transform: scale(1.033);
transform: scale(1.033);
}
75% {
-webkit-transform: scale(1.066);
-ms-transform: scale(1.066);
transform: scale(1.066);
}
100% {
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
}
<div>
<img src="http://lorempixel.com/output/abstract-q-c-100-100-4.jpg" alt="" class="circle" />
</div>
<div>
<img src="http://lorempixel.com/output/abstract-q-c-100-100-4.jpg" alt="" class="circle delay" />
</div>
You can delay the start of the transition by using the transition-delay property.
div {
-webkit-transition-delay: 2s; /* Safari */
transition-delay: 2s;
}
W3Schools