SVGs as Code: Interactive Icons and Easy Image Manipulation | Kevin Ball | Skillshare

SVGs as Code: Interactive Icons and Easy Image Manipulation

Kevin Ball, Web Development Consultant and Trainer

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
20 Lessons (55m)
    • 1. Dive In

      1:07
    • 2. SVG as Code

      3:37
    • 3. Manipulating Stroke and Fill with CSS

      2:27
    • 4. SVG 'Use' and the Shadow DOM

      2:16
    • 5. Inlining SVG

      1:36
    • 6. Fontawesome 5 & svg-with-js

      1:33
    • 7. Creating a Menu Bar

      2:41
    • 8. Making Our Menu Bar Interactive

      4:14
    • 9. Embedding Photos in SVGs

      2:20
    • 10. Your First SVG Filter - Blur

      2:41
    • 11. Color Transformation Filter

      3:09
    • 12. Masks

      2:03
    • 13. Programmatic Manipulation of SVG

      2:00
    • 14. Combining Masks with Filters

      3:35
    • 15. Applying Filters Programmatically

      3:58
    • 16. Mouse Events and Coordinates in JavaScript

      5:51
    • 17. Creating a Mask With Click and Drag

      2:43
    • 18. Uploading Custom Image

      2:42
    • 19. Saving Your SVG

      2:49
    • 20. Final Step

      1:13

About This Class

SVGs are an increasingly popular image format for the web, especially for icons, largely because they're small compared to other image formats and perfectly responsive for different screen sizes. However, another often overlooked part of their appeal and power is that just like HTML, SVGs are code and can be styled with CSS and manipulated with JavaScript.

In this course we will dive into the details of how to manipulate SVGs as code. It is accessible to anyone who has some familiarity with HTML, CSS, and JavaScript. You will learn:

  • How to make your SVG icons change color as a user hovers and clicks on them
  • How to use SVGs to highlight, blur, and manipulate different parts of photos, drawing attention exactly where you intend
  • How to manipulate your SVG images with JavaScript, animating them in response to user action.

As your class project you will build a simple photo filtering and manipulation webpage, one that will allow you to manipulate a photo and create a custom SVG-based filter for it that adds effects and highlights.

You’ll be provided links to code examples throughout the course and for the project.

Transcripts

1. Dive In: Hi there, Cable here and welcome to this course on SVGs as Code. With the rise of the responsive web, SVGs have become very popular. For a good reason, they're vector images, which means this gets perfectly up or down with screen size. However, there's an even more important reason why SVGs are so powerful. SVGs are code just like HTML. That means that we can manipulate them with the same tools with CSS and with JavaScript. In this course, we're going to dive into what that means. We're going to take a look at SVGs. What is this code? What does it look like? We're going to start playing around with how we apply CSS to make them a little bit interactive, change color based on hover or applying a CSS class. Then we're going to dive into some of the more advanced features of SVGs, how we can use filters to put images and then change their coloring, add blur, mask out pieces we don't want, all fun stuff. We'll use JavaScript to make this interactive so that by the end of the course, you will build a photo editor just like you might find in Instagram or Snapchat, where you can put a photo in, apply it custom filters, and then download that image to use wherever you might want. I hope you're as excited as I am. Join me in the next video. 2. SVG as Code: Let's dive into what makes up an SVG. To make this easy, I've created a little simple SVG. I just put together this little face using Sketch. You can see I'm not much of an artist, but this uses a bunch of different elements within SVG that will let us explore what those things are and how they're available to us. If you're following along at home, click through to the pen, just click Fork, you can tinker with it yourself, and you can see what we get right away is a look into. Here is our image, and here's the code that's generating that image. Let's dive into what those pieces are. You can see that it's structured pretty similarly to HTML. You have an outer element that instead of saying HTML is SVG, we can ignore this XML version. In fact, that doesn't matter for the purpose of this. That's just giving a high-level note as to how this is structured. The SVG element has a couple of things that are different from HTML in that you see that it has a width and a height and a view box, which is which parts of the image are visible are inside of the image that's being shown. You can actually have SVGs that go off screen and on-screen within the view box. There's some meta information, a title, this is our simple face, some depths which were not using right now, and then we get into the actual elements. These are just like an HTML, your divs or spans, your paragraph tags, except here they are graphical elements. We have g, which is a group tag. This group is our entire face, the simple face. We can see there's a circle, some ellipses, a path polygon some more ellipses, some more paths, some more ellipses. Circles and ellipses are pretty straightforward. This first one is our face. You can see that there's a few different values with about it that we can change. We could change the stroke color. If we wanted to change the line that is the outer part of the circle from black to, let's say a gray, we can do that and we can see that it changes down here from black to gray. We have the stroke width, which is the width of the line on the outside. If we change that up to five, for example, we can see that it, it gets a lot bigger and fatter. Change it back to two, and we have the fill, which is what is internal to this. Now these stroke, stroke width filled, these are available for most of our elements. You can see there's also some positioning elements. We have cx, cy, that's where this is positioned within the are screened for the center. This is the center x, the center y given r, which has a radius. If we dropped that down to 17, we can see that that circle got a lot smaller. We can see that these are broadly echoed for each of these different types of elements, ellipse, circles, etc. Paths, you'll see there's this other funky thing, d equals and then a set of what essentially looks like numbers and some funky letters attached. We're not going to dive deeply into that format right now, but this is describing an arbitrary route through space. The way that I created this and the way that most people create ads like this or create things within SVG that are arbitrary is they'll use a graphical tool. I used sketch. I've just put this together using the sketch vector tool. Didn't exported these paths for me. Now that they're here, I can tweak them and manipulate them. But I don't think anybody is handwriting paths for their vectors unless they've been doing this for a very long time, they usually use a tool to do it. You can write these in Scatchard, Illustrator get something started, and then export it and you'll get these pads right out. In our next lesson, we'll take a look at how we can manipulate these in a more systematic way and how we can start to use CSS to tinker and play with it. I'll see you there. 3. Manipulating Stroke and Fill with CSS: In this video, we're going to look at taking that same SVG we used in the last video and now styling it not just inline with changing our stroke or our fill inline, but with CSS. This as you can see, is the same SVG, the same simple face we created, but I've added a little bit, I've added class name. I've added a class of face for this outer oval. I've labeled my eyes, my nose, etc. If you're following along at home, click through the pen, hit Fork, and we can start to tinker around with this using CSS. Let me open the CSS tab here. Now, I'm using the Sass preprocessor that lets me use variables here, named variables. That's just so that I can do this a little bit more semantically. Now, you can see that I've taken these classes and I've started to target them and put these properties in. This means two things. One, it means that I can delete the properties over in the original SVG. If I take the face, I could tell it "Don't have any defaults." That's pretty good and it stayed the same here but if I were to get rid of these, it would turn to black, which is the default if it's not defined. I actually want to keep those defaults in but what I'll do instead is start overriding them with CSS. Let's say, for example, I've got my eye color, which right now is this blue and I want to make my eye color black. I'm going to go completely to eyes. We can see that eye right now is just using a fill of eye color. I'm going to change eye color here and just take it to black. That overrides my defaults and you can see with my eyes down here, just turn totally black. You can do this in a number of different ways. What this opens up is the ability to use CSS in all the ways you wouldn't HTML, to create interactions and all sorts of other things. Say my face is this nice, healthy brown right now, but I get really scared when you hover over me, so I'm going to add a hover effect simply by adding some CSS, a pseudo target for hover. I'm going to change my fill to a pasty white when you hover on me. We do that, we come over and suddenly I'm a pasty white anytime I hover. This will allow us to do all sorts of fun interactions and in a future video, we'll talk about how you can do this to create interactive effects on all of your icons. You can create an interactive menu bar using SVGs. There is a caveat which has to do with how your SVG needs to be included in the page for CSS to target it, and we're going to address that in the next video. I'll see you there. 4. SVG 'Use' and the Shadow DOM: In this video, we're going to talk about different ways you can include SVGs in your page. The one you've probably encountered the most is this one. You can drop an SVG in as the source to image. Despite being code, SVGs are also just images and they play nicely with image tags. Another way you can do it is with the object tag. This is an older way to reference external content used to be used for flash players and things like that. It recognizes SVGs but this isn't generally recommended. You can also use an SVG that references another one. You can define an image as a symbol and just a reusable example and then reference it out in SVG. In this case I'm referencing this symbol which I defined up here in an empty SVG, an SVG that doesn't show in the page at all but just defines my symbol. I can reference it in. You can reference third external images, things that are not in the same page but they have to be on your same domain. Then the final way that you can put an SVG in your page is with inline code. This is exactly the same SVG we've been playing with all along. When you use these different mechanisms, you have different limitations. Dropping them in as sources to images is great but you can't actually manipulate these SVGs with CSS. In fact, you'll see if you look down here at my faces, two of them have something slightly different. I've taken our CSS and changed the fill for the nose, so I changed it to be white. But that only impacted two of our versions. It impacted the SVG that's using the symbol and the SVG that's totally inline. If you use image source or object referencing data, you cannot touch those SVGs with CSS. If you're using this, the use you end up with something like the shadow DOM which places some subtle limitations on what it is that you're able to access. We're going to dive into those too much because we're going to focus on this last version, the inline SVG. This is the most powerful way to use SVGs. You put all your code in. The problem with that is, what happens if you are getting your SVGs from a third party source? You got them as image files, you want to just deal with them as images. For that, we're going to do something called inlining. We're going to use a tool that pulls those images in and drops them into your page. We'll cover inlining in the next video. See you there. 5. Inlining SVG: Welcome back and let's talk about SVG injection. SVG injection is quite simply using JavaScript to look at images that have an SVG source, pull that source out and dump it straight into the page which is inline SVG. You could do that manually of course, but not only is that a big pain in the ass, but you also don't get to take advantage of the browser caching available for images. However, this library that a group called Iconic release called SVG injector, lets us do it automatically with JavaScript and still leverage browser caching. What this lets us do is take all of our image tags that reference SVGs, automatically go and pull that SVG source out and dump it in place. Let's look at what this looks like. Here I have my standard face that we've been using up to this point and it's referenced as an image tag but I'm going to do something more with it. I've added a class so I can reference it in JavaScript and I've added the SVG injector JavaScript. Now I've done that just referencing CDNJS, which lets me pull it into my page. You can do it here. You could install it with an NPM package if you're doing something locally it, however you want to do it. But in CodePen, this is the easiest. When I run my page, I have this little bit of JavaScript that looks for any image tag that has an inject class, passes those into the SVG injector and suddenly this is no longer an image. It's actually an inline SVG. We can see that by inspecting it. It's put all of that SVG just straight into place. It's as simple as that. That allows us to start leveraging all the magic of inline SVGs while still keeping our code nice and simple with plain images. 6. Fontawesome 5 & svg-with-js: Playing around with our face has been a lot of fun, but let's move on to some more professional uses of SVGs. The first place we're going to start is with icons. Now, if you're not familiar, Font Awesome is an incredible icon source with hundreds of professional level icons available for free and even more available if you're willing to pay for a bit of a license. In Font Awesome 5, the most recent release, they did something that's really cool. What they did is they released their default mechanism for deploying these icons is using SVGs with JavaScript injecting them. You just include a simple JavaScript file that manages everything, you include your Font Awesome icons using just a couple classes on an ETag, and it will automatically inject them as inline SVGs giving us access to all the power that we've been talking about of inline SVGs. It's super simple to do it. If we look quickly, I set up a basic CodePen. I just put a couple quick versions of Font Awesome icons in there. All I have to do is add a reference to their JavaScript, and suddenly, these icons are showing up and they're showing up as inline SVGs that we'll be able to do fun things with. So in our next video, we'll start diving into actual usage of this in to create a menu bar for what will eventually be our image editor. But that's it for now. Font Awesome. If you haven't checked it out before, check it out, you'll be blown away. 7. Creating a Menu Bar: Now we're going to get started into the first steps of building what will be our course project. In this video, what we're going to do is start looking at building out a menu bar for us to play with. If you're following on it, home, click fork, to fork a new CodePen from the link. What I've started here is just putting together a very simple space for us to create our photo editor in here. So I've got an editor container div, I have got menu bar that we are going to be doing things with, and I've started putting some icons into the menu bar. As we go forward, we're going to do more fancy things, but we're using font awesome. If you're not familiar with the way font awesome works, you can do FA and then the FA dash, whatever the class name is. There are sometimes alternate versions, so FAR if I change what this R is, just FA square is going to be a filled square. Whereas if I do the R, it's just outline. Then I put some simple CSS in here, so I just bounding the size of the editor with the width, centering it, off-setting it a little bit. Put the menu bar, give it a nice little border, some display flex so things a layout properly padding on it and start padding things. Now, one thing to note is, I'm styling SVGs in here, not itags. In fact, if I put itags that matches what I wrote on the source, it does not work out. That's because, we've included font awesome here and it is automatically transforming these Itags, at SVG. Something to keep in mind if you're using font awesome in this way is, these are getting turned into SVGs. We can't rely on them staying in that same way. So I just started with three different icons I'm thinking you will want to be able to download our image, take a picture to put something in there, draw a square on it, maybe we want to do a circle or something like that. Let's put a circle here. You could do all sorts of things if you want to just explore what all the different options are available for you, font awesome icons. You go over to font awesome.com, click on icons. We're using the free versions, but there's still almost 1000 icons that we could put in there. Go to town, think about what are the different things that you might want your photo editor to be able to do and just start playing around with using this font awesome. If you're excited, you can start playing around with styling the SVG, each of these is made up of a path that you can manipulate that has a fill and color. We'll start getting into that a little more in the next video. Get a basic menu bar set, this will be the foundation on which we build going forward. 8. Making Our Menu Bar Interactive: In this video, we're going to look at that menu bar that we just put together in the last video and start making interactive by utilizing CSS, pseudo elements or pseudo properties so that we can make it interact based on hover or applying classes that then let us interact with it, with JavaScript and change its state. What we're going to start is with the same menu bar we have, except I've made one alteration. I've wrapped each of these icons with the little span that lets me contain it and do stuff with it. We'll get into why I do that once we get over to the JavaScript. Now looking at the CSS, I've just set up a couple of SAS variables for us so that we can semantically represent color as we play around with this. If we want to manipulate these SVGs, we should know a little bit about what they look like. If we inspect this with the inspector, we can see that each one of these icons consists of just a single path, which is drawing that shape whatever the icon is and it has a fill value of current color. Now current color is a special CSS property that basically says, whatever the color is for this item, use that here, so that doesn't fun often cases. It lets it inherit whatever the color is of the container and the writing, and in his case. If we just set a color to menu bar to be our light blue, that color actually gets inherited. If we wanted to do this without the current color approach, we'd have to actually set the fill. We'd have to know, okay, this thing has a path in it and we need to manipulate the fill to be light blue. That works just as well. The current color trick is really convenient when you're using these within blocks of texts and things like that because it just picks up whatever the surrounding color is. But we don't care about that as much because what we're going to do is change this based on hover state. If we scroll down a little bit, I've got a block here for hover. This says anytime you hover over the SVG, change the color of the border and change the color. We can see now as we hover, these things turned into light blue when we hover them, and what that does is it makes them feel interactive. It gives the user a hint, hey, I can probably click on this and it's going to do something. Let's actually implement that. If we wanted to do something based on a click, what we need to do is use JavaScript to watch for that click and then apply some thing. Now a standard for this as you apply a class, and then you have whatever styling changes you want change based on that class. That's a way that you can manage display based on state. Now we're going to get to why I put these wrappers around it. What I do with the JavaScript to get this to happen is I'm going to do a set timeout around it and that's just making sure that, hey, we've already got these things in the page Font Awesome has had time to parse it and use its JavaScript. Then I find all of the document elements that are named action. That's what these rappers are called and anytime there's a click on them, I'm going to just toggle whether it has an active class or not. That's a state class that lets me look for that in my CSS. I could have in theory done this on all of the SVGs directly rather than wrapping them with spans. But this comes to a quick got that I want to highlight for you, which is when you're using Font Awesome, it's JavaScript is actually watching all of those SVG. If you manipulate them, it'll re-render them in the page just to make sure that, if for example, you change the class, it's still got the right icon that can mess with other things in our JavaScript. If you want to manipulate the states of these without forcing them to re-render, you'll probably need to wrap them in a class or in an element like I did here. What are we going to do? Every time I click on this, we're going to toggle whether that container, that action has an active class. Then we can use CSS to visually represent that. Anytime this is active, it's going to turn dark blue. Same applies for each one of these and then since we're using toggle, we can actually untoggle it. That gives us a visual indication of behavior. Once we start adding more elements to a photo editor, this will not only add a visual element, but it'll actually change what behavior we have happened. We'll get into that and start talking about how we integrate photos into our SVGs, in our next video. I'll see you there. 9. Embedding Photos in SVGs: We've spent all this time talking about SVGs, which are vector images, images that are defined as descriptions of what they are that say okay, this from point a to point b, or this is a square, things like that. But there's a whole ton of images on the web, like all those wonderful cat photos we find everywhere that don't fall into the category of vector images. They are what's known as raster images, which basically means they're description of dots of color. This is what comes out of your cameras. This is anything that's a PNG or a JPEG or any of those image formats are, and those are really important. There's a lot of important things in them. However, we can incorporate those directly inside of SVGs and do fun things with them. We're going to start doing that with a bunch of image editing, blurring, doing all sorts of cool stuff in the next few videos. But to start with, we just need to know how do we put them in. I've grabbed an image of a set of kittens because the Internet is for cats. I got this from a Flickr user. If you didn't know, you can go to Flickr and ask for any images that have creative common licenses, or licenses where you can use this publicly. I can use this publicly so long as I credit our Flickr user, or Flickr user is Casey XD, and you can find images for your own use that way. Just go to Flickr and search and then sort for by licensed type. What we're going to do is put that inside of an SVG so that we can start to manipulate it in the future. What we've done, I've got what would be, we would have our menu bar up here like we had previously, but I've taken that out for now so we can focus just on the image and put it inside of a stage and then I have my SVG right now just as a wrapper around an image tag. An image tag is basically a reference to any other type of image. You can embed your raster image into an SVG by just putting an image tag, putting the link to where that image lives, and specifying some dimension. Here we're saying, we're going to start at zero in the SVG, at zero and zero, x and y. We're going to have this thing take up 500 pixels of width. It allowed us size the height. Here is our image living right inside of our SVG. If we inspect it, it's in there in the SVG. In our next video, we'll start talking about, now that we've got it in our SVG, what can we do with it? We'll start looking at filters and blur. Join me there. 10. Your First SVG Filter - Blur: Now we get to dive into the meat of what will be our project, the actual editing of photos. To do this, what we're going to do is we're going to use a tool called a filter from SVG. Now filters are essentially sets of image transformations that are defined and then can be applied reusable across any sort of image. You can use these to apply to native SVG components, so you could say, I want to take this SVG component and I want to blur it, or I want to change the colors, or I want to rotate it, or things like that, you could do that with a filter, or you can do it to raster images like our kittens photo. Filters can be combined. There's all sorts of ways you can create a filter that has a set of different primitives that it does but we're going to start with the most basic of filters. We're going to start with a blur. In this case we're going to use a Gaussian blur, and the way this looks in SVG is, you define a filter with some ID, that's what's going to give you the ability to apply it to things and then you use a set of filter primitives inside of it. We have our filter, which we're just going to call Blur Me and it contains a single primitive an feGaussianBlur. Gaussian basically means we're going to distribute things along a curve and you will need to define what is the source for that blur. In this case, we're going to use a key which is the source graphic, which basically says whatever you're applying this filter to, that's what I want you to blur. There's a few other keywords you could apply it to the alpha, which is just the transparency of the graphic, there's a couple of other things. For all of our image editing purposes, I think we're going to want to use the source graphic. Then there's a standard deviation which applies to how spread out is that blur. If we're taking the original and distributing it over a wave, how wide is that or how narrow is that? Then you apply it to an image. We just add this filter property that points to the filter we have defined. To see, we've applied it to our cat, our cat is very blurry. If we put that standard deviation down to 0, it's as if we had no blur on it at all. We change it up to 1, it starts to get a little blurrier, 2, 3, and it just keeps getting blurrier and blurrier. Applying this to the whole image may not be that exciting but as we get down and we start looking at combining this with mass, you'll be able to selectively blur out parts of your image and increase the focus on others. This is going to be a super powerful tool in our toolkit and it's one of the simplest filters to get started with. All right. In our next video, we're going to talk about another filter that we can use to transform our images and make them look retro or tinge there color in different ways. Join me there. 11. Color Transformation Filter: Welcome back and onto our second video about filters in SVG. In this video, we're going to look at a different type of filter. We're going to look at manipulating the colors within our images. You can see that I've got our same kitten photo, but it looks a little different, it looks like an old-school photo. It's got a little retro, it's a little red tinged. The way we're doing that is using another one of the filter primitives available in SVG, this one called an feComponentTransfer. What this does is, it lets us define a function that gets applied to each pixel within the image and transforms it. What we're doing here, we have one function for the red factor, one function for the green, one factor for the blue. This is going to take the RGB value of every pixel in this image and transform it base on the formula we define. For this filter, this is the one I'm actually applying right now. I call it redshift. What we are doing, we have two factors that we can play with. We can play with the slope of the function. What that basically means is, if slope is one that says that's the intensity of the R, the G or the B. If it's one, it's going to be the same intensity as it is in the original photo. Here we've put it into two, so we're ramping the intensities of all of our pixels but then we also get to shift the intercept. That's where the value starts. Intercept zero says leave it alone. Intercept negative values says ramp it down, make it less. In this we're saying, make ours a little bit more extreme, but start in the same spot. Make our greens a little bit more extreme but start lower and rampart blues down even further. If we wanted to shift and emphasize a different component, what we can do is do the same thing but ramp down our reds and our green's a little bit and then delete the blues and change. If we look at what that looks like instead of a redshift, we can see that actually tints everything with a blue color. You can play with this in a number of different ways. We can look at what would it look like if we didn't change the slope at all, but still changed the intercept and that still has that red tint but it feels very dull it's not very alive by adding an additional slope. Even as we're taking away some of the colors, some of the greens, some of the blue, it still feels alive. We can also look at what would happen if we shifted this forward instead of negative, so we changed the red and really emphasize it and that gives us very red focus tinge. We're adding red rather than just emphasizing what's already there by taking out some of the others. This is going to be another one of our permanent filter effects we're going to apply. There are a ton of different filter effects. You can actually go to the W3 documentation and look through all of the different filter primitives. Many of them had to do with light and how light does thing. We're not going to cover all of these in the course, but that's a fun place for you to go and study and explore and figure how you can extend what types of effects you want to apply to your SVGs. In our next video, we'll be talking about masks, which lets us apply things to sub-sections of our images, so join me there. 12. Masks: Now we're going to talk about masks. Masks give us the ability to selectively show pieces of our images and hide the rest. Basically what you do when you define a mask is you create a shape and then when you apply that as a mask to something else, it only shows things that fit within that shape. What I've done here in our examples, I've taken our kitten photo and it's the same exact photo even though you're only seeing part of it. What I've done is I've created a rectangular mask. I called it my kitten mask and I gave it, that mask contains some things inside it, contains a rectangle and I gave it some dimension. I started at, X 50, give it a width of 250 and a height of 500 and what that does is when I apply it using this mask attribute to my image, it selectively shows only the things that are covered by this rectangle. I can change what's showing by changing the size of the rectangle, so if I change the width, it gets a little wider, I see a little bit more of my kittens. If I change where it starts, so say instead of starting at 50, I started at 250. I'm showing the other side of that image now, and I could change the fill, as well. That gets a little tricky. What this essentially will do is show anything where the mask is opaque. Right now the mask has a fill, it's completely opaque, so it's going to show everything. If I got rid of that fill entirely, nothing would show because my fill is not there. If you put something in as your fill that is translucent, you actually can get partly show, so you get it to show translucently. By marking around with the alpha, you can do the fun stuff. We're not going to dive into that in great detail, but that gives you some sense of how flexible masks are. In our next video, we're going to start seeing some of the uses of this, so we can take our mask, use that to selectively show things and then combine that with a filter so that we can selectively blur, selectively color modify, do all sorts of fun stuff. I'll see you there. 13. Programmatic Manipulation of SVG: Okay. Let's talk about programmatic manipulation of SVGs. Just like anything in HTML, SVG elements, especially once they're inline, can be manipulated with JavaScript. What that means is that all these tools that we've been learning about, filters, masks, etc can be changed and applied with JavaScript. So what I've done to demonstrate that here is I've taken our kitten, and I've got the mask that we did in our last video, and I just put three little links together. No mask, small mask, and big mask and I gave them IDs so that we can hook into them and grab them with JavaScript. I also added an ID to my image so I can reference that a little bit and so what we want to make these do, is have no mask, get rid of the mask, small mask, put a small mask on there and big mass, put a big mask on there. To do that, we just use some simple, JavaScript. What I've got here, is, I grabbed these different, objects by their IDs. So I've got the mask, the thing that we're actually going to want to change, if we're changing the mask, is the rectangle inside of it, the dimensions of that. If we change the dimensions, and the mascot, element itself, it's not going to help anything, because , it needs to be what is the object that is doing the mask? Then an image, oops, we've got some extra semicolons there. That's the image that we've got. Then I created , some event listeners. So for no mask, all we want to do, is set the attribute on the image of mask, should not be there. For small mass, we want it to be there and we want to set that mask to have a small width, and for big mask, we want to set it to have a larger width. That's it. It's just plain vanilla JavaScript. It's just like, manipulating anything else. But because, we can manipulate these masks, and these filters, we can apply these effects, in a really fun way. Let's just take a look what it looks like, no mask, there's our original image, small mask. What we've got, big mask, it spreads around. If you want to play with this more, you can try using this to apply filters, and other things that you might be getting ahead because we are going to cover that, in the next few videos. See you soon. 14. Combining Masks with Filters: Welcome back. We're going to tackle combining filters and masks. What we want to do, we've got our kitten photo here, and we want to highlight one of them. Let's just pick this kitten here, this one on the left. We're going to blur out the background and our other kitten and leave just this kitten here. If you recall, our mask highlighted just that kitten and are blur filter blurred this. We should be able to combine these two to get the exactly the effect you want. In our SVG, I've got our mask defined here, I've got the filter that blur filter defined. Those are just the same things we've covered in previous videos. Let's look at how we might apply this to our image. You might think we could just apply them both to the same image. That would make intuitive sense. But if we try that, if we say mask equals URL, kitten mask, and we then apply as well the filter. What happens is they both get applied, but not in quite the combination we wanted. We've masked down to our star kitten, but then we blurred that same one. If we want to combine the effects in a different way, where we want to have this kitten be highlighted. What we need to do is actually layer on these effects rather than combine them. We're going to layer on, first the blur. Then we're going to take another copy of the image and add the mask. If I take this image and I copy it before I do anything, so copy it. Now I have two copies of the image. They don't cascade down the way they would HTML because SVG, we're positioning absolutely. We are setting the same x and y coordinates, so these are actually on top of one another. Now what we want to do is blur the back one and mask the front one. Let's put the mask on here, mask as URL kitten mask. We don't see an effect right away, but we can know if we delete the other one. That's what we're masking down to. Now let's blur the background one. The one that comes first will be the one that's underneath. Let's try filter equals URL. There we have it. You can see that we now have a highlight around this kitten and everything else in the background is blurred. You can start to see how by creating careful masks, you could highlight particular portions of a photo. Now, this is a little awkward. We're repeating exactly the same image over and over again. We might not want to do that, especially if this image, rather than being a link, was a blob that we've uploaded or things like that. We can actually take advantage of another SVG characteristic, in fact, one that we covered earlier, the fact that you can define symbols and use them. If I swap over to this code pen, I've defined a symbol that is the photo that has that my link. Down below where I want to do my layered blurs and masks, I just have to reference that photo I do use and put that in there. This will let us, in our next few videos, access an image that we've uploaded in one spot and start layering on effects as we go. I'm excited to get into the actual editor stuff and we'll get started with that in the next video, so join me there. 15. Applying Filters Programmatically: Now we get to get into the fun stuff of making our editor. We're going to set things up to apply a filter on the click of one of our icons. What I've done here in this Code Pen, and if you're following along at home, you can just fork this and get going and play with it. I've put our two pieces together in the same pen. We have our menu bar, and I have our stage here. Our stage has the photo. I'm using the symbol approach because as we go further, we are going to want to do that to give us flexibility into having more and more versions to this to get that layering effect we did in the last video. But so yeah, I have our menu bar, put it and this is just pulled in. I have our stage here. For my purposes in the video, what I'm going to do is I'm going to apply that little red shift filter to the image. So I put that filter in place and thinking about what Icon would stand for that, well, it seems like the type of rechead thing you might do on Instagram. So I put an Instagram icon in and I'm going to use that. Looking at how we're going to apply these things, if we want to do it with JavaScript, we need to do is give some sort of hook to explain what to do. I'm going to use a practice of using a data attribute to communicate with the JavaScript. This is something that generally for a generic JavaScript. When you're not using fancy frameworks like Reactor, things like that, this is a policy I recommend we use classes to communicate, styling. We use data, attributes and IDs to work with the JavaScript so that you keep a nice separation of concerns there. I'm going to add a data filter points to Redshift, which is just the ID of our Redshift filter here. Then over on the JavaScript side. To get this to work, I'm going to do one thing. First thing I'm going to do, this is the same code that we had for our state color stuff. We did this in a video a few back. But I'm going to add one more layer to this. First I'm going to capture when I toggle this, is it active or not? So the classless toggle will return true or false depending on whether it added the class or removed it. Then I'm going to call a toggle affect function. We're going to build on this as we go forward and keep going. But this is where the need of applying that effect is going to be. Coming down to toggle affect, what I'm going to do is I'm going to grab the element. It takes two parameters, the element itself and whether you're applying it's active or not, since we've got that from here. We're going to toggle in effect. I'm going to build essentially a set of checks here, which we could then potentially call out into separate functions. But for this, we're going to just do one where I say, Okay, what's the data attribute that we've got? Is it a filter? Or maybe down the road it will be a mask or maybe it'll tell us, ''hey, we wanted, this is actually an upload or download or what have you?'' That's going to be what triggers our behavior. What we're going to do then is if it's a filter, then we go to one of two things. We're actually going to apply the filter to the photo, or we're going to remove it as if it's not there. It's really as simple as that, you know, as you've learned in previous ones to apply these filters, all we're doing is setting a filter attribute on this photo itself. When I click my Instagram, suddenly my filters applied. If I click it off, this is really what's going to give us the ability to apply these different filters. I encourage you to go and fort with this and play with it. Don't just stop with this one Redshift filter, but try extending it. Add a couple more filters. If you really like the blur filter or something like that, add another icon and set up a blur filter, get it to work. Then coming soon we're going to look at actually adding masks pro-grammatically and being able to do drag and drop and fun stuff like that. So join me in the next video to talk about that. 16. Mouse Events and Coordinates in JavaScript: Okay. Before we dive full on into creating masks programmatically, let's detour slightly to look at how we make things that interact with mouse events. Because what we're going to want to do with an interactive mask is to be able to click and drag and a part of the image and create a mask layer. But do that, we need to understand how click and drag works. What I've set up here is our basic stage, just like we've got generally. I've added a little circle pointer that we can use to track our mouse and so we understand. Then what we're going to do is look at how mouse events work and what we want to do. If we look at the JavaScript, there are three different events that are important if you're creating a click and drag. There's mouse down, mouse move and mouse up. Those break out the three different pieces of what you might otherwise call a click, mouse down is when you first click down, mouse move happens anytime you move the mouse. So mousemove is actually happening if I haven't clicked at all, but I'm moving this around and mouseup is anytime you click up. If you want to do a drag handler, something that happens when you click and drag, you need to implement a listener for down, turn on your move listener only after you do down and then turn it off again when you do mouseup. That's the basics of what we've got here, we're putting a mousedown listener on the stage. If listener fires, we do some info which we'll talk about in a sec, but then we add these additional listeners so that we're watching our drags and we're watching our mouseup. We actually add these listeners on the whole document and not just the stage because otherwise you can get in a weird state when you add those listeners, put them on the whole document. To take a look at what is available to us in the event let's actually fork this real quick and put a debugger in there. I'm going to just drop a debugger in my on mouse down. Let's open this up in a debug mode so that it's easy to do it. When I do mousedown on the stage, I should get a debugger, over here if I click down on the side, just doesn't do anything. But if I click in here, I get mousedown and I can see what is that event and what data it is. Let's just log that out in the console. Our event has a whole slew of different data on it, including position data. It's got this clientX, clientY, layerX, layerY, offset X, offsetY, pageX, pageY. What are all these things and what are we going do with them? They all mean slightly different things. The client is offset within your viewport. The page is offset relative to the entire page. Those are the two that I use mostly I don't pay that much attention to the rest of them. But we can use those dimensions to know where the mouse is and utilize that in this case, move our little red dot. In the next video, create a mask when we do it. Coming back over into our code, what we want to do is we want to capture where we are and use that as we move this to update our pointer. Now, if you look at the capture code I have here, there's something else that's going on. I'm not only doing a pageX, but I'm applying an offset. Why is that? That's because I want to know where within the SVG I am, not just where within the page I am. If I don't have that offset, so let's get rid of the offset real quick and just take a look at what works with our little red dot. If I don't have that, my dot isn't actually showing up anywhere, it's not at all obvious where it is or should be. That's because the things that we're manipulating are inside the SVG and so they're offset relative to where the SVG starts. But are events, the data is global, it's based on the page. What we do is we capture the offset for the stage and then we apply that offset anytime we're changing our position. We're going to say where am I in the page? Subtract from that my offset. If we put that back in and you can see that when I click and drag each time it's capturing it, it's changing what it thinks it should be and then updates that Cx and Cy. That's going to let us create programmatic masks where we can click and drag to select parts of our image and put a mask over that. One final thing to note, so I mentioned clientX and clientY, pageX and pageY. If we quickly change our pageX and pageY to clientX and clientY, let's take a look at what the difference is. If I were to do this and run, it actually looks like it's doing the same thing. It works just as well until I scroll and then you can see that there's actually an offset relative to where I am because the clientX is relative to this window, not the entire page. But our offset of the SVG we're calculating relative to the page. I only mentioned this because there are times when you're going to want to position something not relative to the page, but relative to the client here. If you're positioning something that's not a part of your SVG, but it's over the top, things like that you may want to understand that distance. So that is how we can use mouse events to manipulate something. You grab the dimensions or the position off of the event, and you use it to change some attributes on the item. In our next video, we're going to dive into using that to create a custom mask. So join me there. 17. Creating a Mask With Click and Drag: Okay. Now we're going to use what we learned in our last video about mouse events to create a click and drag mask, so we can mask over any particular part of our image. What we've got here, we've got our stage. I've set up a mask, I've set up a filter, I've set up the same setup that we had to show combining filters and masks. But now we're going to make this mask able to be custom space. What it's going to end up looking like is, I'm going to click somewhere and draw and that'll be my mask so I can move my mask around, put it wherever I want. The way we're going to do this is by capturing those same mouse events. But now we're going to do some fun stuff with it. Instead of just moving a little red dot around, we're going to update our mask. To do that, we want to have the mask object grabbed. We're going to grab the kitten mask. I'm actually referencing its first child because the thing that I'm going to change is not the mask object itself, but the rectangle inside it. So I'm going to grab that mask, I'm going to do the same stuff that we did to set up offset and stage and things like that so that we know where our points are, and now in our handlers, we need to keep track of both where we start, where that initial click was, so that we have that starting corner and where the mouse ends up. So a cash are both a start and a current when on mask down. As we drag, we just update things and then update the mask as we go and then mouse up distributes the handlers again. Updating mask. What we're doing is we're basically creating a new rectangle. We're setting a new x, a new y, and new width and a new height. To do that, we need to be cognizant of the dimensions and the way that it works so that our x, y is going always be our upper left corner and width and height they're going to be how wide. If you start on the left and go to the right, the first place you start is going to be the x, whereas if you start on the right and go to the left, the second. To do that, we're using this math.min to say. Okay? Whichever one is further left, use that one or whichever is further to the top, use that one. That's all it is. You put that in place and we can update this mask so you can see how you can, now with this approach, create custom masks wherever you want and you're creating things. If you wanted to go a step further and say, "Hey, I want to apply multiple masks." So I want to clear both this one and that one. You could have this create a new mask and create a new layer in our image when you go. But I'll leave that as an exercise for you. All right. We're almost there. In the next video, we're going to talk about how we get a custom image up in here so that we can do something and then we'll do downloading and then we'll be done. I'm excited, let's go. 18. Uploading Custom Image: So in order to make this useful, we need to make it so that we can actually upload a custom photo. Not that we don't love our kittens, but if we want a photo editor, we've got to let us put up a photo. What we're going to do is first, just put a file input. Let's look at what the code is, I put a file input in and I don't want to know default file input, I want something that's styled the same way our buttons are. I put the upload icon and I use a trick for creating styled inputs, which is that I hide this input with CSS and put this image and put upload to displaying on, but I wrap it in a label. Clicking on this, will act as if it clicked on the input. If I click, here's my file input. Next, I want to use JavaScripts to grab whatever image that I upload there and put it into my source image here. There's a couple of things that make this possible. When we get that file up, we will actually get it as a file object that we can either convert into what's known as a blob, which is opaque to us. We can't do anything with it, but it's in the page that we can do or we can actually render it out as a base 64 object, which is a big string of bytes that is translated to the binary of that image. The nice thing about that, is that then if we download that, it's not specific to this page, we can use it wherever we want. We're going to use that approach. The way we do it, we grab the file input, add an event listener on it so anytime that input changes, we're going to run this function. Inside, we just grab the files. This functionality here using a FileReader and readAsDataURL, this is what's going to let us put this thing as a blob or sorry, as a binary string that we can then download. We put that in, run the file in there, and then when it's downloading, we set the attribute of our image over here to have a source of that image. If we take a look at what this is, I upload this photo and suddenly that's in there. If I look into the source here, we can see that it's, oops, let's go back down at image, right in line replacing our external reference and it works just like you'd expect. Now we can apply our filters to that. We can filter this just the same way that we did our kitten photo, we can put whatever image that we want in here. This gives us the ability to create a general-purpose photo editor where we put a photo up. Next video, we're going to look at how do we then pull that down so we can re-use it someplace else. See you there. 19. Saving Your SVG: Welcome back. Let's look at the last thing we need to make an incredible photo editor. We've already got our code that's set up to upload new images, apply filters, do all sorts of fun stuff. We need some way to pull the image down again after we're done. We're going to implement a download function and then we'll have all that we need to make this awesome photo editor. What we're going to do from a markup standpoint, the only thing we're going to change is we're going to add an ID on the download icon so that we can capture clicks and do something with it. Everything else here is the same that we've been building up. We still have the Redshift filter. We still have the ability to upload our own photos, things like that, but we're going to put some functionality on that download. We put an ID, and over in our JavaScript we're going to grab that button and add a click handler. That click handler is going to download the SVG. This very simply all that it needs to do is grab our SVG code that we've created and we've modified using these filter buttons and things like that. Grab the content of that. We grab our SVG, grab the outer HTML, which basically means grab the SVG symbol, everything else, and then put that into a file. In this case, we're going to do it, create a link that has that info as a data attribute. This is a way to create a file on the fly. Set the attribute to download, so your browser will download it and then click. That's all that's going to happen. When I click this, it's going to download an image. There is one caveat, something to put on there. We were getting a little sloppy in our SVGs. We just had the SVG view box version info. In order to get this to render properly in a browser after we download it, we need to link it off to xlink and SVG so that if this basically tells the browser, if it looks at this fall on its own, treat this like an image. We also had ID so that we can grab it up here. But what that lets us do now is say I upload a custom photo, I'm going to upload my eagle. There's my eagle. I apply Redshift filter, looking super retro. Now when I download it, I get a file that has saved all of my changes so that can use them wherever I want. With this, you have everything you need to build an awesome file editor and your challenge, your course project is to go and take this and take it further. We've looked at filters, we looked at mass, build your editor to combine them. Look at some of the other SVG things that are out there for you, some of the other filters available, some of the other tooling, maybe you can do some resizing, do some other fun stuff. I'm excited to see what you come up with, and we have one more video where we talk a little bit about the possibilities of where you can take this, but you've come a long way and now you're ready to complete your course projects. I'm looking forward to seeing them. 20. Final Step: As we wrap up this course, I want to leave you with a sense of the possibilities open to you with SVGs. We've looked a little bit at what's possible. We've looked at the structure of SVG code. We've learned how to manipulate it with CSS and we started playing around with some of the advanced filtering technologies available within it. SVG. However, this is a whole language it says rich of a language for creating images as HTML is for creating documents. There's so much more than we can cover in this course. It's wide open to you barely anyone is taking advantage of the power afforded by SVG. But if you look around and you can see people creating incredibly intricate interactive animated images, you can see people hold games by creating SVGs with advanced JavaScript frameworks like React. The possibilities are endless and it's open to you. Let's not take this course as a finished product, but rather as something that inspires you to dig in more. Just go to Code Pen and start searching for SVG animation examples, look around for SVG games. There's so many possibilities. If you want to learn more about me and what I do and other things that I teach about. You can find me on my website, Zendev.com z-e-n-d-e-v.com. I hope to see more of you in the future. All right, this is cable sign-in out.