Div elements to follow a curved path with CSS3
Finding points on ellipse and translating:
If your oblong circle resembles an ellipse then you can find points on the ellipse using mathematical formula and then translate each div
element to that particular point.
Mathematical formula for calculating point (x,y)
on an ellipse is(a * cos(t), b * sin(t))
. In this formula, a
represents the radius of the ellipse in x-axis, b
represents the radius of the ellipse in the y-axis and t
represents the angle in radians. Angle in radians = Angle in degrees * pi / 180.
To make use of this approach, we do the following:
- Place the
div
elements absolutely at the centre point of the ellipse. - Calculate the
(x,y)
corresponding to each angle and translate thediv
to its place by usingtransform: translateX(...) translateY(...)
. The angles are in steps of 22.5 deg because there are a total 9 elements to be placed within 180 degrees.
.container { position: relative; height: 400px; width: 600px; padding: 12.5px; border: 1px solid; border-radius: 50%;}div > div { position: absolute; top: 0px; left: 0px; height: 50%; width: 50%; transform-origin: bottom right;}div > div:after { position: absolute; content: ''; bottom: 0px; right: 0px; height: 25px; width: 25px; background: black; border-radius: 50%; transform: translateX(50%) translateY(50%);}div > div:after { background: red;}div > div:nth-child(n+4):after { background: orange;}div > div:nth-child(n+7):after { background: green;}div > div:nth-child(1) { transform: translateX(-300px) translateY(0px);}div > div:nth-child(2) { transform: translateX(-277.17px) translateY(-76.5px);}div > div:nth-child(3) { transform: translateX(-212.13px) translateY(-141.42px);}div > div:nth-child(4) { transform: translateX(-114.80px) translateY(-184.77px);}div > div:nth-child(5) { transform: translateX(0px) translateY(-200px);}div > div:nth-child(6) { transform: translateX(114.80px) translateY(-184.77px);}div > div:nth-child(7) { transform: translateX(212.13px) translateY(-141.42px);}div > div:nth-child(8) { transform: translateX(277.17px) translateY(-76.5px);}div > div:nth-child(9) { transform: translateX(300px) translateY(0px);}
<div class="container"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div></div>
CSS - Animate object in curved path
Maybe make parent element move by rotate and children (in my case pseudoelement, whatever) make position absolute to the parent. And just use animation. Look at my solution. Maybe you will have to create some wrapper and use overflow: hidden
, because it is square which is rotating. You can watch square's behavior by adding background-color
.
@keyframes move-sun { from { transform: rotate(0deg); } to { transform: rotate(90deg); }}
.sun { position: relative; width: 400px; height: 400px; margin: 200px; transform: rotate(90deg); animation: move-sun 10s;}
.sun::before { content: ""; position: absolute; top: -25px; left: -25px; width: 50px; height: 50px; background-color: #ff0; border-radius: 50%;}
<div class="sun">
</div>
Move a div in a curved path (like tweening in Flash old days)?
Edit: Here's a work in progress that packages up the second concept described below as a re-usable JS object. You can edit the code or visually drag the curve to see the resulting code:
http://phrogz.net/SVG/animation_on_a_curve.html
I'd personally use SVG, which makes this sort of thing (animating along an arbitrary Bézier curve) trivial using the <animateMotion>
element. As a bonus, you can even cause it to calculate the rotation for you. Some examples:
- http://www.w3.org/TR/SVG/images/animate/animMotion01.svg
- https://developer.mozilla.org/en/SVG/Element/animateMotion
- http://devfiles.myopera.com/articles/76/SolarSystem.svg
Note that you don't even have to actually use SVG to display the result; you could simply create an off-screen SVG with this animation and sample the transform of the animated element to get your desired point/rotation.
Alternatively (if you don't want the rotation, or want to calculate it yourself while controlling the rate of traversal) you can create an SVG path and just use getPointAtLength()
/getTotalLength()
to find where you should be along the path at a given percentage of the total traversal distance. With this you don't even need an SVG document:
// Moving along an S curve from 0,0 to 250,450
var p = document.createElementNS('http://www.w3.org/2000/svg','path');
p.setAttribute('d','M0,0 C350,20 -200,400 250,450');
var len = p.getTotalLength();
for (var i=0;i<=100;i+=10){
var pct = i/100;
var pt = p.getPointAtLength(pct*len);
console.log( i, pt.x, pt.y );
}
// 0 0 0
// 10 65.54324340820312 10.656576156616211
// 20 117.17988586425781 49.639259338378906
// 30 120.2674789428711 114.92564392089844
// 40 100.49604034423828 178.4400177001953
// 50 78.06965637207031 241.1177520751953
// 60 63.526206970214844 305.9412841796875
// 70 74.59959411621094 370.6294860839844
// 80 122.1227798461914 415.8912658691406
// 90 184.41302490234375 438.8457336425781
// 100 250 450
Now all you have to do is set the .style.top
and .style.left
of your <div>
or <img>
appropriately. The only 'hard' part is deciding what you want to the curve to look like and defining where to put the handles.
Can I create a div with a Curved bottom?
CSS:
div{
background-color:black;
width:500px;
height:50px;
border-bottom-left-radius:50%;
border-bottom-right-radius:50%;
}
see is this ok for you
div {
background-color: black;
width: 500px;
height: 50px;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
}
<div>
</div>
Curve bottom side of the div to the inside with CSS
Simply use border-radius
and rely on some overflow. You can also consider pseudo element to avoid extra markup:
.container { margin: 0 auto; width: 500px; height: 200px; background: lightblue; position: relative; overflow: hidden;}
.container:after { content: ""; position: absolute; height: 80px; left: -10%; right: -10%; border-radius: 50%; bottom: -25px; background: #fff;}
<div class="container"></div>
How to make inverted rounded corners and bend content to follow curved container
You should post also complete code, it is not always enough with CSS. (Enlico already commented this to you).
Anyway, a posible solution would be this, moving the elements in a vertical amount to make them rotate:
.container {
width: 100%;
position: relative;
top: 200px;
}
.element {
position: absolute;
background-color: tomato;
left: 50%;
transform: translateY(-400px) rotate(var(--angle)) translateY(400px) rotate(calc(-1 * var(--angle)));
}
.element:nth-child(1) {
--angle: 50deg;
}
.element:nth-child(2) {
--angle: 30deg;
}
.element:nth-child(3) {
--angle: 10deg;
}
.element:nth-child(4) {
--angle: -10deg;
}
.element:nth-child(5) {
--angle: -30deg;
}
.element:nth-child(6) {
--angle: -50deg;
}
<div class="container">
<div class="element">item 1</div>
<div class="element">item 2</div>
<div class="element">item 3</div>
<div class="element">item 4</div>
<div class="element">item 5</div>
<div class="element">item 6</div>
</div>
Create a dotted path that follows a curve
Here's an example of how this can be done using SVG <path>
elements, <use>
elements, a <mask>
element, the stroke-dasharray
attribute, and the stroke-linecap
attribute.
You can define a single <path>
element once, and then reuse it multiple times with different stroke styles or masks applied to it, which is especially handy in this case.
body { background: darkblue; }
<svg viewBox="0 0 515 515">
<defs>
<mask id="mask">
<rect fill="black" x="0" y="0" width="515" height="515"></rect>
<rect fill="white" x="0" y="200" width="515" height="315"></rect>
</mask>
<path id="path" fill="none" d="M138 414C192.333 414 312.8 414 360 414C419 414 504 262 360 262C216 262 261 262 153 262C45 262 39 130 144 130C249 130 327 130 378 130C429 130 452 83 452 -2C452 -87 472 -87 452 -87"></path>
</defs>
<!-- solid wide line -->
<use href="#path" stroke="rgba(255,255,255,0.2)" stroke-width="20"></use>
<!-- solid narrow line -->
<use href="#path" stroke="rgba(255,255,255,0.2)" stroke-width="10"></use>
<!-- dotted full line -->
<use href="#path" stroke="rgba(255,255,255,0.2)" stroke-width="5" stroke-dasharray="0 10" stroke-linecap="round"></use>
<!-- dotted masked line -->
<use href="#path" stroke="rgba(255,255,255,0.8)" stroke-width="5" stroke-dasharray="0 10" stroke-linecap="round" mask="url(#mask)"></use>
</svg>
How to animate a ball along the curved path using css3 animation?
This is not a complete solution to your Question, but you asked for how can I define a path
in css animation, so this is how you can:
JSFIDDLE
div.ball {
background : green;
width:20px; height:20px;
border-radius:50%;
-webkit-animation: myOrbit 4s linear infinite; /* Chrome, Safari 5 */
animation: myOrbit 4s linear infinite; /* Chrome, Firefox 16+,IE 10+, safari 5 */
}
@keyframes path {
0% { transform: translateX(10px) }
10% { transform: translateX(0px) translateY(20px)}
20% { transform: translateX(20px) translateY(40px)}
30% { transform: translateX(50px) translateY(52px)}
40% { transform: translateX(150px) translateY(50px)}
}
If you see at the code you are actually defining the path for the ball to move as X,Y
Related Topics
Efficient and Inefficient CSS Selectors (According to Google, Pagespeed ...)
How Necessary Are CSS3 Vendor Prefixes Right Now
Web Fonts and Providing Fallback Fonts
How to Align Input and Label from Collection_Check_Boxes
CSS3 Question: How to Have No Box Shadow on The Top of a Div
Any Way to Save a CSS Diff Rather Than Save The Entire Stylesheet in Chrome Dev Tools
Animating Elements Sequentially in Pure CSS3 on Loop
Why Is Browser Showing Td's Larger Than My Specified Width Property
Rotating a Svg with CSS (Animation)
CSS Effect to Render a Font with "Rubber Stamp" Effect
CSS "Transform: Rotate()" Affecting Overall Design with "Position: Absolute" (Not Aligning Properly)
Where to Put CSS3 Media Queries
CSS Color Names + Alpha Transparency