I currently have an image "floating". So it moves up and down over 10 seconds. But what I'd really like it to do is to do is slide in right from off canvas over 10 seconds and then float infinitely.
The code I have now just makes it float up and down and I'm struggling to add the slide in part. I'm new to CSS animation so I'd appreciate any help.
This is what I have so far.
.shake-vertical {
-webkit-animation: shake-vertical 15s cubic-bezier(0.455, 0.030, 0.515, 0.955) infinite both;
animation: shake-vertical 15s cubic-bezier(0.455, 0.030, 0.515, 0.955) infinite both;
}
#-webkit-keyframes shake-vertical {
0%,
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
10%,
30%,
50%,
70% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
}
20%,
40%,
60% {
-webkit-transform: translateY(8px);
transform: translateY(8px);
}
80% {
-webkit-transform: translateY(6.4px);
transform: translateY(6.4px);
}
90% {
-webkit-transform: translateY(-6.4px);
transform: translateY(-6.4px);
}
}
#keyframes shake-vertical {
0%,
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
10%,
30%,
50%,
70% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
}
20%,
40%,
60% {
-webkit-transform: translateY(8px);
transform: translateY(8px);
}
80% {
-webkit-transform: translateY(6.4px);
transform: translateY(6.4px);
}
90% {
-webkit-transform: translateY(-6.4px);
transform: translateY(-6.4px);
}
}
Considering your image has a class of ball. You can add this CSS to your Existing CSS:
#keyframes slide-in {
from{
margin-right: -100px;
}
to{
margin-right: 0;
}
}
.ball{
width: 100px;
height: 100px;
border-radius: 50%;
background-color: red;
float: right;
animation: slide-in 10s forwards,/*forwards keeps the ball at final position*/
shake-vertical 15s infinite 10s both;
/*
* Two animations applied
* comma separated
* shake-vertical has a 10 second delay specified by '10s'
* the delay should be same as the duration of first animation
*/
}
I have added comments for explanation but if you need more, feel free to comment.
You can set the object with a slidein animation for 10 seconds and on the animationend event change its class to your shake animation.
Add CSS something like this:
#keyframes slidein {
0% {
transform: translateX(100vw);
}
100% {
transform: translateX(50vw);
}
}
.slidein {
animation-name:slidein;
animation-duration:10s;
animation-fill-mode: follow;
}
.shake {
animation-name: shake-vertical;
animation-duration: 10s;
animation-iteration-count: infinite;
}
}
and JavaScript something like this
obj.addEventListener("animationend", function () {
obj.classList.remove('slidein');
obj.classList.add('shake');
});
Example with a simple sliding square in the Snippet.
<!DOCTYPE html>
<html>
<head>
<style>
#keyframes slidein {
0% {
transform: translateX(100vw);
}
100% {
transform: translateX(50vw);
}
}
#keyframes shake-vertical {
0%,
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
10%,
30%,
50%,
70% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
}
20%,
40%,
60% {
-webkit-transform: translateY(8px);
transform: translateY(8px);
}
80% {
-webkit-transform: translateY(6.4px);
transform: translateY(6.4px);
}
90% {
-webkit-transform: translateY(-6.4px);
transform: translateY(-6.4px);
}
}
#obj {
position: relative;
width: 50px;
height: 50px;
top: 50px;
background-color:magenta;
animation-delay:0s;
}
.slidein {
animation-name:slidein;
animation-duration:10s;
}
.shake {
left: 50vw;
animation-name:shake-vertical;
animation-duration: 10s;
animation-iteration-count: infinite;
}
</style>
</head>
<div id="obj" class="slidein"></div>
<script>
var obj = document.getElementById('obj');
obj.addEventListener("animationend", function () {
obj.classList.remove('slidein');
obj.classList.add('shake');
});
</script>
</html>
In below code, the animation plays fine for both initialization and for hover, however when I stop hovering the initial animation is re-played. How do I stop this behaviour? Thanks,
Rik
.logoImage2{
width:100%;
-webkit-filter: drop-shadow(12px 8px 4px #222);
filter: drop-shadow(12px 8px 3px #222);
padding-bottom:2rem;
animation: moveInTopRight 5s ease-out;
}
.logoImage2:hover{
animation: spinY 5s ease-in-out;
}
#keyframes moveInTopRight {
0% {
opacity: 0;
transform: translate3d(50rem,-50rem,50rem) rotateZ(0);
}
80% {
opacity: .5;
transform: translate3d(5rem,5rem,5rem) rotateZ(180deg);
}
100% {
opacity: 1;
transform: translate3d(0,0,0) rotateZ(360deg);
}
}
#keyframes spinY {
0% {
transform:rotateY(0);
}
50% {
transform: rotateY(180deg);
}
100% {
transform: rotateY(360deg);
}
}
You should use them within the same animation to avoid the first one to restart:
.box{
width: 200px;
height:200px;
background:red;
margin:50px;
animation: moveInTopRight 5s ease-out;
}
.box:hover {
animation:moveInTopRight 5s ease-out, spinY 5s ease-in-out;
}
#keyframes moveInTopRight {
0% {
opacity: 0;
transform: translate3d(50rem, -50rem, 50rem) rotateZ(0);
}
80% {
opacity: .5;
transform: translate3d(5rem, 5rem, 5rem) rotateZ(180deg);
}
100% {
opacity: 1;
transform: translate3d(0, 0, 0) rotateZ(360deg);
}
}
#keyframes spinY {
0% {
transform: rotateY(0);
}
50% {
transform: rotateY(180deg);
}
100% {
transform: rotateY(360deg);
}
}
<div class="box">
</div>
And for this particular case you can replace the second animation with a transition:
.box{
width: 200px;
height:200px;
background:red;
margin:50px;
animation: moveInTopRight 5s ease-out;
transition:0s;
}
.box:hover {
transform: rotateY(360deg);
transition:transform 5s ease-in;
}
#keyframes moveInTopRight {
0% {
opacity: 0;
transform: translate3d(50rem, -50rem, 50rem) rotateZ(0);
}
80% {
opacity: .5;
transform: translate3d(5rem, 5rem, 5rem) rotateZ(180deg);
}
100% {
opacity: 1;
transform: translate3d(0, 0, 0) rotateZ(360deg);
}
}
<div class="box">
</div>
I have tried to make an animated arrow like like the one in this site. A demo of my code attempt is available here. But the animation is not working in-line with the animation in the site.
My Code :
.animated-arrow-1 {
-webkit-animation: arrow1 3s infinite ease-out;
animation: arrow1 3s infinite ease-out;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0
}
.animated-arrow-2 {
-webkit-animation: arrow2 3s infinite ease-in;
animation: arrow2 3s infinite ease-in;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1
}
#-webkit-keyframes arrow1 {
0% {
opacity: 0;
-webkit-transform: translate(0,0);
transform: translate(0,0)
}
90% {
opacity: 0;
-webkit-transform: translate(0,0);
transform: translate(0,0)
}
100% {
opacity: 1;
-webkit-transform: translate(0,36px);
transform: translate(0,36px)
}
}
#keyframes arrow1 {
0% {
opacity: 0;
-webkit-transform: translate(0,0);
-ms-transform: translate(0,0);
transform: translate(0,0)
}
90% {
opacity: 0;
-webkit-transform: translate(0,0);
-ms-transform: translate(0,0);
transform: translate(0,0)
}
100% {
opacity: 1;
-webkit-transform: translate(0,36px);
-ms-transform: translate(0,36px);
transform: translate(0,36px)
}
}
#-webkit-keyframes arrow2 {
0% {
opacity: 1;
-webkit-transform: translate(0,0);
transform: translate(0,0)
}
90% {
opacity: 1;
-webkit-transform: translate(0,0);
transform: translate(0,0)
}
100% {
opacity: 0;
-webkit-transform: translate(0,36px);
transform: translate(0,36px)
}
}
#keyframes arrow2 {
0% {
opacity: 1;
-webkit-transform: translate(0,0);
-ms-transform: translate(0,0);
transform: translate(0,0)
}
90% {
opacity: 1;
-webkit-transform: translate(0,0);
-ms-transform: translate(0,0);
transform: translate(0,0)
}
100% {
opacity: 0;
-webkit-transform: translate(0,36px);
-ms-transform: translate(0,36px);
transform: translate(0,36px)
}
}
Could you please anybody tell me what I missed here?
You were reasonably close to achieving the required animation. In your code, there was only one movement from 0px to 36px for both the arrows but what was actually needed is a two stage animation with different keyframe settings for the two arrows. One arrow should start invisible at 0px, fade-in to 50px, stay there and then fade-out to 100px whereas the other arrow should start visible at 50px, fade-out to 100px, immediately go to 0px and then fade-in at 50px.
.icon {
position: relative;
}
.icon img {
position: absolute;
margin: auto;
display: block;
}
.animated-arrow-1 {
animation: arrow1 3s infinite linear;
opacity: 0
}
.animated-arrow-2 {
animation: arrow2 3s infinite linear;
opacity: 1;
}
#keyframes arrow1 {
0%, 10% {
opacity: 0;
transform: translate(0, 0px);
}
50%,
60% {
opacity: 1;
transform: translate(0, 50px)
}
100% {
opacity: 0;
transform: translate(0, 100px)
}
}
#keyframes arrow2 {
0%, 10% {
opacity: 1;
transform: translate(0, 50px);
}
50%,
60% {
opacity: 0;
transform: translate(0, 100px)
}
61% {
opacity: 0;
transform: translate(0, 0);
}
100% {
opacity: 1;
transform: translate(0, 50px)
}
}
body {
background: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="icon">
<img src="http://s12.postimg.org/ibsmfp6w9/Down_Arrow.png" class="animated-arrow-1" />
<img src="http://s12.postimg.org/ibsmfp6w9/Down_Arrow.png" class="animated-arrow-2" />
</div>
Is it possible to animate a path in the symbol tag with css3 keyframe animation? It doesn't work in my case.
Example:
http://codepen.io/anon/pen/Hfbmr
HTML:
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="icon-love" viewBox="0 0 54 54">
<title>Love</title>
<path id="icon-love-circle" fill="#000000" d="M27,3c13.2,0,24,10.8,24,24S40.2,51,27,51S3,40.2,3,27S13.8,3,27,3 M27,0C12.1,0,0,12.1,0,27
s12.1,27,27,27s27-12.1,27-27S41.9,0,27,0L27,0z"/>
<path id="icon-love-heart" fill="#000000" d="M15.2,23.2c0-2,0.6-3.5,1.7-4.6c1.1-1.1,2.7-1.7,4.7-1.7c0.6,0,1.1,0.1,1.7,0.3c0.6,0.2,1.1,0.5,1.6,0.8
c0.5,0.3,0.9,0.6,1.3,0.9c0.4,0.3,0.7,0.6,1,0.9c0.3-0.3,0.7-0.6,1-0.9c0.4-0.3,0.8-0.6,1.3-0.9c0.5-0.3,1-0.6,1.6-0.8
c0.6-0.2,1.1-0.3,1.7-0.3c2,0,3.6,0.6,4.7,1.7c1.1,1.1,1.7,2.6,1.7,4.6c0,2-1,4-3.1,6l-8.3,8c-0.2,0.2-0.4,0.2-0.6,0.2
c-0.2,0-0.4-0.1-0.6-0.2l-8.4-8.1c-0.1-0.1-0.2-0.2-0.4-0.3c-0.2-0.2-0.4-0.5-0.7-0.9c-0.3-0.4-0.6-0.9-0.9-1.3
c-0.3-0.4-0.5-1-0.7-1.6C15.4,24.4,15.2,23.8,15.2,23.2z M17,23.2c0,1.5,0.8,3.1,2.5,4.8l7.8,7.5L35,28c1.7-1.7,2.5-3.3,2.5-4.8
c0-0.7-0.1-1.4-0.3-1.9c-0.2-0.6-0.4-1-0.7-1.3c-0.3-0.3-0.7-0.6-1.1-0.8c-0.4-0.2-0.8-0.3-1.3-0.4c-0.4-0.1-0.8-0.1-1.3-0.1
s-1,0.1-1.5,0.3c-0.5,0.2-1,0.5-1.5,0.9c-0.5,0.3-0.8,0.7-1.2,1c-0.3,0.3-0.6,0.6-0.8,0.8c-0.2,0.2-0.4,0.3-0.7,0.3
s-0.5-0.1-0.7-0.3c-0.2-0.2-0.5-0.5-0.8-0.8c-0.3-0.3-0.7-0.6-1.2-1c-0.5-0.3-0.9-0.6-1.5-0.9c-0.5-0.2-1-0.3-1.5-0.3
c-0.5,0-0.9,0-1.3,0.1c-0.4,0.1-0.8,0.2-1.3,0.4c-0.4,0.2-0.8,0.5-1.1,0.8c-0.3,0.3-0.5,0.8-0.7,1.3C17.1,21.8,17,22.5,17,23.2z"
/>
</symbol>
CSS:
.icon-love {
height: 54px;
width: 54px;
}
#icon-love-heart {
animation-name: 'heartbeat';
animation-duration: 5000ms;
transform-origin:70% 70%;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
#keyframes heartbeat {
0% { transform: scale(1); }
30% { transform: scale(1); }
40% { transform: scale(1.08); }
50% { transform: scale(1); }
60% { transform: scale(1); }
70% { transform: scale(1.05); }
80% { transform: scale(1); }
100% { transform: scale(1); }
}
Cheers Philip
It is perfectly possible. It works if you drop <use xlink:href="#icon-love"/> part and just use normal svg. If you are concenrned about maintaining your code clean I suggest you store your svg in a variable and output it dynamically instead of using the <use> tag, which breaks the animation.
http://codepen.io/easwee/pen/xFDbu
<svg class="icon-love" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54">
<path id="icon-love-circle" fill="#000000" d="M27,3c13.2,0,24,10.8,24,24S40.2,51,27,51S3,40.2,3,27S13.8,3,27,3 M27,0C12.1,0,0,12.1,0,27
s12.1,27,27,27s27-12.1,27-27S41.9,0,27,0L27,0z"/>
<path class="icon-love-heart" fill="#000000" d="M15.2,23.2c0-2,0.6-3.5,1.7-4.6c1.1-1.1,2.7-1.7,4.7-1.7c0.6,0,1.1,0.1,1.7,0.3c0.6,0.2,1.1,0.5,1.6,0.8
c0.5,0.3,0.9,0.6,1.3,0.9c0.4,0.3,0.7,0.6,1,0.9c0.3-0.3,0.7-0.6,1-0.9c0.4-0.3,0.8-0.6,1.3-0.9c0.5-0.3,1-0.6,1.6-0.8
c0.6-0.2,1.1-0.3,1.7-0.3c2,0,3.6,0.6,4.7,1.7c1.1,1.1,1.7,2.6,1.7,4.6c0,2-1,4-3.1,6l-8.3,8c-0.2,0.2-0.4,0.2-0.6,0.2
c-0.2,0-0.4-0.1-0.6-0.2l-8.4-8.1c-0.1-0.1-0.2-0.2-0.4-0.3c-0.2-0.2-0.4-0.5-0.7-0.9c-0.3-0.4-0.6-0.9-0.9-1.3
c-0.3-0.4-0.5-1-0.7-1.6C15.4,24.4,15.2,23.8,15.2,23.2z M17,23.2c0,1.5,0.8,3.1,2.5,4.8l7.8,7.5L35,28c1.7-1.7,2.5-3.3,2.5-4.8
c0-0.7-0.1-1.4-0.3-1.9c-0.2-0.6-0.4-1-0.7-1.3c-0.3-0.3-0.7-0.6-1.1-0.8c-0.4-0.2-0.8-0.3-1.3-0.4c-0.4-0.1-0.8-0.1-1.3-0.1
s-1,0.1-1.5,0.3c-0.5,0.2-1,0.5-1.5,0.9c-0.5,0.3-0.8,0.7-1.2,1c-0.3,0.3-0.6,0.6-0.8,0.8c-0.2,0.2-0.4,0.3-0.7,0.3
s-0.5-0.1-0.7-0.3c-0.2-0.2-0.5-0.5-0.8-0.8c-0.3-0.3-0.7-0.6-1.2-1c-0.5-0.3-0.9-0.6-1.5-0.9c-0.5-0.2-1-0.3-1.5-0.3
c-0.5,0-0.9,0-1.3,0.1c-0.4,0.1-0.8,0.2-1.3,0.4c-0.4,0.2-0.8,0.5-1.1,0.8c-0.3,0.3-0.5,0.8-0.7,1.3C17.1,21.8,17,22.5,17,23.2z"
/>
</svg>
Also added prefixes for crossbrowser css (webkit, firefox and standard):
.icon-love {width:54px;height:54px;}
.icon-love-heart {
-moz-animation: heartbeat 5s linear infinite;
-webkit-animation: heartbeat 5s linear infinite;
animation: heartbeat 5s linear infinite;
-moz-transform-origin:50% 50%;
-webkit-transform-origin:50% 50%;
transform-origin:50% 50%;
}
#-moz-keyframes heartbeat {
0% { -moz-transform: scale(1); }
30% { -moz-transform: scale(1); }
40% { -moz-transform: scale(1.08); }
50% { -moz-transform: scale(1); }
60% { -moz-transform: scale(1); }
70% { -moz-transform: scale(1.05); }
80% { -moz-transform: scale(1); }
100% { -moz-transform: scale(1); }
}
#-webkit-keyframes heartbeat {
0% { -webkit-transform: scale(1); }
30% { -webkit-transform: scale(1); }
40% { -webkit-transform: scale(1.08); }
50% { -webkit-transform: scale(1); }
60% { -webkit-transform: scale(1); }
70% { -webkit-transform: scale(1.05); }
80% { -webkit-transform: scale(1); }
100% { -webkit-transform: scale(1); }
}
#keyframes heartbeat {
0% { transform: scale(1); }
30% { transform: scale(1); }
40% { transform: scale(1.08); }
50% { transform: scale(1); }
60% { transform: scale(1); }
70% { transform: scale(1.05); }
80% { transform: scale(1); }
100% { transform: scale(1); }
}