i want to make a animation for a circle that splits open on two sides:
kind of like the 🎊 emoji flipped upside down. I have two half circle elments and i put them next to each other. I tryed to animate one of the sides but its not really what im going for, i wanted the split to pivot on the bottom of the semi-circle not in the middle. Since the circle is split and right next to each other in two when you rotate one of the halfs it overlaps, i didnt attempt to fix it yet (i was think move it to the left/right over the animation but i dont know...).
.circlecontainer {
display: flex;
justify-content: center;
align-items: center;
}
.halfright {
width: 150px;
height: 300px;
border-top-right-radius: 150px;
border-bottom-right-radius: 150px;
background: orange;
}
.halfleft {
width: 150px;
height: 300px;
border-top-left-radius: 150px;
border-bottom-left-radius: 150px;
background: orange;
animation: splitleft 3s;
}
#keyframes splitleft {
0% {
transform: rotate(-0deg)
}
100% {
transform: rotate(-90deg)
}
}
<div class="circlecontainer">
<div class="halfleft"></div>
<div class="halfright"></div>
</div>
thats it! I hope this makes sense since its hard to explain...
You're looking for transform-origin
.circlecontainer {
display: flex;
justify-content: center;
align-items: center;
}
.halfright {
width: 150px;
height: 300px;
border-top-right-radius: 150px;
border-bottom-right-radius: 150px;
background: orange;
animation: splitright 3s;
transform-origin: bottom left;
}
.halfleft {
width: 150px;
height: 300px;
border-top-left-radius: 150px;
border-bottom-left-radius: 150px;
background: orange;
animation: splitleft 3s;
transform-origin: bottom right;
}
#keyframes splitleft {
0% {
transform: rotate(-0deg)
}
100% {
transform: rotate(-90deg)
}
}
#keyframes splitright {
0% {
transform: rotate(0deg)
}
100% {
transform: rotate(90deg)
}
}
<div class="circlecontainer">
<div class="halfleft"></div>
<div class="halfright"></div>
</div>
Transforms will always rotate, scale, etc. from the center of the div (by default). In this case you want to pivot from where the circles meet at the bottom, use transform-origin to do this:
.circlecontainer {
display: flex;
justify-content: center;
align-items: center;
}
.halfright {
width: 150px;
height: 300px;
border-top-right-radius: 150px;
border-bottom-right-radius: 150px;
background: orange;
transform-origin: bottom left; /* THIS ONE!! */
animation: splitright 3s forwards;
}
.halfleft {
width: 150px;
height: 300px;
border-top-left-radius: 150px;
border-bottom-left-radius: 150px;
background: orange;
transform-origin: bottom right; /* THIS ONE!! */
animation: splitleft 3s forwards;
}
#keyframes splitleft {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-90deg);
}
}
#keyframes splitright {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(90deg);
}
}
<div class="circlecontainer">
<div class="halfleft"></div>
<div class="halfright"></div>
</div>
Related
I want to:
Align the circle (containing exclamation mark) with the dashed vertical line.
Make the circle bounce along the vertical line while changing the height of the dashed vertical line accordingly.
Can you please tell me how can I achieve that in CSS? thank in advance.
.pin{
display:inline-block;
align-contents: center;
}
.circle {
color: #ffffff;
background: #ff5500;
width: 30px;
height: 30px;
border-radius: 50%;
text-align: center;
font-size: 25px;
font-weight: bold;
display: inline-block;
animation: blinkingBackground 1s infinite;
}
#keyframes blinkingBackground {
0% {
opacity: 0;
transform: translateY(-10px);
}
25% {
opacity: 0.025;
transform: translateY(10px);
}
50% {
opacity: 0.05;
transform: translateY(-10px);
}
75% {
opacity: 0.075;
transform: translateY(10px);
}
100% {
opacity: 1;
}
}
.vline{
border-left: 1px dashed orangered;
height: 50px;
position: relative;
}
<div class="pin">
<div class="circle">
!
</div>
<div class="vline"></div>
</div>
#1 Align circle with line
For your .vline class add those two properties. Width in order to have the one pixel width from your border. And margin: 0 auto will center your div inside the parent div.
width: 1px;
margin: 0 auto;
#2 Reduce height while bouncing
Just add another animation to your .vline class.
In the example below I also changed the height from 50px to 0, that's keeping the .vline at zero pixels after animation is done. And instead I'm setting at keyframe 0% the height to 50px.
Depending on how many pixels you want to reduce it, you will need more keyframes. In the example I've reduced the height by 10px per second, so I have 5 keyframes with 10px steps.
#keyframes reduceHeight {
0% {
height: 50px;
}
20% {
height: 40px;
}
40% {
height: 30px;
}
60% {
height: 20px;
}
80% {
height: 10px;
}
100% {
height: 0px;
}
}
And here the working example
.pin{
display:inline-block;
align-contents: center;
}
.circle {
color: #ffffff;
background: #ff5500;
width: 30px;
height: 30px;
border-radius: 50%;
text-align: center;
font-size: 25px;
font-weight: bold;
display: inline-block;
animation: blinkingBackground 1s infinite;
}
.vline{
width: 1px;
margin: 0 auto;
border-left: 1px dashed orangered;
height: 0;
position: relative;
animation: reduceHeight 5s;
}
#keyframes blinkingBackground {
0% {
opacity: 0;
transform: translateY(-10px);
}
25% {
opacity: 0.025;
transform: translateY(10px);
}
50% {
opacity: 0.05;
transform: translateY(-10px);
}
75% {
opacity: 0.075;
transform: translateY(10px);
}
100% {
opacity: 1;
}
}
#keyframes reduceHeight {
0% {
height: 50px;
}
20% {
height: 40px;
}
40% {
height: 30px;
}
60% {
height: 20px;
}
80% {
height: 10px;
}
100% {
height: 0px;
}
}
<div class="pin">
<div class="circle">
!
</div>
<div class="vline"></div>
</div>
It's not perfect yet and you'll have to play around with positionings (maybe even have to add them to the animations), depending on what exactly you wanna acchieve. But it should give you a general idea and ONE possibility on how to do it. There might be different methods to do the same.
So I've tried separating the animations with a comma and having them on the same transform but it still doesn't work.
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 100%;
background: silver;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 20%;
height: 20%;
background-color: pink;
transform: rotate(0deg) translatey(0px);
animation: wavy 3s linear infinite alternate,
float 3s linear infinite alternate;
}
#keyframes wavy {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(-10deg);
}
100% {
transform: rotate(10deg);
}
}
#keyframes float {
0% {
transform: translatey(0px);
}
50% {
transform: translatey(-20px);
}
100% {
transform: translatey(0px);
}
}
<div class="container">
<div class="box"></div>
</div>
And here's a link to the codepen:
https://codepen.io/FaroukHamadi/pen/OJOWWKW
Yes - add an id to the div and set that animation on the specified id. For your example, I called it #box
EDIT ~ the id solution I had previously worked flawlessly UNLESS there are two transforms being used in the keyframe which is your case. What I would suggest is just combining the two animations into one animation and using more % increments. So instead of 0, 50, and 100, you can use 0, 25, 50, 75, 100 - to combine the two and have it seem like they are "alternating"
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 100%;
background: silver;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 20%;
height: 20%;
background-color: pink;
transform: rotate(0deg) translatey(0px);
animation: wavy-float 3s linear infinite alternate;
}
#keyframes wavy-float {
0% {
transform: rotate(0deg):
}
25% {
transform: rotate(-20deg);
}
50% {
transform: translateY(-20px);
}
75% {
transform: rotate(20deg);
}
100% {
transform: translateY(20px)
}
}
<div class="container">
<div class="box"></div>
</div>
Problem
I've made a simple css animation, but it's not behaving as I expect it.
The idea is for the animation to draw a straight line (from top downwards) , and the disappear (also from the top downwards).
The start of the line moves down a bit, as the animation starts, then up again to stay at set position (same goes for the bottom at the end of the animation).
Question
How do I get the start of the line to stay at one position instead of 'bouncing' down and up?
Expected behavior
Actual behavior
Code
.lineWrapper {
width: 1px;
height: 300px;
margin: auto;
position: relative;
}
.lineWrapper .line {
width: 100%;
height: 100%;
background: #000;
animation: scrollLine 5s linear infinite;
}
#keyframes scrollLine {
0% {
transform: scaleY(0);
}
10% {
transform: scaleY(0);
transform-origin: top;
}
30% {
transform: scaleY(1);
}
70% {
transform: scaleY(1);
}
90% {
transform: scaleY(0);
transform-origin: bottom;
}
100% {
transform: scaleY(0);
}
}
<div class="lineWrapper">
<div class="line"></div>
</div>
Codepen
https://codepen.io/strazan/pen/RwPYgjq
The default transform-origin is center so if you omit it in the initial and last state it will be set to center. You need to also have an instant change of the transform-origin in the middle:
.lineWrapper {
width: 1px;
height: 300px;
margin: auto;
position: relative;
}
.line {
height: 100%;
background: #000;
animation: scrollLine 5s infinite;
}
#keyframes scrollLine {
0%,10% {
transform: scaleY(0);
transform-origin: top;
}
49.9% {
transform: scaleY(1);
transform-origin: top;
}
50% {
transform: scaleY(1);
transform-origin: bottom;
}
90%,100% {
transform: scaleY(0);
transform-origin: bottom;
}
}
<div class="lineWrapper">
<div class="line"></div>
</div>
I have made similar CSS animation with some different code lines.
body {
margin: 0px;
display: flex;
justify-content: center;
background: black;
overflow: hidden;
}
.line-wrapper {
height: 800px;
width: 8px;
background: tranparent;
display: flex;
justify-content: center;
animation: down 2s linear infinite;
}
#keyframes down {
0% {
transform: translateY(0px);
}
15% {
transform: translateY(0px);
}
30% {
transform: translateY(0px);
}
60% {
transform: translateY(90px);
}
90% {
transform: translateY(115px);
}
100% {
transform: translateY(115px);
}
}
.line {
height: 8px;
width: 4px;
background: Gray;
animation: scrollLine 2s ease-in-out infinite;
}
#keyframes scrollLine {
100% {
height: 800px;
}
}
.eraser {
height: 0px;
width: 4px;
background: black;
animation: rmv 2s linear infinite;
}
#keyframes rmv {
55% {
height: 0px;
}
100% {
height: 800px;
}
}
<div class="line-wrapper">
<div class="line">
<div class="eraser"></div>
</div>
</div>
I've made a heart with CSS and made it resize, go small - big every second, like normally. But I noticed this strange wobble, that I didn't really put there and is really painful to look at. I aware of few possible duplicate questions, but they didn't really help. Here's a fiddle.
html,
body,
.container {
height: 100%;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
.heart {
display: flex;
justify-content: center;
align-items: center;
background-color: red;
transform: rotate(-45deg);
transform-style: preserve-3d;
animation: growMain 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.heart:after,
.heart:before {
background-color: red;
content: "";
border-radius: 50%;
position: absolute;
transform: translateZ(-1px);
}
.heart:after {
animation: growAfter 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.heart:before {
animation: growBefore 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
#keyframes growMain {
from {
width: 50px;
height: 50px;
}
to {
width: 80px;
height: 80px;
}
}
#keyframes growAfter {
from {
left: 25px;
width: 50px;
height: 50px;
}
to {
left: 40px;
width: 80px;
height: 80px;
}
}
#keyframes growBefore {
from {
top: -25px;
width: 50px;
height: 50px;
}
to {
top: -40px;
width: 80px;
height: 80px;
}
}
.inner {
display: initial;
transform: rotate(45deg);
}
.text {
text-align: center;
color: white;
font-family: "Comic Sans MS";
font-size: 100%;
margin: 0;
}
<div class="container">
<div class="heart">
<div class="inner">
<p class="text">Some text</p>
</div>
</div>
</div>
Animating actual width/height/position tends to not perform super well, especially when doing multiple animations at once like you are here. Moving/resizing elements with transform tends to perform better.
In this case, I would recommend setting the initial size of your heart and then using a scale transformation to make the pulse effect. With this approach, you also get the added benefit of going from three animations to one, which is easier for the browser to handle, and you don't have to worry about syncing them all up.
In order to make the text not shrink along with the heart, you can put a wrapper around it, and absolutely position the text in the center of the wrapper, on top of the heart. Then just transform the heart itself, not the wrapper. (Or if you want the text to shrink along with the heart, keep the same HTML structure you have now.)
html,
body,
.container {
height: 100%;
}
.container {
display: flex;
justify-content: center;
align-items: center;
}
.heart-wrapper {
position: relative;
width: 80px;
height: 80px;
}
.heart {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background-color: red;
transform: rotate(-45deg) scale(1);
transform-style: preserve-3d;
animation: pulse 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.heart::before {
left: 40px;
}
.heart::after {
top: -40px;
}
.heart::after,
.heart::before {
background-color: red;
content: "";
width: 80px;
height: 80px;
border-radius: 50%;
position: absolute;
transform: translateZ(-1px);
}
#keyframes pulse {
from {
transform: rotate(-45deg) scale(1);
}
to {
transform: rotate(-45deg) scale(0.6);
}
}
.text {
position: absolute;
top: 40%; /* slightly off-center to the top, so it appears centered when the heart shrinks */
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: white;
font-family: "Comic Sans MS";
font-size: 100%;
margin: 0;
}
<div class="container">
<div class="heart-wrapper">
<div class="heart"></div>
<div class="text">some text</div>
</div>
</div>
So I'm doing this for some lines on my webpage.
#keyframes dropHeader {
0% {
height: 0px;
}
100% {
height: 100%;
}
}
.slant-decor {
left: 50%;
height: 100%;
position: fixed;
display: inline-flex;
animation-name: dropHeader;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 0.6s;
}
.slant-decor:after {
width: 5px;
height: 100%;
background-color: rgba(0, 0, 0, 0.55);
content: "";
position: relative;
margin-left: -5px;
transform: skewX(-30deg);
display: inline-block;
}
.slant-decor div {
width: 19px;
height: 100%;
display: inline-block;
margin-left: -4px;
-ms-transform: skewX(-30deg); /* IE 9 */
-webkit-transform: skewX(-30deg); /* Safari */
transform: skewX(-30deg); /* Standard syntax */
}
.decor-orange {
background-color: orange;
}
.decor-red {
background-color: red;
}
.decor-green {
background-color: green;
}
<div class="slant-decor">
<div class="decor-red"></div>
<div class="decor-orange"></div>
<div class="decor-green"></div>
</div>
As of right now, the animation on .slant-decor works fine, however - as you can see, it causes a kind of a weird effect on the lines. What I'd like to achieve is that the animation follow the skew angle aswell, creating an effect where the lines would slide in from the top of the page, at the right angle. How could I achieve this?
If my understanding is correct, setting a transform-origin: right top would produce the effect that you are looking for. The default value for transform-origin is 50% 50% (the center-mid point of the element). When you animate the height, this point is constantly changing and hence creates that weird effect. If the transform-origin is set to a point that is fixed then that problem would be avoided.
#keyframes dropHeader {
0% {
height: 0px;
}
100% {
height: 100%;
}
}
.slant-decor {
left: 50%;
height: 300px;
position: fixed;
display: inline-flex;
animation-name: dropHeader;
animation-iteration-count: 1;
animation-timing-function: ease-out;
animation-duration: 0.6s;
}
.slant-decor:after {
width: 5px;
height: 100%;
background-color: rgba(0, 0, 0, 0.55);
content: "";
position: relative;
margin-left: -5px;
transform-origin: right top;
transform: skewX(-30deg);
display: inline-block;
}
.slant-decor div {
width: 19px;
height: 100%;
display: inline-block;
margin-left: -4px;
transform-origin: right top;
transform: skewX(-30deg);
}
.decor-orange {
background-color: orange;
}
.decor-red {
background-color: red;
}
.decor-green {
background-color: green;
}
<div class="slant-decor">
<div class="decor-red"></div>
<div class="decor-orange"></div>
<div class="decor-green"></div>
</div>