Convert Photos to Animated SVGs with React, React Hooks, and TypeScript | Chris Frewin | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Convert Photos to Animated SVGs with React, React Hooks, and TypeScript

teacher avatar Chris Frewin, Full Stack Software Engineer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Introduction

      0:43

    • 2.

      How to Convert Photos into Optimized, web-Ready SVGs and Port to React TypeScript

      24:50

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

84

Students

--

Project

About This Class

Learning your way around SVGs is an important skill in any designer or developer's skillset. In this short "mini" course, which has just one lesson, we'll go through a workflow of bringing an image captured on a phone, editing it with opensource tools Gimp and Inkscape, and optimizing it and porting to the web via a React TypeScript project. As a bonus, we'll write a custom React Hook to animate So even if you are not a developer, you may find this course interesting as to how bitmap imagines can be cleanly converted into SVGs. It's the last half of the mini-course that gets into the software part implementing the React, TypeScript, and Hook implementation.

Meet Your Teacher

Teacher Profile Image

Chris Frewin

Full Stack Software Engineer

Teacher

Hi everyone!

I've been a professional full stack software engineer for 7+ years, and I've been programming for many more. In 2014, I earned two separate degrees from Clarkson University: Mechanical Engineering and Physics. I continued at Cornell for my M.S. Degree in Mechanical Engineering. My thesis at Cornell was a technical software project where I first learned Bash and used a unique stack of Perl and Fortran, producing a publication in the scientific journal Combustion and Flame: "A novel atom tracking algorithm for the analysis of complex chemical kinetic networks".

After opening up my first terminal while at Cornell, I fell in love with software engineering and have since learned a variety of frameworks, databases, languages, and design patterns, including TypeScrip... See full profile

Level: Intermediate

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Introduction: Learning how to use an optimized SVGs is an important skill in any designer or developer skillset. In this mini-course, which just has one lesson, we are going to go from a picture that's taken with just a normal phone. We're going to optimize that picture. We're going to convert it into an SVG. We're then going to optimize that SVG to get it ready for the web, will then create a React SVG component. And then as a bonus, we'll throw in a custom React hook to animate the background of that SVG. And all the while and react will be using TypeScript. This mini course was really fun for me to record. I hope you learned a lot. Now let's get started. 2. How to Convert Photos into Optimized, web-Ready SVGs and Port to React TypeScript: I thought it'd be cool to turn this really cool logo on the back here and the front near with the sixth six year anniversary. But it'd be cool to turn it into an SVG. And we'll even as a bonus, I'll throw in a custom React hook to change, ultimately, this pink background color. So as we move the mouse around, we'll change the background color. So I'll show you the full flow. I've taken picture of the front back of the shirt. So yeah, let's let's hop into the code and start looking at it. Like I said, I've already taken a picture of the front and back of the shirt just with a normal iPhone camera and nothing special. The first thing we're going to do towards making our react based SVG is opening these two images in GIMP. So I'll select both of them. And we'll open them up in GIMP here. Now that we've got both images in here, the first thing we'll do is rotate them. So we go down to Transform, rotate 90 degrees. And also for the back of the shirt, rotate 90 degrees. Then what I'm gonna do is go up to image mode index. And I am going to convert this to a three color image. So we've got black, light blue, and this bright pink color. So hopefully, Gimp does a good job for us. Let's see how that goes. Great. So it basically more or less has done a good job. I'm going to also do the same here. And in this case, we don't have three colors, but we have 12345, I guess. I believe these are the same color. So let's try indexing with five colors and see what happens. Alright, so that looks pretty good. The next thing we're gonna do is export these images. I'm just going to call this shirt back clean. Make sure that 100 quality is set. And same for the front here. And I'll call this likewise. Shirt clean. We've got our 100 quality and will export those. Next, what we're gonna do is open up Inkscape. And now that we've got Inkscape open, we're going to import both of those cleaned up pictures. I've got the two right here can select both with Command and click. And we're going to open those up. Now, Inkscape will ask you here, few settings we want smooth to optimize the quality. Embedding is fine and from file. So just make sure it really, the only important one here is smooth because we want the highest quality image to be important. So Inkscape will by default open up these two separate images. We can take the front here, and I'm just going to copy that over into the back. We've got the front in the back side-by-side here. They're still both bitmap images, and this is where the magic comes in. So as we said, this is a three color image, and this is a five color image. So let's do the three color first. Once you've selected your bitmap. I'm gonna go up here, Trace Bitmap. And we want to do multiple scans. And instead of brightness steps, we won't colors. And then we want three scans, one per color. Typically I remove all these optimizations, but your mileage may vary. The nice thing is you can continually update and decide if you want to fiddle around with these values. Sometimes doing smooth provides a nice smoother edges, but looks like the default here, without any optimization or selecting smooth, looks pretty good. So I'm going to say OK. And you'll see now here, exactly overlaid with the bitmap. It's not a bitmap like this still is, says image down here. We instead see it's a group of three objects. So that means the trace worked perfectly. I'm going to just move that over here and I'm gonna get rid of the old image. Now I'm going to do the same for the back of the shirt. Trace Bitmap. Multiple scans. In this case we have five colors. Let's update it, see if it picks up all the colors. Perfect. That looks great. Let's say, okay. And now we see we have a group of five objects. So I'll move that again over and get rid of the old image. So now we're gonna do is clean up these images. So for the front of the shirt, I actually don't need this background. I just want the lettering. So the blue and the pink. So the first thing I'm gonna do is ungroup. This group of three colors. Typically the trace automatically groups. And altogether, we can just ungroup that. And we see we've selected this dark path here. We're just gonna get rid of that. So it looks like there were some artifact thing when we converted in GIMP, but that's also no problem. Just be careful when you select here. We don't want to delete the whole layer. We just want to delete this corner. And since this is now an SVG, we just want the nodes from this SVG and we're going to delete this corner out. So we're just left for the pink layer. Just this nice lettering. So we can do the same for the back of the shirt. I'm going to ungroup that. And here we have to be a bit careful because if we look closely in the way that the shirt was printed, this black isn't a separate color. This literally is the background of this image. So we will need to keep some of this background, but what I'm going to do is kind of shape it back so it creates an outline around this whole image. Will look a little bit nicer. I think. The first thing I'm gonna do is get rid of this red. I'm not sure how it showed up exactly, but I'm gonna get rid of that red layer altogether. So we can just delete that. And as I said, I'll start reshaping this black background. So we can do a lot of optimizations here. I'm going to delete the majority of these nodes and we can start cleaning up. Now, you may find that some point you need another node. That's easy enough to solve. You just make sure that at least two nodes are selected with Shift-click. And we simply press the plus button here to insert a new node, I'm going to need a few more. So even while these are all three selected, I'm going to again press the plus button and you'll see that it actually puts a new one in-between each selected. So that should get me some pretty good mileage here. Now we'll do is pull this up and over. Just put it on top. That looks pretty nice. And I noticed that this color didn't really transfer over perfectly. I'm just going to take Aqua. That looks really nice. And I'm also going to ensure that the subtitle here in this background are the same color. Just for a little bit of unity. Can copy this hex code. And when I pick this here, can paste this back in. And that looks pretty good. I mean, the background here is not super clean, but that's of course not the point of this video. That's why I've sped through a lot of this stuff. And of course, as we know, you can find infinite SVGs on the Internet. So sometimes you'll start anyway with an SVG. This was just a bit of a bonus to show you guys my workflow of how I convert bitmap images into SVGs. We're almost done. I'm going to select this and go to document properties. I'm going to resize the page to the content. I'm going to add some margins. Probably 50 is pretty good. Just make sure that when you do this, your units are in pixels. If you're an inch or something, you're going to have huge margins. But 50 seems pretty decent. And I think this is good for us to save. So I'm going to Save As and I'll just put shirt design. And of course, with the SVG extension. Now here, Inkscape offers us to SVG options, the Inkscape SVG or the plane SVG. And since we're heading towards web, we want to go to plain SVG. Inkscape will drop out a little bit of their markup. So it's not so verbose. But as we'll see shortly, we're going to optimize the SVG even further. So I'm going to save that. Now just to illustrate what we're about to do here, I'm in my downloads. This is the SVG we've just exported. And I'm going to open this up with Visual Studio Code. We can see here there's quite a bit of junk around here. This is a huge SVG. Wouldn't it be great if there was a tool that could reduce the size of the SVG we just exported. So we can use it easily or more easily in React. Luckily, there is such a tool for us and that is this SVG OMG tool by Jake Archibald. It's hosted on one of his GitHub Pages. So I'm going to open up the SVG we just exported. And now the cool thing with this tool is that we can play around with quite a few settings, ultimately reducing the size of our SVG. Typically, the ones that saved the most space are these two, but you do have to be careful. If I start to reduce the precision too low, you may start to see some strange edges and so on. But you can see by doing that, we're already down to 16 kb. But just so it's not so rough, I think I'll leave the number precision at one. And we can play a little bit with the transform precision. I don't seem to notice anything there. You can prettify the markup. Can do a multi-pass. Not sure I see what the differences there, but we save a little bit. So we'll take that. And immediately we can simply press Copy here, and this SVG is copied to our clipboard. Now I'm in code sandbox and we're going to create a sandbox. And of course, react with TypeScript. And the first thing we're gonna do here is create a new folder called components. And I'm going to create a new component called SVG is a TSX file. And it's just a functional component. Now, we could try and just paste in the SVG we just copied. And if I clean this up, we are going to have some problems. And essentially the problem is that since the SVG is original XML, it's not exactly ready for JSX. Luckily, there is another tool we can use for that. And this tool is magic dot React js.net. So we can just paste in our SVG and the generator will generate for us valid JSX syntax. Now, for some reason it always decides to create a class component. But of course we only need the markup within the return statement. So if I scroll all the way down here, we're going to have everything we need and we can go back into our sandbox and try this again. Now, we shouldn't have any syntax warnings when I format the document. Perfect, so I'm going to save this shirt SVG component, and I'm going to clean up the app component here. Let's put React plus SVG plus TypeScript equals heart. And I'm going to add in my SVG component. I'll import that from opponents, SVG. So this is already looking pretty good. And as I mentioned, we would use a custom hook so that as we move the mouse around the screen, we would change this background color just to make it a little bit fun. And I think also what would be really cool is we change both of these colors. So first, we have to hop back into our SVG, identify which path or which paths are contributing to these. And then we'll use the hook to change the color according to the mouse position. So first let's hop in here. And if we look at the first path listed, we've got this color. Okay, that's the, this light beige color. Then we've got this FC color. Bingo, we've found our color. Now, if I look for this, yes, exactly. I should see it twice. And this is the color that we want to change as the mouse moves. The first thing I'm gonna do is instead of keeping this hard-coded as a string, I'm gonna change this to a variable called simply color. And of course, code sandbox is going to yell at us because we haven't defined that yet. So up here, I'm going to say color. And let's call this hook, which has yet to be defined and yet to be implemented. Let's call it something like use color on mouse. Move. Now to actually implement this hook. I like to keep my code organized. I typically put my hooks in a separate hooks folder. We can call it the same name, use color on mouse move and will export const, use color on mouse move. And for now, let's just return red. We can already check to see if we've connected all the dots correctly. So I will import, use color on mouse move from hooks. That's back one folder. Use color on mouse move. Nice. So we're halfway there. We've selected the correct color we want to modify. And now it's just the actual animation when we move the mouse to change this color. So we can add the return type definition and that we always want to string to be returned from this hook. And of course, since the color itself will be changing on the mouse move, we're going to use use state to define our color. So we've got constant color, set color, and that is used state. And I'm going to continue to use red here as the initial value. And we need to import that from React. Alright, everything is still okay. Now to actually start listening to the mouse move, That's a window. Add event listener. And the event is mouse move. And I'm going to define a mouse move function. Now in React, it's not a best practice to just define this out in the open. We should do a unmount and also unmount cleanup. So I'm going to put this into a user effect hook that is on Mount. With a empty dependency array. I would add this event listener. And the cleanup function, as we know, is when we return a function from US effect. And that would be window dot, remove event listener. Now smooth and on mouse move. So now let us define this mouse move function. And if we look at this add event listener for mouse move, we see we get a mouse event. So that would be passed in this function. And since our image takes up quite a lot of the screen, I don t think it's too naive as an initial implementation to take the full dimensions of the screen and base that on some sort of percentage of where we currently are with our mouse. So e.g. the percent x of our mouse's location will be the client x divided by the inner width of the screen. And the same for why the window. And then perhaps as an average percentage, we can sum the 2% x plus y, divided by two. Now we have some sort of percent. And what comes to mind immediately is that we can have some sort of mixing of colors. So the easiest thing right now would be perhaps two colors. And with this present, you have some sort of mixing between them. You can try and write your own function to do this given two colors. But as for me, I'm going to use a very popular dependency for doing this type of stuff. And it's called chromosomes AS. And with chroma js, we can import Kromer from a JS and we can define a scale using Chrome's scale function. So that is chromatic scale. And we can pass one or more colors. For now, I think I'll do something. Let's try pink and purple. And I'm also going to change this initial color back to pink, so it's closer to what we originally had and the design. Now with this scale mixing in-between them, given a decimal, which is exactly what this will be end with this scale object. It says simple as calling. Scale on the average. And then getting a hex. So I'm going to call this color. Then of course, set the color to the state, which will trigger this hook to run and then of course return the new color. And the last thing to clean up here, it looks like code sandbox is complaining or rather TypeScript is complaining. Can't find the chroma JS types. So let's also add the types for chroma js. Now we can clean this up and let's reach fresh the app. See our handiwork here. Very cool. So as we move the mouse around, goes from pink to purple. And because of this algorithm, we've set here, of course, the total 0% is when both x and y are zero, this will get you as close to pink as possible. And when x and y are close to the inner height or inner width, this will give you the closest to purple. So as the last kind of cherry on top, we're going to go back into our SVG and fix. It looks like there's some small border issues that we could clean up. And we can clean this up simply by adding a small stroke width to our black SVG here. So I'll just do that. This black path of the SVG is in fact this one with this dark color. And so we see the first thing that's missing actually is the stroke color itself, which in SVG language is denoted simply by stroke. And I'm going to make the stroke, of course the same color. The fill. Save that and refresh here. That may have done something, but let's bump up the stroke up to one and see how that looks. Reload here. It's almost solved. Maybe if we go up to two, that will finally do this for us. Very nice. Still see here, Let's see how it looks. If we jump all the way up to four. Alright, that's pretty good. We could go back into Inkscape and fix these two small pointers here, but I'm pretty satisfied with how this came out. Nice, fun little project we did. I hope you learned something about making bitmaps turn into SVG is turned into cleaner SVGs. This was really fun for me. And yes, Let me know if you want more details on tips and strategies for building these custom hooks. Other than that, I'm super happy to be back and I will see you guys next time. Take care.