Form does not rotate around center axis (x,y) - css

Even though I have set [transform-origin: 100% 50%;] in css, the form does not rotate around its center in comparison to X- and Y- axis.
Question: How can I make the form rotate counted exactly from its midpoint.
.box {
background-color: pink;
margin: 300px 0 0 300px;
width: 200px;
height: 200px;
}
.box {
position: absolute;
animation: spin 10s;
animation-fill-mode: forwards;
}
.line-horizontal {
background-color: black;
width: 200px;
height: 5px;
margin: 100px 0 0 0;
}
.line-vertical {
background-color: black;
width: 5px;
height: 200px;
margin: -105px 0 0 100px;
}
#keyframes spin {
from {
transform:rotate(0deg);
transform-origin: 100% 50%;
}
to {
transform:rotate(360deg);
}
}
<div class="box">
<div class="line-horizontal"></div>
<div class="line-vertical"></div>
</div>

Change the tranform-origin to 50% 50% instead which means the center in both axis and don't put it inside the keyframes because it will get animated
.box {
background-color: pink;
width: 200px;
height: 200px;
}
.box {
position: absolute;
animation: spin 10s;
animation-fill-mode: forwards;
transform-origin: 50% 50%;
/*center*/
}
.line-horizontal {
background-color: black;
width: 200px;
height: 5px;
margin: 100px 0 0 0;
}
.line-vertical {
background-color: black;
width: 5px;
height: 200px;
margin: -105px 0 0 100px;
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
<div class="box">
<div class="line-horizontal"></div>
<div class="line-vertical"></div>
</div>
You can also simplify your code like below in case you need the same visual:
.box {
width: 200px;
height: 200px;
background:
linear-gradient(#000,#000) center/100% 5px,
linear-gradient(#000,#000) center/5px 100%,
pink;
background-repeat:no-repeat;
animation: spin 10s forwards;
transform-origin: 50% 50%; /* OR center*/
}
#keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
<div class="box">
</div>

Related

CSS pie chart with background pattern [duplicate]

This question already has an answer here:
How to create a circular arc (sector) with a background image?
(1 answer)
Closed 2 years ago.
I'm trying to make a pie chart with PNG image as background-image there:
.piebg {
width: 95px;
height: 95px;
border-radius: 50%;
background-image: url('https://pngimg.com/uploads/pizza/pizza_PNG44095.png');
background-size: cover;
}
.pie {
width: 102px;
height: 102px;
border-radius: 50%;
background: inherit;
}
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: #fff;
transform-origin: left;
animation: spin 5s linear infinite, bg 5s step-end 1;
}
.pie::after {
content: '';
display: block;
height: 100%;
right: 50px;
border-radius: 100% 0 0 100% / 50%;
background-color: #fff;
position: relative;
top: -102px;
}
#keyframes spin {
to {
transform: rotate(.5turn);
}
}
#keyframes bg {
50% {
background: transparent;
}
}
<div class="piebg">
<div class="pie"></div>
</div>
There is an issue with the wrong fill of a pie chart area.
CSS animation is not a strong side of my experience yet to complete this example.
Could you help me to find an article or example how to complete my pie chart?
If you consider discontinuous animation, we can do this with only single div and mask.
.pie {
width: 95px;
height: 95px;
border-radius: 50%;
background-image: url('https://i.stack.imgur.com/tJMg9.png');
background-size: cover;
--s: 0%;
--mask: conic-gradient(#000 var(--s), transparent var(--s) 360%);
-webkit-mask: var(--mask);
mask: var(--mask);
animation: pie 2s forwards;
/* ↑ you can use "infinite" instead */
}
#keyframes pie {
10% {
--s: 10%;
}
20% {
--s: 20%;
}
30% {
--s: 30%;
}
40% {
--s: 40%;
}
50% {
--s: 50%;
}
60% {
--s: 60%;
}
70% {
--s: 70%;
}
80% {
--s: 80%;
}
90% {
--s: 90%;
}
100% {
--s: none;
}
}
<div class="pie"></div>
Also now we can make a continuous animation with #property
#property --s {
initial-value: 0%;
inherits: false;
syntax: '<percentage>';
}
.pie {
width: 95px;
height: 95px;
border-radius: 50%;
background-image: url('https://i.stack.imgur.com/tJMg9.png');
background-size: cover;
--s: 0%;
--mask: conic-gradient(#000 var(--s), transparent var(--s) 360%);
-webkit-mask: var(--mask);
mask: var(--mask);
animation: pie 2s 1s infinite;
}
#keyframes pie {
100% {
--s: 100%;
}
}
<div class="pie"></div>

Creating a gravity-like effect in CSS falling animation and calculating change of radius of a 'circle' when using rotateX

I have the following animation of a ball falling down and bouncing back up:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite linear;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0%,100% {
transform: translateY(0);
}
20% {
background-color: black;
transform: translateY(40px);
}
50% {
background-color: red;
transform: translateY(84px) rotateX(45deg);
}
70% {
background-color: black;
transform: translateY(40px);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>
As you can see, I tried to make the ball have a "squeezed" effect when it touches the ground. I had to use the translateX to 84px to maintain the touching of the ball with the ground. I got that 84px by trial and error. Is there a formula which I can use to calculate the offset (i.e. 4px in this case)?
The ball is falling at a linear speed, I've tried using ease-in and ease and it didn't work. I've also tried different numbers from cubic-bezier.com. How do I make it so that the velocity increases along with time because of gravitational acceleration and deceleration when it is bouncing back up?
Check solution below if you hate maths 1
Since you are rotating the element 45deg you are having something like this:
What you are looking for is the Green line which you can get with the following formula:
width/2 - X
Where
X = Width/2*cos(45deg)
so you will have Width/2*(1 - cos(45deg)) ~ Width/2*(1 - 0.707)
You can then adjust the percentage value to control velocity. As a side note, you should not get to initial value but a lower value to have a more realistic animation:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite ease-in;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0% {
transform: translateY(0);
}
30% {
background-color: black;
transform: translateY(80px);
}
40% {
background-color: red;
transform: translateY(calc(80px + 10px*(1 - 0.707))) rotateX(45deg);
}
50% {
background-color: black;
transform: translateY(80px);
}
100% {
background-color: black;
transform: translateY(50px);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>
1 You can also avoid the calculation by simply changing the transform-origin to rotate from the bottom thus the space will be reduced from the top:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite linear;
transform-origin:bottom;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0% {
transform: translateY(0);
}
30% {
background-color: black;
transform: translateY(78px);
}
40% {
background-color: red;
transform: translateY(80px) rotateX(45deg);
}
50% {
background-color: black;
transform: translateY(78px);
}
100% {
background-color: black;
transform: translateY(50px);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>
If you want to have a non-realistic bounce effect you can try this:
body {
margin: 0;
padding: 0;
}
.ball {
width: 20px;
height: 20px;
margin: 0 auto;
border-radius: 50%;
background-color: black;
animation: bounce 2s infinite linear;
transform-origin:bottom;
}
.ground {
display: block;
width: 100%;
border-bottom: 1px solid black;
position: absolute;
top: 100px;
}
#keyframes bounce {
0%,100% {
transform: translateY(0);
}
35%,65% {
background-color: black;
transform: translateY(40px);
}
45%,55% {
background-color: black;
transform: translateY(75px);
}
50% {
background-color: red;
transform: translateY(80px) rotateX(45deg);
}
}
<div class = "ball">
</div>
<div class = "ground">
</div>

How to stop progress bar animation halfway using Keyframes

I'm trying to load the progress bar up to a certain percentage. Whatever that percentage is, the progress bar will stop at that specific color animation specified in the keyframes.
How can i get it to work.
HTML
<div class="container">
<div class="progress-bar">
<span style="width:50%">
<span class="progress-value"></span>
</span>
</div>
<span><strong>CSS</strong></span>
<br/>
</div>
CSS
.container {
display: flex;
justify-content: center;
}
.progress-bar {
background-color: lightgray;
border-radius: 1.25em;
width: 300px;
height: 16px;
width: 50vw;
}
.progress-bar > span {
display: flex;
}
.progress-value {
background-color: #673ab7;
transition: 0.3s all linear;
border-radius: 1.25em;
height: 16px;
width: 50vw;
animation: progress-color 3s linear forwards;
-webkit-animation: progress-color 3s linear forwards;
}
/* animation */
#keyframes progress-color {
0% {
width: 0;
}
50% {
width: 30%;
background: purple;
}
100% {
background: green;
width: 100%;
}
}
#-webkit-keyframes progress-color {
0% {
width: 0;
}
50% {
width: 30%;
background:red;
}
100% {
background: green;
width: 100%;
}
}
Here's my codepen
https://codepen.io/mingsterism/pen/xJgePK
The problem is that where you have specified the animation is 100% completed under the #keyframes , there you must specify red as the color, which you have specified as the color you wish when the bar reaches 50%, while the rest of of the code is fine. Replace your piece of code with this one below and tell, is this what you want ?
#keyframes progress-color {
0% {
width: 0;
}
50% {
width: 30%;
background: green;
}
100% {
background: red;
width: 100%;
}
}
#-webkit-keyframes progress-color {
0% {
width: 0;
}
50% {
width: 30%;
background: green;
}
100% {
background: red;
width: 100%;
}
}

Is it possible to make CSS Pie timer run only once?

I use CSS Pie Timer, and I struggle to make my pie loading animation run only once.
The order I want the animation to be in:
the circle is not shown
the circle is starting to fill up with a border color
the circle get filled fully
the circle stays filled (and doesn't repeat)
Demo here
<div class="wrapper">
<div class="pie spinner"></div>
<div class="pie filler"></div>
<div class="mask"></div>
</div>
Help will be appreciated!
You just have to remove animation-iteration-count - infinite and add animation-fill-mode as forwards.
Here is the working code
.wrapper {
position: relative;
margin: 40px auto;
background: white;
}
.wrapper, .wrapper * {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.wrapper {
width: 250px;
height: 250px;
}
.wrapper .pie {
width: 50%;
height: 100%;
transform-origin: 100% 50%;
position: absolute;
background: #08C;
border: 5px solid rgba(0,0,0,0.5);
}
.wrapper .spinner {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
z-index: 200;
border-right: none;
animation: rota 5s linear forwards;
}
.wrapper:hover .spinner,
.wrapper:hover .filler,
.wrapper:hover .mask {
animation-play-state: running;
}
.wrapper .filler {
border-radius: 0 100% 100% 0 / 0 50% 50% 0;
left: 50%;
opacity: 0;
z-index: 100;
animation: opa 5s steps(1, end) forwards reverse;
border-left: none;
}
.wrapper .mask {
width: 50%;
height: 100%;
position: absolute;
background: inherit;
opacity: 1;
z-index: 300;
animation: opa 5s steps(1, end) forwards;
}
#keyframes rota {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes opa {
0% {
opacity: 1;
}
50%, 100% {
opacity: 0;
}
}
<div class="wrapper">
<div class="pie spinner"></div>
<div class="pie filler"></div>
<div class="mask"></div>
</div>

CSS circle border fill animation

I have a css file which makes circle border fill animation perfectly. Its in 100px width and height. But i need only in 50px width and height circle with the same animation. I tried many more times to minimize the size, but the circle not get correctly fix with animation. please help me to smaller this circle.
My need:
Width-50px
Height -50px
border size as per the image file attached -circle border fill sample image
My code
#loading
{
width: 100px;
height: 100px;
margin: 30px auto;
position: relative;
}
.outer-shadow, .inner-shadow
{
z-index: 4;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.inner-shadow
{
top: 50%;
left: 50%;
width: 80px;
height: 80px;
margin-left: -40px;
margin-top: -40px;
border-radius: 100%;
background-color: #ffffff;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.hold
{
position: absolute;
width: 100%;
height: 100%;
clip: rect(0px, 100px, 100px, 50px);
border-radius: 100%;
background-color: #fff;
}
.fill, .dot span
{
background-color: #f50;
}
.fill
{
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px, 50px, 100px, 0px);
}
.left .fill
{
z-index: 1;
-webkit-animation: left 1s linear ;
-moz-animation: left 1s linear ;
animation: left 1s linear both;
}
#keyframes left
{
0%{-webkit-transform:rotate(0deg);}
100%{transform:rotate(180deg);}
}
#-webkit-keyframes left
{
0%{-webkit-transform:rotate(0deg);}
100%{-webkit-transform:rotate(180deg);}
}
.right
{
z-index: 3;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.right .fill
{
z-index: 3;
-webkit-animation: right 1s linear ;
-moz-animation: right 1s linear ;
animation: right 1s linear both ;
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
#keyframes right
{
0%{-webkit-transform:rotate(0deg);}
100%{transform:rotate(180deg);}
}
#-webkit-keyframes right
{
0% {transform: rotate(0deg);}
100% {transform: rotate(180deg);}
}
My code in jsfiddle...!
You need to divide by 2 every values involved, even the clip(); ones (fiddle updated)
#loading {
width: 50px;
height: 50px;
margin: 30px auto;
position: relative;
}
.outer-shadow,
.inner-shadow {
z-index: 4;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.inner-shadow {
top: 50%;
left: 50%;
width: 40px;
height: 40px;
margin-left: -20px;
margin-top: -20px;
border-radius: 100%;
background-color: #ffffff;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.hold {
position: absolute;
width: 100%;
height: 100%;
clip: rect(0px, 50px, 50px, 25px);
border-radius: 100%;
background-color: #fff;
}
.fill,
.dot span {
background-color: #f50;
}
.fill {
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip: rect(0px, 25px, 50px, 0px);
}
.left .fill {
z-index: 1;
-webkit-animation: left 1s linear;
-moz-animation: left 1s linear;
animation: left 1s linear both;
}
#keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(180deg);
}
}
.right {
z-index: 3;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.right .fill {
z-index: 3;
-webkit-animation: right 1s linear;
-moz-animation: right 1s linear;
animation: right 1s linear both;
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
#keyframes right {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes right {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
.inner-shadow img {
margin-left: 8px;
margin-top: 7px;
}
<div id='loading'>
<div class='outer-shadow'>
</div>
<div class='inner-shadow'>
</div>
<div class='hold left'>
<div class='fill'></div>
</div>
<div class='hold right'>
<div class='fill'></div>
</div>
</div>
edit: in respond to comment #Filipe
How would the change from clip to clip-path be? I tried (also changing rect to inset), but the animation stops working.
Possible example with clip-path instead clip .
#loading {
width: 50px;
height: 50px;
margin: 30px auto;
position: relative;
}
.outer-shadow,
.inner-shadow {
z-index: 4;
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.inner-shadow {
top: 50%;
left: 50%;
width: 40px;
height: 40px;
margin-left: -20px;
margin-top: -20px;
border-radius: 100%;
background-color: #ffffff;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.hold {
position: absolute;
width: 100%;
height: 100%;
clip-path: polygon(50% 0, 0 0, 0 100%, 50% 100%);
border-radius: 100%;
background-color: #fff;
}
.fill,
.dot span {
background-color: #f50;
}
.fill {
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
clip-path: polygon(50% 0, 100% 0, 100% 100%, 50% 100%);
}
.left .fill {
z-index: 1;
-webkit-animation: left 1s linear;
-moz-animation: left 1s linear;
animation: left 1s linear both;
}
#keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes left {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(180deg);
}
}
.right {
z-index: 3;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
transform: rotate(180deg);
}
.right .fill {
z-index: 3;
-webkit-animation: right 1s linear;
-moz-animation: right 1s linear;
animation: right 1s linear both;
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
#keyframes right {
0% {
-webkit-transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
#-webkit-keyframes right {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(180deg);
}
}
.inner-shadow img {
margin-left: 8px;
margin-top: 7px;
}
<div id='loading'>
<div class='outer-shadow'>
</div>
<div class='inner-shadow'>
</div>
<div class='hold left'>
<div class='fill'></div>
</div>
<div class='hold right'>
<div class='fill'></div>
</div>
</div>
is this what you expect,hope this will help to you.try this.I only concerned about the circle size of 50 px with inside circle.if this is not the case tell me.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>jquery</title>
<style type="text/css">
div.circleone{
width: 50px;
height: 50px;
border-radius: 25px;
box-shadow: 1px 2px 1px black;
}
div.circletwo
{
width: 25px;
height: 25px;
border-radius: 12.5px;
box-shadow: 1px -1px 1px black;
position: relative;
top: 25%;
left: 25%;
}
</style>
</head>
<body>
<div class="circleone">
<div class="circletwo"></div>
</div>
</body>
</html>

Resources