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.
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
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!
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 video Kevin! To position the circles around the image, I came with this solution: CSS: .container { --outline-radius: 400px; width: calc(var(--outline-radius) * 2); aspect-ratio: 1; border-radius: 50%; background: lightcoral; position: relative;
.item { --item-radius: 100px; width: calc(var(--item-radius) * 2); aspect-ratio: 1; border-radius: 50%; background: lightblue; position: absolute; display: grid; place-content: center; left: calc((var(--outline-radius) - var(--item-radius)) + ((var(--outline-radius) - var(--item-radius)) * sin((var(--position) - 1) * (360deg / var(--quantity))))); bottom: calc((var(--outline-radius) - var(--item-radius)) + ((var(--outline-radius) - var(--item-radius)) * cos((var(--position) - 1) * (360deg / var(--quantity))))); } } HTML: 1 2 3 4 5 6 7 8 With this solution, no need to had-coding and the items are positioned in a perfect circle. I enjoyed the challenge very much. Thanks for your great job.
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. 🤓
@@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.
_"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.
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) ); } }
@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).
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().
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?
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
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....)
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.
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!
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.
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.
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 ♥
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 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.
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!
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 :)
I know this is 2 years old. But the formula is x = cos(angle) * radius and y = sin(angle) * radius. So for example, since you have 8 circles, angle increases by 360deg / 8 for each. Radius is distance from center. Your case would be with a --radius of 10rem and a --count of 8: transform: translate( calc(var(--radius) * cos(var(--item-index) * 360deg / var(--count))), calc(var(--radius) * sin(var(--item-index) * 360deg / var(--count))) ); Set all the li's to that and you can just set the --item-index to the item index. for example, li{ transform } li:nth-child(1){--item-index:1}
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)?
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
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 :)
Very cool, thanks for sharing! sin() and cos() and maybe some others are even coming to CSS too, but it would have been nice to show them in this case, since I was using SCSS already.
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!
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.
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.
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
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.
Hey Kevin, just wanted to let you know if you don't already, TH-cam's auto CC is still capturing "Friend and Friends" in all your videos. I think that's hilarious. Amazing content as usual! 😄
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.
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🎉
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?
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 :)
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.
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))
25:25 this is what happiness and winning looks like. Ouou! Also - business idea! You should do extra hard challanges and let sadists fund it. :) "Come on, dude, watch me pain!"
Well... the trick is using math actually. All of the circles should be at the same distance from the center, and four of them at the 45, 135, 225 and 315 deg respectively. 45 degree right triangle has a hypotenuse of length sqrt(2) times the legs, so if the distance from the center is 15rem, and the angle equals 45, the translate values should actually be 15/sqrt(2), so about 10.6067rem. And they told us Pythagorean theorem wouldn't be useful in real life ;)
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
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: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?
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 :)
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!
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
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!
Great video Kevin! To position the circles around the image, I came with this solution:
CSS:
.container {
--outline-radius: 400px;
width: calc(var(--outline-radius) * 2);
aspect-ratio: 1;
border-radius: 50%;
background: lightcoral;
position: relative;
.item {
--item-radius: 100px;
width: calc(var(--item-radius) * 2);
aspect-ratio: 1;
border-radius: 50%;
background: lightblue;
position: absolute;
display: grid;
place-content: center;
left: calc((var(--outline-radius) - var(--item-radius)) + ((var(--outline-radius) - var(--item-radius)) * sin((var(--position) - 1) * (360deg / var(--quantity)))));
bottom: calc((var(--outline-radius) - var(--item-radius)) + ((var(--outline-radius) - var(--item-radius)) * cos((var(--position) - 1) * (360deg / var(--quantity)))));
}
}
HTML:
1
2
3
4
5
6
7
8
With this solution, no need to had-coding and the items are positioned in a perfect circle.
I enjoyed the challenge very much. Thanks for your great job.
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.
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)
);
}
}
@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).
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.
🎉 🥳 Congratulations on 500,000+ Subscribers Kevin! 🎊 🍻
🎉
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?
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.
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....)
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.
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 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!
This is the most fun i ever had on any follow along tutorial.
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.
Very useful 😄Thanks Kevin ✌🏻
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.
this is actually what im looking for. thanks 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 ♥
By far the best CSS content on TH-cam!
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 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.
Hey Kevin, these types of videos are the best...Please make some more of these types!
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!
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 :)
What an epic adventure. Great work!
Just got an A in Web Dev 230 thanks in great part to your videos. Thank you! 🙏🏻
I remember doing this exact animation 4-5 years ago for a client in pure css. It was awesome....
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 love this! no googling is an artform :D
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.
Fantastic video, thanks kevin 👍
Congratulations on your 500k plus subscribers
I know this is 2 years old. But the formula is x = cos(angle) * radius and y = sin(angle) * radius. So for example, since you have 8 circles, angle increases by 360deg / 8 for each. Radius is distance from center. Your case would be with a --radius of 10rem and a --count of 8:
transform: translate(
calc(var(--radius) * cos(var(--item-index) * 360deg / var(--count))),
calc(var(--radius) * sin(var(--item-index) * 360deg / var(--count)))
);
Set all the li's to that and you can just set the --item-index to the item index. for example, li{ transform } li:nth-child(1){--item-index:1}
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)?
I honestly learned a lot here, I'll keep watching your channel!
Greatest video ever I love to see mistakes makes me feel human
Thank you Kevin! Your work are really inspiring!
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
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 :)
AMAZING JOB! It was enjoyable watching this like watching an action movie! Congratz!
love this type of videos, make more of like these one
You can use math.sin and math.cos to calculate exact placements of the circles.
I did something like this:
@use 'sass:math';
$number: 30; // number of circles
$each: math.div(360deg, $number);
$radius: 300px;
$size: 20px;
.parent {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
> li {
position: absolute;
height: $size;
width: $size;
background-color: red;
display: block;
border-radius: 50%;
}
@for $i from 1 through $number {
li:nth-child(n + #{$i}) {
transform: translate(math.sin($each * ($i - 1)) * $radius, math.cos($each * ($i - 1)) * $radius * -1);
}
}
}
Very cool, thanks for sharing!
sin() and cos() and maybe some others are even coming to CSS too, but it would have been nice to show them in this case, since I was using SCSS already.
@@KevinPowell I hope so. I was looking for a CSS solution, so those coordinates could be calculated on the fly using CSS variables, but no luck.
I think i need to rethink my decision to code lmao
I was watching this on TV when the TH-cam apocalypse happened. Now I'm too invested and want to know how to do this so hey from my mobile
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!
You amaze me Kevin. Your skills are inspiring.
Excellent - took me 2 days to get this fully
Phenomenal work Kevin!
You are the CSS guru
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
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.
that was super cool, good problem solving skills, thank you!
Thank u Mr. Powell
Damn this is insane! 🙌🏼🙌🏼
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.
I bet you that the original creator took more than 2 days to make this, you are the king 😊
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.
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
Thank you Kevin
Hey Kevin, just wanted to let you know if you don't already, TH-cam's auto CC is still capturing "Friend and Friends" in all your videos. I think that's hilarious. Amazing content as usual! 😄
this is literally what I want to do for my app.
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.
You are an inspiration!
you are amazing! great video as always
Awsome job!
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🎉
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?
Really cool !
Thanks Kevin! also improve my english listen to you! Great video, and success copy design jeje
So cool!
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 :)
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.
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
Positions on a circle.
x = cx + r * cos(a)
y = cy + r * sin(a)
@kevin 1:27:22 - you have got a variable typo "--thob-play-state"
You can use the Pythagorean theorem to find the coordinates!
25:25 this is what happiness and winning looks like.
Ouou! Also - business idea! You should do extra hard challanges and let sadists fund it. :)
"Come on, dude, watch me pain!"
AWESOME
Amazing video!!
"THE" smile at 25:35 😁😁😁😁😁😁
Well... the trick is using math actually. All of the circles should be at the same distance from the center, and four of them at the 45, 135, 225 and 315 deg respectively. 45 degree right triangle has a hypotenuse of length sqrt(2) times the legs, so if the distance from the center is 15rem, and the angle equals 45, the translate values should actually be 15/sqrt(2), so about 10.6067rem.
And they told us Pythagorean theorem wouldn't be useful in real life ;)
Or 15 * sin(pi / 4)
oh, we're getting sin and some other math functions in CSS soon, that could work well here!
I knew it was math, I just had no idea what the math was, lol. Thanks for sharing :D
@@KevinPowell you inspire me to get better at css, so I'm happy i could give something back
Trigonometry, Kevin; you're looking for trigonometry 🙂 translate(distance * cos(angle), distance * sin(angle)) . sass:math lets you use trig functions, too
Kinda funny that at about 30 minutes you were struggling to make them a circle and I am sitting here like SOH CAH TOA. XD
Thanks!
Thank you so much!
daaaam, that's crazy
Thanks so much
Appreciate. Awesome thanks 👍
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
Me: "they're upside down because you have rotate 0.5 right here!" *points with mouse ...."no, right here!"
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;
}
}
Brilliant!
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.
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?
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 :)
So the circle bit is basic trig. Use SOH-CAH-TOA pick your angle and plug in the radius. Then solve for the 2 points x and y.
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!
reverse pythagorus to find the unknown side. the square root of the hypoteneuse squared minus the x or y value that you know