CSS reverse morphing animation on hover - css

i have circle element animating on my page, what i try to do is to smoothly transition it on hover, to be just a square with it original size: 200px x 200px. And also, on mouse leave to smoothly back to previous (morphing) state. Any ideas? Heres my code:
a {
width: 200px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
background: #333;
color: #fff;
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
animation: morphing ease-in-out 10s infinite;
}
a:hover {
}
#keyframes morphing {
0% {
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
}
25% {
border-radius: 58% 42% 75% 25% / 76% 46% 54% 24%;
}
50% {
border-radius: 50% 50% 33% 67% / 55% 27% 73% 45%;
}
75% {
border-radius: 33% 67% 58% 42% / 63% 68% 32% 37%;
}
}
<a>sample text</a>

Ok, so here it goes. On mouseover, we start the morphing animation. On mouseout, we set the border radius to start position.
You can play with duration (which is in milliseconds) as per your liking.
let elem = document.querySelector("a");
let morphAnim = elem.getAnimations()[0];
elem.addEventListener("mouseover", () => {
elem.animate(morphAnim.effect.getKeyframes(), {
easing: "ease-in-out",
duration: 10000,
iterations: Infinity,
iterationStart: 0.1
})
})
elem.addEventListener("mouseout", () => {
elem.animate({
borderRadius: "30% 70% 70% 30% / 30% 30% 70% 70%"
}, {
duration: 1000,
fill: "forwards",
iterations: 1
});
})
a {
width: 200px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
background: #333;
color: #fff;
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
animation: morphing ease-in-out 10s infinite;
animation-play-state: paused;
}
#keyframes morphing {
0% {
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
}
25% {
border-radius: 58% 42% 75% 25% / 76% 46% 54% 24%;
}
50% {
border-radius: 50% 50% 33% 67% / 55% 27% 73% 45%;
}
75% {
border-radius: 33% 67% 58% 42% / 63% 68% 32% 37%;
}
}
<a>sample text</a>

Related

Smooth continuous CSS animation blob flow

I am trying to make a lively blob that blobs smoothly around the shape's plane. However, when I make this approach, the blob is very rigid and the flow of 0-25-50-75-100 can be directly seen in the animation. I am guessing this is because of the ease-in-out transition but I am not sure what to do next. I have tried linear, ease-in, ease-out, and ease-in-out but they are all very choppy
What should I change to make it a smoother animated blob?
.shape-container{
display: flex;
align-items: center;
justify-content: center;
height:100vh;
}
.shape{
width: 400px;
height: 400px;
background: linear-gradient(64deg, #f34868 23%, #f24768 23%, #9e00ec 80%);
animation: blob 8s ease-in-out infinite;
}
#keyframes blob {
0%, 100% {
border-radius:65% 100% 80% 100%
}
25% {
border-radius:100% 80% 100% 65%
}
50% {
border-radius:80% 100% 65% 100%
}
75% {
border-radius:100% 65% 100% 80%
}
}
<div class="shape-container">
<div class="shape"/>
</div>
[UPDATE] This is the 2nd blob I tried, this blob also does not smoothly rotate around, it just goes back and forth
.shape-container{
display: flex;
align-items: center;
justify-content: center;
height:100vh;
}
.shape{
width: 400px;
height: 400px;
background: linear-gradient(64deg, #f34868 23%, #f24768 23%, #9e00ec 80%);
animation: blob 8s ease-in-out infinite;
}
#keyframes blob {
0%, 100% {
border-radius:24% 76% 35% 65% / 27% 36% 64% 73%
}
25% {
border-radius:76% 24% 33% 67% / 68% 55% 45% 32%
}
}
<div class="shape-container">
<div class="shape"/>
</div>
I would have another look at the linear animation timing function because it has the same speed from start to end. Also if you combine the blob animation with a rotate animation you don't easily get the idea there is a pattern in the entire animation.
* {
margin: 0;
padding: 0;
}
.shape-container{
display: flex;
align-items: center;
justify-content: center;
height:100vh;
background-color: #222;
}
.shape{
width: 400px;
height: 400px;
background: linear-gradient(64deg, #f34868 23%, #f24768 23%, #9e00ec 80%);
border-radius: 28% 72% 22% 78% / 39% 23% 77% 61%;
transform: rotate(0deg);
will-change: border-radius, transform;
animation: blob 10s linear infinite, spin 100s linear infinite;
}
#keyframes blob {
0%, 100% {
border-radius: 28% 72% 22% 78% / 39% 23% 77% 61%;
}
50% {
border-radius: 72% 28% 50% 50% / 55% 26% 74% 45%;
}
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
<div class="shape-container">
<div class="shape"/>
</div>

How to give wiggle animation effect with fixed position?

I want an element to be animated like a swaying plant. I am looking to animate a div in the following manner.
Fix the bottom
Move the head back and forth
Looking for full css solution.
I have tried this,
#keyframes wiggle {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(-1deg);
}
50% {
transform: rotate(2deg);
}
75% {
transform: rotate(-0.4deg);
}
100% {
transform: rotate(1deg);
}
}
You can set transform-origin property to bottom.
.el {
margin: 30px 50px;
width: 0;
height: 0;
border-style: solid;
border-width: 150px 50px 0 50px;
border-color: #007bff transparent transparent transparent;
animation: wiggle infinite 3s alternate;
transform-origin: bottom;
}
#keyframes wiggle {
0% {transform: rotate(0deg);}
25% {transform: rotate(-3deg);}
50% {transform: rotate(5deg);}
75% {transform: rotate(-1deg);}
100% {transform: rotate(2deg);}
}
<div class="el"></div>

Keyframe animation jumping from the last to first image instead of fading

I inherited an old website to look after and was asked to try and modernise it a bit with a twitter feed and an image slider.
A question.
My slider works fine except that it jumps from the last image to the first rather than fading. Anyone got an idea where I'm going wrong?
I assume it's got something to do with timings or maybe opacity however, I've spent aeons trying to fix it! Or should I try FadeInOut, etc?
CSS:
.slider {
max-width: 508px;
height: 318px;
margin: 2px auto;
position: relative;
}
.slide1,.slide2,.slide3,.slide4,.slide5,.slide6 {
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 1px;
}
.slide1 {background: url("images/B18A4640.jpg") no-repeat center;
background-size: cover;
animation:fade 46s infinite;
}
.slide2 {
background: url("images/B18A4669.jpg") no-repeat center;
background-size: cover;
animation:fade2 46s infinite;
}
.slide3 {
background: url("images/harriet1.jpg") no-repeat center;
background-size: cover;
animation:fade3 46s infinite;
}
.slide4 {
background: url("images/B18A4634.jpg") no-repeat center;
background-size: cover;
animation:fade4 46s infinite;
}
.slide5 {
background: url("images/P1080449.jpg") no-repeat center;
background-size: cover;
animation:fade5 46s infinite;
}
.slide6 {
background: url("images/harriet2.jpg") no-repeat center;
background-size: cover;
animation:fade6 46s infinite;
}
#keyframes fade
{
0% {opacity:1}
20% {opacity: 0}
40% { opacity: 0}
60% { opacity: 0}
80% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade2
{
0% {opacity:0}
20% {opacity: 1}
40% { opacity: 0}
60% { opacity: 0}
80% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade3
{
0% {opacity:0}
20% {opacity: 0}
40% { opacity: 1}
60% { opacity: 0}
80% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade4
{
0% {opacity:0}
20% {opacity: 0}
40% { opacity: 0}
60% { opacity: 1}
80% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade5
{
0% {opacity:0}
20% {opacity: 0}
40% { opacity: 0}
60% { opacity: 0}
80% { opacity: 1}
100% { opacity: 0}
}
#keyframes fade6
{
0% {opacity:0}
20% {opacity: 0}
40% { opacity: 0}
60% { opacity: 0}
80% { opacity: 0}
100% { opacity: 1}
}
This is the Website
html:
<link href="slider.css" rel="stylesheet" type="text/css" />
<div class='slider'>
<div class='slide1'></div>
<div class='slide2'></div>
<div class='slide3'></div>
<div class='slide4'></div>
<div class='slide5'></div>
<div class='slide6'></div>
</div>
Cracked it!
.slider {
max-width: 508px;
height: 318px;
margin: 2px auto;
position: relative;
}
.slide1,.slide2,.slide3,.slide4,.slide5,.slide6 {
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 1px;
}
.slide1 {
background: url("images/B18A4640.jpg") no-repeat center;
background-size: cover;
animation:fade 46s infinite;
-webkit-animation:fade 46s infinite;
}
.slide2 {
background: url("images/B18A4669.jpg") no-repeat center;
background-size: cover;
animation:fade2 46s infinite;
-webkit-animation:fade2 46s infinite;
}
.slide3 {
background: url("images/harriet1.jpg") no-repeat center;
background-size: cover;
animation:fade3 46s infinite;
-webkit-animation:fade3 46s infinite;
}
.slide4 {
background: url("images/B18A4634.jpg") no-repeat center;
background-size: cover;
animation:fade4 46s infinite;
-webkit-animation:fade4 46s infinite;
}
.slide5 {
background: url("images/P1080449.jpg") no-repeat center;
background-size: cover;
animation:fade5 46s infinite;
-webkit-animation:fade5 46s infinite;
}
.slide6 {
background: url("images/harriet2.jpg") no-repeat center;
background-size: cover;
animation:fade6 46s infinite;
-webkit-animation:fade6 46s infinite;
}
#keyframes fade
{
0% {opacity:1}
15% {opacity: 0}
30% { opacity: 0}
45% { opacity: 0}
60% { opacity: 0}
75% { opacity: 0}
100% { opacity: 1}
}
#keyframes fade2
{
0% {opacity:0}
15% {opacity: 1}
30% { opacity: 0}
45% { opacity: 0}
60% { opacity: 0}
75% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade3
{
0% {opacity:0}
15% {opacity: 0}
30% { opacity: 1}
45% { opacity: 0}
60% { opacity: 0}
75% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade4
{
0% {opacity:0}
15% {opacity: 0}
30% { opacity: 0}
45% { opacity: 1}
60% { opacity: 0}
75% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade5
{
0% {opacity:0}
15% {opacity: 0}
30% { opacity: 0}
45% { opacity: 0}
60% { opacity: 1}
75% { opacity: 0}
100% { opacity: 0}
}
#keyframes fade6
{
0% {opacity:0}
15% {opacity: 0}
30% { opacity: 0}
45% { opacity: 0}
60% { opacity: 0}
75% { opacity: 1}
100% { opacity: 0}
}
Don't understand why I need the "opacity=1" at the 100% point for the first slide though or if the "-webkit-animation-fade: bits are necessary as it was working except for the jumping without it.

Why does my CSS3 animation stops for a few miliseconds in each percentage range using #keyframes?

I am trying to make a sailing ship animation. It works, but it is not a smooth animation. It stops in each change I make in the #keyframes. I'm using transform:rotate(-5deg) and then it changes to 5deg to simulate the waves effect, at the same time I make it moves changing the "left" values, but and the result is awful. What piece of css code am I missing to have my animation running soft and smoothly?
Here is code:
div {
width: 150px;
height: 150px;
top: 20px;
background-image: url('https://s-media-cache-ak0.pinimg.com/originals/c2/bb/ae/c2bbaed0207deef5775af9c01e1b31ba.jpg');
position: relative;
background-size: cover;
animation: mymove 5s linear infinite alternate;
transform: rotate(0deg);
transform:translate3d
transition: all;
}
#-webkit-keyframes mymove {
from,
20% {
trans: -2%;
transform: rotate(5deg)
}
20%,
30% {
left: 20%;
transform: rotate(-5deg)
}
40%,
50% {
left: 40%;
transform: rotate(5deg)
}
60%,
70% {
left: 60%;
transform: rotate(-5deg)
}
80%,
90% {
left: 80%;
transform: rotate(5deg)
}
90%,
100% {
left: 100%;
transform: rotate(-5deg)
}
}
When you add 2 percent values like 20%, 30% { ... }, 40%, 50% { ... }, etc., the rules applied will be the same between those 2 steps/values, hence it stops for a few milliseconds.
If to remove 1 of the percent values, and you can also remove the left from all but the first and last, you get a smooth animation
div {
width: 150px;
height: 150px;
top: 20px;
background-image: url('https://s-media-cache-ak0.pinimg.com/originals/c2/bb/ae/c2bbaed0207deef5775af9c01e1b31ba.jpg');
position: relative;
background-size: cover;
animation: mymove 5s linear infinite alternate;
transform: rotate(0deg);
transform:translate3d
transition: all;
}
#-webkit-keyframes mymove {
from,
0% {
left: -150px;
transform: rotate(5deg)
}
20% {
transform: rotate(-5deg)
}
40% {
transform: rotate(5deg)
}
60% {
transform: rotate(-5deg)
}
80% {
transform: rotate(5deg)
}
100% {
left: 100%;
transform: rotate(-5deg)
}
}
<div></div>
If to use the same syntax as in your original CSS, one can combine the rules that has the same property/value, like this.
div {
width: 150px;
height: 150px;
top: 20px;
background-image: url('https://s-media-cache-ak0.pinimg.com/originals/c2/bb/ae/c2bbaed0207deef5775af9c01e1b31ba.jpg');
position: relative;
background-size: cover;
animation: mymove 5s linear infinite alternate;
transform: rotate(0deg);
transform:translate3d
transition: all;
}
#-webkit-keyframes mymove {
from,
0% {
left: -150px;
}
20%, 60%, 100% {
transform: rotate(-5deg)
}
0%, 40%, 80% {
transform: rotate(5deg)
}
100% {
left: 100%;
}
}
<div></div>

CSS radial / circular progress indicator with a transparent middle

I'd like to make a radial progress indicator with css that has it's middle circle transparent. See here: http://codepen.io/geedmo/pen/InFfd – it's a perfect example of what I want to do but the middle (.overlay) has background-color which overlays the bigger circle. However, I'd like to have it transparent (the bigger circle would have transparent middle too). How to do it?
<div class="wrap">
<div class="progress-radial progress-25">
<div class="overlay">25%</div>
</div>
<div class="progress-radial progress-50">
<div class="overlay">50%</div>
</div>
<div class="progress-radial progress-75">
<div class="overlay">75%</div>
</div>
<div class="progress-radial progress-90">
<div class="overlay">90%</div>
</div>
</div>
SASS:
// Colors
$barColor: tomato
$overlayColor: #fffde8
$backColor: #2f3439
#import url(http://fonts.googleapis.com/css?family=Noto+Sans)
body
padding: 30px 0
background-color: $backColor
font-family: 'Noto Sans', sans-serif
.wrap
width: 600px
margin: 0 auto
/* -------------------------------------
* Bar container
* ------------------------------------- */
.progress-radial
float: left
margin-right: 30px
position: relative
width: 100px
height: 100px
border-radius: 50%
border: 2px solid $backColor // remove gradient color
/* -------------------------------------
* Optional centered circle w/text
* ------------------------------------- */
.progress-radial .overlay
position: absolute
width: 60px
height: 60px
background-color: $overlayColor
border-radius: 50%
margin-left: 20px
margin-top: 20px
text-align: center
line-height: 60px
font-size: 16px
/* -------------------------------------
* Mixin for progress-% class
* ------------------------------------- */
$step: 5 // step of % for created classes
$loops: round(100 / $step)
$increment: 360 / $loops
$half: round($loops / 2)
#for $i from 0 through $loops
.progress-#{$i*$step}
#if $i < $half
$nextdeg: 90deg + ( $increment * $i )
border-image: linear-gradient(90deg, $backColor 50%, transparent 50%, transparent), linear-gradient($nextdeg, $barColor 50%, $backColor 50%, $backColor)
#else
$nextdeg: -90deg + ( $increment * ( $i - $half ) )
border-image: linear-gradient($nextdeg, $barColor 50%, transparent 50%, transparent), linear-gradient(270deg, $barColor 50%, $backColor 50%, $backColor)
This is the result I'd like to get:
html code :
<div class="wrapper">
<div class="pie spinner lightBlue"></div>
<div class="pie filler lightBlue"></div>
<div class="mask"></div>
</div>
css code :
body {
background-color: #f3f3f4;
}
.lightBlue {
border: 10px solid #a8d2d2;
}
.wrapper {
width: 250px;
height: 250px;
margin: 10px auto;
position: relative;
background: white;
background-color: #f3f3f4;
-webkit-transition: width 0.5s, height 0.5s;
transition: width 0.5s, height 0.5s;
-webkit-animation: finalRota 2s 10s linear forwards;
animation: finalRota 2s 10s linear forwards;
}
.wrapper .pie {
width: 50%;
height: 100%;
position: absolute;
background-color: radial-gradient(left center, circle, #00ccff 0px, #000088 100%);
-webkit-transform-origin: 100% 50%;
-ms-transform-origin: 100% 50%;
transform-origin: 100% 50%;
}
.wrapper .spinner {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
z-index: 200;
background-color: radial-gradient(right center, circle, #00ccff 0px, #000088 100%);
border-right: none;
-webkit-animation: rota 10s linear forwards;
animation: rota 10s linear forwards;
}
.wrapper .filler {
border-radius: 0 100% 100% 0 / 0 50% 50% 0;
left: 50%;
border: 10px solid #8dbdbb;
opacity: 0;
z-index: 100;
border-left: none;
-webkit-animation: fill 10s steps(1, end) forwards;
animation: fill 10s steps(1, end) forwards;
}
.wrapper .mask {
width: 50%;
height: 100%;
position: absolute;
background: inherit;
opacity: 1;
z-index: 300;
-webkit-animation: mask 10s steps(1, end) forwards;
animation: mask 10s steps(1, end) forwards;
}
#-webkit-keyframes opoFinalRota {
100% {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
}
#keyframes opoFinalRota {
100% {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
}
#-webkit-keyframes rota {
0% {
-webkit-transform: rotate(300deg);
transform: rotate(300deg);
}
100% {
-webkit-transform: rotate(60deg);
transform: rotate(60deg);
}
}
#keyframes rota {
0% {
-webkit-transform: rotate(300deg);
transform: rotate(300deg);
}
100% {
-webkit-transform: rotate(60deg);
transform: rotate(60deg);
}
}
#-webkit-keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#keyframes mask {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
#-webkit-keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
#keyframes fill {
0% {
opacity: 0;
}
50%, 100% {
opacity: 1;
}
}
and a demo : http://jsfiddle.net/usrs01ye/2/
Just set your $overlayColor variable to transparent
$overlayColor: transparent
Here's a working codepen

Resources