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.