2.1 Bubble Bevel
In this project, we’ll create some bubbly blue beveled text. We’ll cover some of the essentials of working with SVG text, such as filters and fill methods.
2.1 Bubble Bevel
Hey, welcome back to Five SVG Text Projects. In this lesson, we're gonna be creating this bubble bevel effect that you see on the screen right now. This one is a little bit simpler than the other four projects that we're gonna be creating. In this one, we're gonna focus on getting across some of the basic components of working with SVG in the way that we're going to be in this course. So we're gonna start with the starter file named bubblebevel.html that you find in the source files that come along with this course. So go ahead and open that up in Atom editor or whichever editor you decided to go with, and let's start coding. Now, let's just quickly take a look at the code that we already have here in the starter file. So you can see here we have these svg tags. So these defines where the SVG that we're working with starts and finishes. And then down here, we have a text element. Within that text element, we have the text that's showing up on our screen. We've just got a couple of sizing parameters that is setting the size and the position of our text on our screen. Now up here we also have this defs element. And this is where we're gonna define a bunch of filters, gradients and other things that we're gonna use to style our text. Inside this defs element, this is where you define all the things that you're going to use in your SVG. So we're gonna start by defining a linear gradient. We're gonna give a blue linear gradient to our bevel text. So to do that, inside our defs element, we're gonna type linearGradient, With a big G. We're gonna give an id so that we can target it to have it applied to our text. So we're gonna say id=fillGradient. And then inside this linearGradient, we're gonna add a couple of stops. So we're gonna add a stop at the top end of the text and a stop at the bottom end of the text. And each one of those stops is gonna have two different colors. So we'll add a stop tag, and then inside it, we're gonna set the offset to 0%. So this first stop is going to be at the beginning of our text. Then we're gonna give it a stop color. And we're going to use an RGB code here. I'm just gonna copy and paste this in. So we've got rgb 48, 212, 255, with an opacity of 1. Now you can see there I have pigments, the plugin that we were talking about earlier shows you exactly what that color is gonna be. Now we need to add another stop, we just copy and paste that code. This stop is gonna be at 100%. And this rgb code, Is going to be 7, 0, 149. Now in order to apply that gradient to our text, we're going to use the fill property. So inside our text here, we're gonna add fill =, and then we're gonna say url. And we're gonna tell it to look for an internal reference with this URL and that is our ID of fill gradient. So we're gonna add a hash and then say FillGradient. And now when we save you see that FillGradient applied to a our bevel text, right? So there we go. Now, at the moment you can see that, that FillGradient is running from left to right but we wanted to run from top to bottom. So going back to our code, what we're gonna do is up here in our linear gradient, we're gonna add gradient transform. I'm gonna set that to rotate. And inside the brackets we'll add 90 for a 90 degree rotation. Now, when we save, there we go we have our linear gradient running from top to bottom. So that's how you provide a linear gradient fill for text in an SVG. Now we're gonna move on to creating our actual bevel effect that you see here. Where we have the puffy edges, the shadow around the bottom edges and the lighting around the top edges. And the way we're gonna do that is by creating something called a filter. With a filter, you can do all kinds of different things to an SVG object. And you're gonna see a lot of these things as we work through our lessons. So once again, inside our defs elements, let's make some space, we're going to create a filter element. And like we did with our gradient, we're gonna give it an ID so we can apply it. We'll give it the id bevel. And now we're just going to add a couple of parameters that make sure that the sizing of the filter that we apply matches the sizing of the text. So we're gonna say filterUnits = userSpaceOnUse. We're gonna set the x and y positions of this filter to 0. And we're gonna set the width and height to 100%. Now that we have our filter with an ID, we can apply that to our text. So do that in the similar way to how we added a fill, only this time we're gonna say filter=url and then we'll provide it with the ID, so we'll say #Bevel. Now, inside this filter element, this is where we're gonna start setting up our bevel effect. The way that we're gonna do that is by stacking up a heap of what is called primitives. So each primitive is an individual effect that can then be combined with other effects stacked on top of each other and mixed together to create your final result. The first thing that we need to do in order to create a bevel effect is to create basically a bump map. So what a heart map is, is effectively a duplicate of your main image, which in this case is our text. But it provides information on what parts of that text should be higher, or should be made to seem higher, and what parts of the text should seem further away. So we're gonna create this bump map by making a duplicate vertex that's completely black, and then we're just gonna blur around the edges. So then the parts that are blurred around the edges are going to be made to seem further away, as we see in our finished product here. So we see we have all around the edges, it's made to look further away. And the solid black parts in the core of the letters is gonna be made to seem closer, so let's put that together. We're gonna do it by creating a Gaussian Blur primitive. So we're gonna say, feGaussianBlur then we're gonna close off that element. And it's actually a little bit more readable if you stack all the properties of your primitives one on top of the other inside the element. And now we're gonna feed in the alpha channel of our text. Now actually before I do that, I'm just gonna show you what the alpha channel of our text looks like by itself. There's another perimeter called feMerge, and that basically lets us create a bunch of different layers that stack on top of each other like they would find in Photoshop, for example. So we're gonna add feMerge. And then inside it we're gonna create a merge node, so feMergeNode. We're gonna give it an input which is in for short. And we're gonna say SourceAlpha. The source is whatever you've applied the filter to. And the alpha is the alpha channel of that source. So we'll just close off that node. Now when I save, you'll see the source alpha show up. So there you go, the alpha channel for this is just a black version of the text that we already had. That just shows which part of the source graphic is transparent and which part is not. So now we'll go back to gradient our GaussianBlur. Just gonna comment out this feMerge. And now what we're gonna do is plug in that source alpha as the input for our GaussianBlur. Now we need to tell the system how much we want to blur our source alpha by. So we're gonna add stdDeviation, standard deviation, and we're gonna set it to 5. So now when we save, let's see our results. So you can see that everything is blurred all around the edges here. And where that blurring is, that's where you're gonna see the beveling happen in our final image. Now what we wanna do is take that bump map that we just created by blurring source alpha, and we're going to apply some lighting to it. So in order to that, we need to give the result that this blur has created a name, then we can take that name and we can use it in the next filter primitive. So we're gonna say result="blur". I'm gonna copy in the next lighting primitive. So if you wanted to do the same thing, if you wanna copy and paste this next primitive in, you can grab the completed project version of this file. So we're gonna add in a specular lighting primitive. So what we are doing here is we are plugging in that blur that we just created, that's our input. We are using these settings here to determine how the lighting is going to be applied to the blur effect. We are setting the lighting color to a blue color, so you can imagine that we have a blue spotlight shining on the blurred text that we just created, and then nested inside our SpecularLighting primitive. We have a point light. You can actually simulate a few different kinds of lighting in SVG. In this case, we're just gonna be working with a point light. And these three parameters here let you specify where in the simulation of 3D space that the SVG is gonna use, that point light would be located. And then finally, we're outputting the result with the name specula. So let's uncomment our merge down here again. And we're gonna take this Specular result and we're gonna show it inside a merge node here. Now we'll save. And now you can see that we've got our lighting applied, and we're starting to get that bevel effect. With what we've got so far, the blue light that we just created is being applied to the whole SVG, but we're gonna change that as we go along. But you can see that we already have that bevel effect happening, because the blur that we created has told the system which parts should be higher and which parts should be lower. Next what we need to do is change it so that instead of that blue light filling out the entire SVG, it only applies to the shape that's defined by the source alpha that we showed before. To do that, we're going to create an fe composite primitive. The composite primitive allows you to compose different images by mixing one import source with another in different ways. We're going to say, feComposite. Now we'll close off the element. We're gonna give it two inputs so that's going to mix together. The first input is our Specular that we just created. The second input, in2, input 2, is going to be the SourceAlpha. Now we're gonna specify how we want these two images to be composed together by using the operator parameter. And we're gonna use the mode in. Now that's basically gonna use that source alpha shape like a cookie cutter. So instead of the whole SVG being blue, we'll only see the portion that's cut out by that source alpha shape. And then we'll give it the result name, lighting. Now let's try that in our merge node. When we save, there we go. Now the only part of what we've created so far that's visible is the part that's been cut out by that source alpha. So obviously that still look a little bit funny. What we need to do is take the effect we've created so far and combine it with our original source graphic that just has the blue gradient running on it. So we are going to add another composite node. I'm just going to paste this code in. This time, our first input is the source graphic, that's our text with the liner gradient. The second input is the lighting that we just created up here. This time we're using the arithmetic operator, which just gives you a bit more fine grain control over exactly how the two images are mixed, and that fine grain trail comes through these parameters here. And honestly, the best way to sort of see how those parameters work is just by changing those numbers a little bit, and then you'll be able to see what tweaking those numbers does. Now finally, we're creating the result bevelled. We're gonna take that and plug that into our merge node, and when we refresh, now we're starting to see our bevel effect come together. You could just stop there if you wanted, but we're going to add a bit more dimension to this by including a drop shadow to make the text look like it's coming off the screen. So to make our drop shadow, we're going to need another GaussianBlur. So it's the same thing again. We're putting in the source alpha and we're setting the standard deviation to 5, so it's gonna blur it by 5 pixels. I'm gonna make another merge node. We're gonna put it behind our bevelled effect and we'll plug in our shadow result here so that we can see the effect. So you can see that we've got this blurred black behind our text. Now we wanna move this blurred black off and to the right, and we can do that with an offset primitive. So we're gonna plug in our shadow result from our previous primitive in here. Now we're going to set how far we want to offset that shadow by. This is saying we are going to offset it by eight pixels on the x axis, so that's horizontal, and by 8 pixels on the y axis, which is vertical. Then our result is going to be drop shadow. We'll plug that in, we'll save, and there we go. Now, that is looking like a drop shadow. Now there's only one more step, and that is to add an outline around the outside of that bevel. So you can see here, this is looking the same, the only difference between our current text and the finished text is this outline around the outside. You can also see we have a gradient filling this outline, so it looks a little dark in the bottom than at the top. So to create the outline, the first thing that we're gonna do is take our source graphic, and we're going to expand it by two pixels. And we're gonna do that with a morphology primitive. So we're plugging in our source graphic as the input. Then we're using the operator dilate. This morphology can expand something or contract it. If you want to expand it, then you need to set the operator to the dilate mode. We're giving it a radius of two pixels to say that we want to expand it by two pixels, and then we have the results dilated. So we're going to create another merge node, And plug in our dilated results. And we're just going to comment out these two so that we can better see what we're working with. And when we save, you can see that we've got our original graphic, but it's just fattened up by two pixels. Now what we wanna do is cut out the center of these letters so that we just have an outline left. So we're gonna do that by again, using the source alpha as like a cookie cutter. So we're gonna use another composite node. We're gonna plug in our dilated results. Our second input is gonna be our SourceAlpha. This time, the operator is out. I'll show you the two results so you can better understand the difference between operator in and operator out. But first, we're just gonna plug in our outline. Now when we save, there you can see that we just have our outline left. Now if I change the operator to in, you can see that it's cut the extra part around the outside of our letters instead of the inside. So I'll just switch that back and there is our outline. I'm just going to uncomment our other nodes again. And you can see that right now, the problem with our outline is it's too similar in color to the rest of the image. What we wanna do is darken it off. And we're gonna do that by overlaying a darker blue color on top of this outline and blending it in with the multiply mode. Just as you would see in Photoshop or any other graphics application when you use the multiply blend mode. So first up we're going to set the color that we wanna use as our blending color. And we're gonna do that with an feFlood primitive. And this actually fills the entire screen with the color that we've selected. So we've got flood color and then a semi transparent blue color. And we'll plug in our outline color into the node here so we can see what happens. So there you go we've just got a whole blue wash over the whole thing. Obviously that's not what we want, we only want it to affect our outline. Next we're gonna blend that blue color with our outline, and we're gonna use an feBlend primitive to do that, so our input is our outline color that we've set here. Our second input is our outline, that we created with the above nodes, we're gonna set the blending mode to multiply and our result is going to be blended outline. So let's plug that in and see what we get. So there, now you can see that the outline is visible because our blue flood fill has darkened it off. It's still over the top of everything else too though, so now we need another composite mode to cut that recolored outline out of the rest of the picture. So we'll add in another composite mode, and plug our blended outline in. And our regular outline, we're gonna use that in operator just like we did before. And our output is gonna be colored outline. So that should leave only the portion of our recolored image that aligns with our outline. So we'll save once again, and there we go. Now we've got our recolored outline. Unfortunately at the moment, it looks a bit scratchy, it's a bit staircasey, so that's not really the best look. We're gonna fix that by using a morphology primitive again to expand our outline by one pixel. So we'll add in a morphology primitive, our input is the colored outline. We're going to dilate it by one pixel and the result is gonna be named finaloutline. So I'll just plug that one in there and let's save once again. And there we go, and now we've got a nice, smooth outline. So that wraps up our bubble bevel effect. And that also shows you some of the key steps of working with this type of project. We've seen how to apply a fill, how to make that fill a linear gradient. How to apply a filter, how to use filter primitives to stack on top of each other to create all different types of effect. How to group those effects up as individual results, that can then be stacked on top of each other inside an if emerge primitive, all coming together to create a unified effect. In the next lesson we're gonna start adding a little bit more to our SVGs and we're gonna create this inset wood project. So we're gonna be bringing in working with images, how to make them tile, and set them to the correct sizes. And we're gonna keep working with some of the types of effects that we already used in the first project. So we'll see you in the next lesson.