Can I create this tricky orbiting icon animation?
HTML-код
- Опубликовано: 9 июл 2024
- You can find details on my upcoming course here: beyondcss.dev
🔗 Links
✅ The original design I'm trying to copy: seamlesshr.com/
✅ My code: github.com/kevin-powell/seaml...
✅ How I compile my Sass in this video: • Stop using an extensio...
✅ Visbug: chrome.google.com/webstore/de...
⌚ Timestamps
00:00 - Introduction
01:08 - Getting started
02:49 - Writing the HTML
06:02 - Generating the colours
14:09 - Starting to style things
15:22 - The center image
19:35 - The li circles
43:24 - Adding the rotation
01:04:20 - Pausing the animation on hover
01:08:51 - Adding the throbbing animation
#css
--
Come hang out with other dev's in my Discord Community
💬 / discord
Keep up to date with everything I'm up to
✉ www.kevinpowell.co/newsletter
Come hang out with me live every Monday on Twitch!
📺 / kevinpowellcss
---
Help support my channel
👨🎓 Get a course: www.kevinpowell.co/courses
👕 Buy a shirt: teespring.com/stores/making-t...
💖 Support me on Patreon: / kevinpowell
---
My editor: VS Code - code.visualstudio.com/
---
I'm on some other places on the internet too!
If you'd like a behind the scenes and previews of what's coming up on my RUclips channel, make sure to follow me on Instagram and Twitter.
Twitter: / kevinjpowell
Codepen: codepen.io/kevinpowell/
Github: github.com/kevin-powell
---
And whatever you do, don't forget to keep on making your corner of the internet just a little bit more awesome!
The `scale:` property worked for me because I had the Experimental Web Platform features flag turned on in Chrome. It is supported in Firefox and Safari, but still behind a flag in Chrome as they work out performance issues from the bug reports I looked at. If you'd like to enable it, you can find the flag by going to chrome://flags and searching for it in the search that shows up.
Did. D him lol
Hey ! if you work with degrees a circle is 360°, you have 8 circle then each circle must be at 45° from each other (8 * 45° = 360).
Then u can use sin() and cos(), basically sin() gives u the distance on the Y axes and cos() on the X axes, your translate will be : translate( (15 * cos(45 * i)) rem , (15 * sin(45* i) rem) where i is the number of the circle you are curently looping on !
@@gaetanvitrac4179 yeah and maybe you could just use sin and cos to change their position changing their angle bit by bit based on the speed you want to rotate it at
The 'rotate' as well in 45:29 as well. It required the Experimental Web Platform flag to turn on
Hey Kevin, your videos actually helped me go from "I wish I was writing JS" to "This is not so bad" when talking about CSS, thanks again for making them!
So happy to hear that!
Man, you really inspire me as a frontend dev. Anything that I don't know or forgot I would always go to your channel. Thank you so much Kevin
After googling: how to find the coordinates of a point on a circle, I noticed that to get the position of the translate property for the even lis, you need to multiply the radius by 0.707 (which is the sin of 45º). So, it would be 15rem * 0.707 = 10.605rem. 🤓
you can get the same answer through the pythagorean theorem.
x^2 + x^2 = 15^2
x^2 = (15^2)/2
x = ((15^2)/2)^0.5 = 10.61
@@manneg Pythagorean is working only because there are 8. The general way is to use trigonometry. 12rem*cos(360/8*n) for the X, where 8 is the nomber of circles you want to place. For Y, it is the same formula but with sin instead of cos.
@@amandinelevecq6664 well, yes. In this case i was just showing that you don't need trigonometry to figure out the right answer. This was the solution that immediately came to mind so I thought I'd share.
15/sqrt(2)
_"how to find the coordinates of a point on a circle"_
x = (cos(angle) * some multiplier depending on how big you want the circle to be) + origin x.
y = (cos(angle) * some multiplier depending on how big you want the circle to be) + origin y.
I used a different approach, to build something similar:
Inside each I used inline-style variables, which helped me to build a perfect circle using calc( ).
.flex {
position: relative;
display: grid;
place-content: center;
width: 350px;
height: 350px;
}
.flex span {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: rotate(calc(80deg * var(--i))); >>this formula lets build a perfect circle, without using transform: translate( ) in each tag.
}
My code: codepen.io/esmeralddedushaj/pen/KKZbPOE
really cool
cool
Brother has 300IQ
maybe use attr() instead of style?
Kevin your videos are amazing. I've learned so much from them. Also love this format, where we get to see the process and the mistakes along the way. It's very relatable! Keep up the good work!
To arrange the items in a perfect circle, instead of hardcoding magic numbers in translate(), we could use rotations, which allows us to even have an arbitrary number of items!
$item-count: 8;
@for $i from 1 through $item-count {
$angle: (360deg / $item-count) * $i;
.item:nth-child(#{$i}) {
transform:
translate(-50%, -50%)
rotate(calc(-1 * #{$angle}))
translate(15rem)
rotate(#{$angle});
}
}
The first "translate" is just for centering.
The magic happens in the remaining 3 transforms:
The first "rotate" causes the X axis itself to be rotated.
So, the subsequent "translate" now moves the element not horizontally, but along the angle by which we rotated!
With this, the element is now at the right location, but it still looks rotated.
So the last "rotate" is opposite to the first one - now the element visually has no overall rotation!
Sandwiching the "translate" between two opposite rotations this way allows us to translate along any direction with a fixed distance.
Using "translate" without the two "rotate"s would require us to know the exact X and Y distances to translate with, which can only be calculated using cos() and sin().
cos() and sin() are on their way to CSS, and I could have done this with Sass, if I'd had any idea about how to actually do it, lol.
you can do several translates on one transform? I didnt know that, that is awesome!
For those wondering, ~10.61 is the value you want to rotate on the 45 degree items. Though my self I would love to see this in a loop like like shown here. I have a strong tenancy to want to generalize and hardcore nothing.
How would animating the counter rotation work if we code this example. Should the animation include everything from you transform and then on top of that out rotate() that will be changing value?
@@yordanpopov7080 Yes, all the transforms would have to be repeated for each keyframe within an animation.
Hey Kevin,
I really love your work. You did make me fall in love with CSS. I get to learn a lot from your work. Keep making such awesome videos.
this is actually what im looking for. thanks kevin!
Phenomenal work Kevin!
What an epic adventure. Great work!
Very useful 😄Thanks Kevin ✌🏻
Hey Kevin, these types of videos are the best...Please make some more of these types!
🎉 🥳 Congratulations on 500,000+ Subscribers Kevin! 🎊 🍻
🎉
wanted to do something like this for 3 days straight and i gave up trying and you posted this video in the right time , thank you so much man i love you ♥
I've watched so many of your videos so far, I'm the frontend developer I am today because of your channel, thank you so much. I finally enjoy and love coding CSS.
Great to hear!
I honestly learned a lot here, I'll keep watching your channel!
Fantastic video, thanks kevin 👍
Congratulations on your 500k plus subscribers
Great video! The math problem of getting the correct x and y was a fun challenge. Ended up coming up with this in sass as possible solve, could probably be tided up so it's a bit more re-usable the 45deg is 360 divided by number of list items.
@for $counter from 0 through 7 {
li:nth-child(#{$counter + 1}) {
transform: translate(
15rem * math.cos(45deg * $counter),
15rem * math.sin(45deg * $counter)
);
}
}
AMAZING JOB! It was enjoyable watching this like watching an action movie! Congratz!
By far the best CSS content on RUclips!
that was super cool, good problem solving skills, thank you!
Thank you Kevin! Your work are really inspiring!
love this type of videos, make more of like these one
This is the most fun i ever had on any follow along tutorial.
Awsome job!
Damn this is insane! 🙌🏼🙌🏼
you are amazing! great video as always
@1:32:10 -
At the bottom of the window, and above the "&:hover", there's "--thob-play-state: play;", which was supposed to be "--throb-play-state: play;"
Missing the 'r' in the "--thob-..."
---
No big deal! Kevin, I've learned so much from your videos, but the best thing I've learned is how to just tinker and forget about making mistakes; mistakes are important, and they help us gain wisdom alongside knowledge. Your approach is so calming that it makes me more excited to fidget around! I've been dev'ing since 1996, as a hobby, side projects, and as a freelancer. You inspire me to keep up with the newer updates to the design cores and adapt to not living in the past (no, I'm not still using for layouts, lol).
Really cool !
For positioning of all icons could set the li width and height to 36rem, then center to body below the woman/man images. The image icon and paragraph will need an extra wrapping [ul > li > div.icon-12rem > (img, p)] that will be 12rem diagonally circle translated to right (and its rightmost point aligned to the li rightmost side). Then to place the other list items you rotate them (if they are only 8, by 360/8 * [0....7] = 0, 45, 90, 135, 180, 225, 270, 315) and counter rotate the li > div.icon-12rem wrappers (with 0, -45, -90....)
I'm a junior frontend dev and you inspires me a lot not to give up challenges using only css. keep on making more contents pls.
This channel literally made me turn from pulling my hair out working with CSS to having uncontrollable urges to style my friends projects because he doesn't care to make it look nice 😂. Thanks Kevin!
Amazing video!!
You amaze me Kevin. Your skills are inspiring.
So cool!
Very cool! I hope you do more videos like this one in the future.
One thing that could be an interesting general video topic is a discussion of how to recreate things that are standard in javascript into CSS, and how to tell when you should and should NOT be using javascript instead of CSS.
You are an inspiration!
Great video!
Btw, you can use a negative animation-delay on the itens, so that the animations will be offset from each other but will not have the start delay when the page refreshes.
For the exact radial placement, coordinate formula is: (x, y) = (radius*sin(radian(angle)), radius*cos(radian(angle))). I don't know if sass supports trigonametric functions but in your case, a for loop can be defined where the radius is 15rem with 45-degree angle incremenents.
You inspired me to go through this challenge. Turns out, the most difficult part is math for list item coordinates, especially when you are trying to animate their moving and expanding at the same time.
Thank u Mr. Powell
Brilliant!
Awesome presentation! In the end it seemed to be "simple", but the moments in between when you went on like "why is this moving" reminded me again why I'm no frontend developer - I'm not gonna try it, I prefer to keep my sanity, or what's left of it.
Thank you Kevin
Appreciate. Awesome thanks 👍
AWESOME
Excellent - took me 2 days to get this fully
I remember doing this exact animation 4-5 years ago for a client in pure css. It was awesome....
Just got an A in Web Dev 230 thanks in great part to your videos. Thank you! 🙏🏻
I love this! no googling is an artform :D
Kevin...you're amazing and you deserve all the praise and followers! That laugh...at 17:14 ...I haven't laughed that hard this year!
🤣🤣 I didn't even really notice that when editing, lol
I think to determine the position of each options is to use pythagorean theorem, using the constant radius as your base and the angle as the space for each. :)
Overall, great work. I learned a lot , thanks :)
Greatest video ever I love to see mistakes makes me feel human
Thanks Kevin! also improve my english listen to you! Great video, and success copy design jeje
A lot of new stuff to learn from this video, thanks! Just one question - why the has to have both width and height. If I unset width - nothing changes, if I also unset height - the image moves a little bit down, but the animation continues working (all the items are at the same position)?
In cases like this, my first reaction is to open the developer tools and see how they did it.
For practice doing without that is better. But afterwards, I would still do it to compare.
Would be nice to see that comparison for this case.
Either way, I learn. So it's all good.
Thank you master Kevin.
Thanks so much
This is why trigonometry is useful folks, the translates should be r cos((360/n)*c) , r sin((360/n)*c) where n is the number of evenly spaced points c is the specific point you are translating and r is the length between the center!
Shucks I knew custom properties were the way to go, didn't know about rotate: 1turn either, good idea. As always I love your presentation and speaking style! I posted my solution to my youtube channel and codepen :3 It's amazing how wildly different our solutions are. Thank you for the challenge!
Always fun when there are more than one way to approach things like this :D
Thanks!
Thank you so much!
I bet you that the original creator took more than 2 days to make this, you are the king 😊
Great video, followed along coding my own project using straight CSS as I am not familiar with SASS. Something I will look at doing through udemy when I get a chance
Question - How do you fix the issue of adjusting the CSS when the page goes full screen without having to manually refresh the page to fix it? Do you have to use JS to solve this issue?
It's fun to see the unedited process but I'm glad this isn't live, I'm still screaming "translate-origin" at my monitor.
Hey Kevin, just wanted to let you know if you don't already, RUclips's auto CC is still capturing "Friend and Friends" in all your videos. I think that's hilarious. Amazing content as usual! 😄
Call PBS. A modern-day Bob Ross. Well done!
If you want merch ideas you could do a "var(--thob-play-state)" t-shirt :P You were missing an r.
Also, for the record, you continue to help fortify my newfound love CSS. I really hope to be as good as you someday but for now I am still only a few weeks into my journey.
To make the item appear in a circle could you have set the XY using (0,15), (0,-15), (15,0), (-15,0) and then "pre rotated" every other one 45 degrees. I am thinking this would work provided the rotation happened while the center was still the center of the content and not the center of the individual item. Much like what was happening around 53:10
You are the CSS guru
daaaam, that's crazy
make a big circle that all the little circles are attached to. spin the big circle. rotate the icons in the opposite direction at the same pace, and add a scale pulse animation to the little circles. easy peasy :)
I was watching this on TV when the RUclips apocalypse happened. Now I'm too invested and want to know how to do this so hey from my mobile
Loved this video! Just as an idea, wouldn't it be also possible to create both the circle and animation using sin & cos functions? I think that'd be easier to maintain and manipulate.
A few people have said that would be the better way to do it, yes :D
Thanks for this long and very interesting video, I learned a lot again.
Question: Why did you write the rule for the hover of the center image as &:not(:first-child):hover and not &:last-child:hover? I tried it, both work identical in this case. But you probably had a reason to use the more complicated way with :not, did you?
I think I would each circle as a watch hand, origining from the center of the image (with the actual hand/line invisible) and the circle absolute positioned at the end of each hand.
Then divide 360 / number of circles, and rotate each watch hand by the corresponding value.
Something like that should work in theory.
Was thinking. If you make the ul 1 pixel the rotating corner would just be rotating at the same point?
1:03:00 If I remember my webGL and other comp sci stuff for graphics wouldn't you want to apply a rotation for each with incrementing values of angles around the circle, then apply the same translate to move them away from the center?
So hard. Thanks sir
makasih suhuu
At 1:12:45 you actually don't need the helper div that is surrounding the div around the img tag. You can just give the list item the corresponding background color (and adjust some minor other things). All in all, this works much better because you can avoid having multiple animations (with different transforms) on the same object (which leads to problems if the browser doesn't support scale: X and rotate: X but only transform: scale(X), ...).
With this solution, you can simply "rotate" the ul, img and p (the latter 2 in reverse mode) and "throb" the li-item and get the same result but much cleaner without having to deal with multiple transform/rotates :)
(And also as some other's also pointed out, you can compute the exact positions using sin and cos)
I'd have to dive back in and play with it... I thought I had to have that extra one, because the transform-origin on them, I can't reverse-spin them in place properly, but I could easily have mucked it up as I went and overthought it. I'll take another look at it :)
cant you put transforms together like in computer graphics?
when doing this (lil circle position) with transformation matrices i would rotate 45 degrees and then move outward, then 90 degrees and out, and so on. To unturn the icons i would just transform back.
but i dont know if thats a thing in css. it seams VERY burdensome to do it like you did. What if you want to add an icon, or rotate all of them, or something, seams like a hassle.
Also, can you acess the "n" in nth child? so you can do stull like that programmatically?
it makes me shiver seeing all the hardcode haha
You could also just have them all have the same translation from the center and let them start part way through the orbit animation. Using a negative animation delay starts the animation right away but still advances it to specified point in the animation. You can also use custom properties to avoid using the rotate and scale properties.
Untested example:
transform: translateX(15rem) rotate(--ball-rotation) scale(--ball-scale);
transform-origin: -15rem;
animation: orbit var(--speed) var(--orbit-delay) linear reverse infinite,
throb 1s var(--throb-delay) ease-in-out infinite alternate;
--orbit-delay: calc(-1 * (var(--speed) / var(--numberOfBalls)) * var(--ballIndex))
oh, never thought about a negative delay. I like the idea :D
Do you have a video or somewhere I can find answers for my problem please?
What I'm trying to do is to save space because I have multiple html labels (5 at most) and I'm trying to stack them in one like "Label1 +4" and when I hover on is I want to show the other labels around it, like in the video, I don't need all the animation but just the transition to make them appear with transition (explosion?).
While I'm writing this, I think that I might find what I need somewhere in this particular video (?)
I was thinking about the positions of the items - after your struggle with transforms. This might have been an option:
li {
position: absolute;
}
li:nth-child(1) {
top: 0;
left: 0;
}
li:nth-child(2) {
top: 0;
margin-left: 50%;
transform: translate(-50%);
}
li:nth-child(3) {
top: 0;
right: 0;
}
And continue doing this with all the other items. While typing this, this might not be a great idea due to the animation (that's probably why you used transform), but it could be possible.
I came very close to using top and left/right, but still using transforms to move them. I thought I'd have to at one point actually.
Hello, i'm wondering if it's possible to make each ''.orbit li:nth-child() '' ( bubbles around main image ) linkable to a website or something else? I've been trying to figure it out, but it usually connects 2 of them together and doesn't let me fix. Hope someone can answer me.
a²+b²=c² is your friend for this simple circle. The 45s should be at 10.6rem 10.6rem.
Proof:
a² + b² = 15rem²
a² + b² = 225rem
(a = b for 45°)
2a² = 225rem
(divide both sides by 2)
a² = 112.5rem
a = sqrt(112.5)rem
a ~ 10.6rem
This was the first thing I though of!
As a programmer, watching an obviously talented UI designer struggle with basic concepts in trigonometry was instructive.
this is literally what I want to do for my app.
Big fan
Hey, I'm trying to study this code. It loads fine in different browsers, but there is no orbiting or any other movement. It that because the SASS requires some kind of compile?
I hate css, but that was pretty cool. Definitely good to know about managing state with custom properties, I will definitely use that in the future.
Kevin maybe you can use the inheritance for the pause animation when its hover on
for example :
.parent{
&:hover{
animation-play-state: paused;
.child{
animation-play-state: inherit;
}
}
1:04:03 u didnt do anything wrong Kevin. Just the other circles needed to be translated to 10.6rem, 10.6rem. Pythagoras theorem, Euclidean distance. great video🎉
Weirdly in Chrome rotate() and scale() don't work for me as alone properties. They work only inside "transform" property but when I use transform, they're mixing up other existing things, for example translate(). Everything is fine in Mozilla tho :)
When you were toying with whether to do the central image(s) as a background or not, considering they are purely decorative (as you defined them) would background image not be the better choice as it would remove them from the HTML? (Yes, I understand that very few if any people look at HTML without CSS/JS - but still).
In this case, I think either one would be fine.
For the paragraph in the li is there a reason to use opacity:0 and instead of display:none
Trigonometry, Kevin; you're looking for trigonometry 🙂 translate(distance * cos(angle), distance * sin(angle)) . sass:math lets you use trig functions, too
Do You think that parcel-bundler is still ok or should we use new Parcel for sass processing?
It depends? lol. I hate that answer, but it's usually true. I wouldn't migrate an old project just for the fun of it, but for a new one I probably go with the current release.
Ohhh this theme is crazy! Can you tell me how can i find it?
Hey Kevin! For the angled circiles the translate value is 11.25rem
First thought was: cmon, there’s nothing difficulties at all. But then I’m noticed css) I could easily do this with swift on ios, but css.. I have no idea how could I do that) Nicely done!