- Oh, man, I'm super
excited about this video mainly because it's current and fresh. So, my coworker sent me this screenshot. (upbeat music) And asked me if I could quickly put something together inside a CodePen, and you know, I am always
up for a challenge. Besides, new things always
make great YouTube videos. (upbeat music) If you're new to self tech me channel, my name is Amy Dutton. I'm a web designer and developer. If you're just getting into this space, sometimes it's hard to know where to start or what resources to trust. I wanna help you level up and
get to where you wanna be. If this sounds interesting to you, hit the subscribe button below. This is part five of a
multi-part series on SVGs. Check the description below for links to all the videos and a
link to the SVG playlist. So if you've seen any of the
other videos in this series, you'll know that I'm giving
away a free SVG cheat sheet that outlines these seven different ways you can get an SVG on a page. So, I'll include a link
in the description below. Last thing, before we jump in, I have timestamps in the description below if you wanna jump around. Let's do this. First, let's look at this screenshot in a little bit more detail. We have two circles, or I guess a donut is a better description since the center is missing. One circle is in the background, and the second circle sits on top, illustrating percentage
or progress being made. And then we have text
in the center of that. In the past, I probably would
have reached for CSS first, but SVGs actually make this even easier. Plus I don't think that that
rounded edge on the progress is even possible with CSS. If we were to do this in CSS, that progress bar would
have to have a flat edge. Okay, I'm gonna write this in CodePen. So if you've never used CodePen before, it's a code sandbox that is great for experimenting and
sharing code snippets. You can create an account for free, but of course, more money
will give you more features. The first thing that I'm going to do is to minimize the JavaScript panel. We're going to be doing
everything within HTML and CSS. Okay, let's start by stubbing out our SVG, and SVGs are namesakes. So boiled down, this
simply tells the browser what rules to apply when parsing the data. So the first thing that we're gonna say is xmlms equals HTTP, www.w3.org 2000/SVG. And then we'll do something similar, except this time we'll
say www.w3.org/1999 xlink. Perfect. Next we wanna establish
the width and height, otherwise the SVG would
fill whatever space for whatever container we give it. So I'm gonna say a width of 230 pixels and a height of 230 pixels. Notice we didn't have to
send it a unit of measure. So we're not specifying pixels, it knows that we're talking about pics. So next up, we need to define a view box. And if you'll remember
in a previous video, I said, and I never, never,
I never touched the view box. Well, in the previous
videos we've used SVGs that were exported from
Figma or Illustrator. This case is different because we'll be writing
our own from scratch, and we need to specify
what that view box is. All good, so let's take a hot minute and talk about some of the
fundamental concepts of SVGs. One minute on the clock. You can think of an SVG
as unlimited graph paper, or like the game of battleship, we're plotting points on a graph, D2, A1. The view box is like a
window into that graph paper. So part of the reason I said before, I never messed with the view box is because that changes your window. The first two values are
your x and y coordinates. Usually this will be zero,
zero, so think top left corner. The next two values are the x and y coordinates for
the bottom right point. And as long as the first
two values are zero, zero, you can think of this
as the width and height. So for our SVG, let's
say zero, zero, 230, 230. Awesome, so we're well on our way. Now for a circle, technically we could draw
a path within our SVG, but let's make this even
easier on ourselves. SVGs have a circle element built in. Okay, we wanted to find the coordinates for the center of our circle. So we can say cx equals
zero and cy equals zero. Next, we wanted to find the size or the radius of our circle. So we'll give it a radius of 100. Okay, so this is a perfect example of our view box at work. Our window isn't allowing us
to see the rest of the circle, and we can move it down by changing the center point
with our cx and cy values. So 115 is the exact center of 230. Okay, perfect. Kinda crazy how easy it is
to position and size that, and I think you can also see
how helpful this would be if you're plotting points on a graph. You could set the center point, and then adjust the radius
or the size of the point while keeping the location
of the point the same. Now, remember, we had a donut, so I'm going to remove the fill, set the stroke width to 25 pixels, set the stroke color to yes,
which is a very light gray. Easy peasy, right? Now, I'm going to duplicate our
circle for our progress ring except this time I'm going
to give it a color of red. Now, here's the part that
starts to get a little tricky. We need to adjust the red ring
for a progress percentage, and strokes and SVGs have
this really great property called stroke dash array that
allow you to create a dotted or a dashed line. So we can add this to our red circle by saying /-array equals, then it takes two values,
the length of the dash and the length of the gap. So I'm gonna say, 10, 10. So you have this nice
little piece of peppermint, and we can play around
with this a little bit. We can make our dash longer,
or we can make the gap longer. Maybe this visual will help. We wanna make the dash, the
entire length of the circle, and the gap, the entire
length of our circle. Then if we shift it or change our offset, it looks like our percentage is changing. I'll admit, at first, when
I was trying to build this, this whole concept was
really confusing to me. It does not help that I've forgotten a lot of geometry that I
learned in high school. So, stick with me. We wanna take the length of our circle, and this is called the circumference. And to do that, we need the radius. And that's the point from
the center of the circle to the outside edge. And now multiply that times two times PI. So fortunate for us, Google has a calculator that we can use. Let's plug in our radius. And remember, we set this inside our SVG when we've said r equals 100. So if I come back here and type in 100, you'll see 628.32. So perfect, I'm going to
use that value, so copy. And I'm going to plug
this into our dash array. Now, it looks like our circle is full since the dash is the
entire length of the circle. Okay, now let's change that first value, the length of our dash
to be 66% of our circle. So we wanna show the progress to be 66%. If we were gonna figure out 66% of 628.32, then we could say 628.32 times 0.66. So remember to calculate percentages, you have to move the
decimal over two places, or essentially divide 66
by 100, which is 0.66. So we can revise our calculation to account for dividing by 100, by saying 66 divided by 100 times 628.32. The great thing about SVGs
is there's a calc function which will actually do the math for us. So I can say calc 66
divided by 100 times 628.32. And I could do the calculation and use the actual value here, but if I leave it like this, then I can easily change
the value to say, 25% without having to open up my calculator. And plus, if we ever turn
this into a react component, we can easily pass in the percentage and let it do the calculation for us, because let's set this back to 66%. Okay, this is looking pretty good, except that we want the graph to start at the top and wrap around. So to rotate it, we can use
the transform attributes. I'm gonna say transform equals rotate, and I'll say negative 90 degrees. Huh? That's strange. When we did that, we lost
our red circle altogether. So, what happened? Well, it rotated the circle
outside of our view box. If we change the value
to something smaller and slowly increase the value, you will see it rotate off the screen. So I'm gonna say change
view and go into debug mode. Then if I pull up my Chrome dev tools, and we wanna grab our progress circle, and you can see here we
have transform rotate, negative 90 degrees. So let's override that. I'm gonna say transform rotate,
and let's say zero degrees. You'll see there's our progress circle. And if I slowly increase that, you can see it rotate off the screen. To compensate for this, we
need to add a translate value of negative 230 pixels, or
the width of our circle. Sweet, so just a few more things before we can call this done. We want the red circle
to have a rounded in. There's a property called stroke align cap that we can add and set it to round. Now, say, we want this to
animate in, fancy, I know. So this is probably easier than you think. And we can use CSS to change
the length of our dash. I'm going to give our red
circle a class of progress. Now, on the CSS panel,
we can hook onto it. Now, the first thing I wanna do is define our actual animations. So let's say key frames, animate, and this could actually be named anything. I've named it animate here,
but it could be bananas. And then we wanna say at 0%, so at the very beginning of our animation we want the dash in our
stroke rate to be zero. So say dash array zero, and
then it will animate to our 66%. And the gap still needs to be the circumference of our circle. So the progress will look
empty and it'll animate to 66%. Let's assign our animation
to the progress class. So I'm gonna say animation,
and we're gonna call animate since that's the name of our key frames. We want it to last one second,
and we want it to ease out and we only want it to go forwards. Now we just need to add the text to the center of our circle. So SVG has a text tag built
in, so we can create two, one for our number, and
one for our subtext. Next, we just need to position it. I'll set x to 115 since
that's exactly half of our 230 pixel circle. And I'll give y an arbitrary value of 110, and we can dial that in if we need to. Okay, so same for the subtext. Let's say x is 115 and we'll give y 135. So it's a little bit further down. Okay, not totally stellar, but we can tweak this within the CSS. So let's give our percentage,
a class of percentage. And in our subtext, a class of subtext. Then in our CSS, let's
target the percentage first. Right now our text starts at the center, but it's not really centered. So let's shift it over
with text anchor middle, and we want our text to be read. So normally with CSS, we'd
use the color property, but since this is an SVG,
we will use a fill instead, and let's make the font bigger. So the font size, 0.3 and a half from. And let's make this a Sans Serif font. So I'll say font family, Sans Serif. And let's make the weight bold. And now let's set our subtext styles. We can actually copy and
paste most of the styles from our percentage class over to subtext as a starting point, but
let's make the text black instead of red and let's change
the font size to one rem. Now, the cool part about this is our SVG can scale without any trouble. I can change the width
and the height to 100. And the view box stays the same and continues to manage our aspect ratio. So everything scales down and up perfectly without any additional code, so cool. Done. Done, done, done. All my code is on CodePen,
link in the description below. Feel free to download it,
fork it, copy it, tweak it, whatever, it's yours. If you like this video,
and wanna see more videos on web design and development, be sure to hit the subscribe button below, hit the bell icon to receive notifications when new videos are posted. Until then, be cool. (upbeat music) Many of you may or may not know, I work for a company called Zeal and they actually underwrite my channel. That's right, they wholeheartedly support what I'm doing on the YouTubes. Frankly, I don't know many
companies that do that. In fact, most companies
don't even want you to have side projects, but in my case, Zeal not only encourages
it, but they support it. Anyway, they're hiring. So if you're an engineer
and looking for a job or even if you're not, but
wanna work for a great company, plus you get to work with me, check out our website for the job listing. I'll include a link in
the description below.