Now let's go ahead and let's add the Resize Observer and let's also add some functionality to Auto Zoom. So I'm going to go ahead and go inside of my Use Editor, make sure you are here. And what we're going to add here is we're going to add a specific use auto resize hook. Like this. And now let's go ahead inside of the hooks here and let's add use auto resize.
Let's go ahead and add use auto resize and let's just return it like this. So we can call it use auto resize like this. Or perhaps it's actually easier to just do this. Okay, let's keep it like that. Before we can continue here, I just want to go ahead and quickly add some use states here.
So I want to add the canvas and set canvas. I want to add container and set container. And let's go ahead and just define the types here. So the canvas can be null or fabric.canvas. Let's go ahead and write fabric.canvas and then null and same is true for the container so it's going to be HTML div element or null for both of these great So now I want to go back inside of my init method and let's go ahead and let's go right here after we do the initial canvas and clip path so before the test rectangle here because we're going to remove this part later anyway.
We're just keeping it here so you can, you know, play around with this little rectangle. So we're going to add set canvas, initial canvas and set container will be the initial container. There we go. So now we have them inside of our state. And what we can do now is we can pass it to hooks like use resize.
My apologies, use auto resize. So let's go ahead and do that. Let's extract this and let's pass in the canvas and the container. Let's go back inside of the use auto resize and let's go ahead and let's create the types for that. So interface use auto resize props.
We'll have a canvas which will be a type of fabric.canvas or null and we're gonna have a container which will be a type of HTML div element or null as well. Now let's go ahead inside of here and let's destructure the useAutoResize props. Let's add a canvas and a and a container and now inside of here I want to add a use effect I want to add my canvas and my container but let's go ahead actually my apologies I thought this was a reference but it's not right so we need to have this inside and let's just see all right so this says canvas null or undefined So let me just see how did I define this incorrectly? Oh yes, let's give it a default value inside of use editor. When we define the states, let's also write null as the default values here.
So we no longer have these errors. Now we can use out the resize here. What we're gonna have to do here is we're gonna have to add the resize observer. So let's do it like this. Let's define as a let resize observer to be a type of resize observer which comes natively or null.
So by default it won't exist. Only if we have both the canvas and the container available, only then are we able to add the resize observer. So we're gonna create the resize observer to that variable above using new resize observer and we're gonna go ahead and for now just console.log resizing. And then let's go ahead and still inside of this if add the resize observer dot observe container so that's what we are going to observe and then in the unmount we're gonna check if we have the resize observer resize observer dot disconnect so we don't have any overflow there we go Let me just format my document a bit. Perfect.
I just want to, can I do this? No, okay. Nevermind. Now that we have this, we should actually be console logging every time we resize. So Let's go ahead and refresh and let's try it out.
So there we go, it says resizing. And you can see whenever I move something, our container div, our flex box is also resizing. So that's what we wanted to detect. And now that we have that knowledge we can go ahead and we can implement an auto zoom function which we are going to call inside. So now it's time for us to create the auto zoom method.
So let's go ahead above the use effect and let's write const auto zoom. Let's call use callback here and let's give it an empty array for now like this first of all if there is no canvas or if there is no container we are going to break the method which also means we need canvas and container in our dev dependencies. Then let's define the width to be container offset width and the height to be container offset height. Now let's go ahead and do canvas set width to the new width and canvas set height to the new height. So this is the simplest zoom, right?
We are basically doing what we did in the initialize function, as you can see right here, we are setting the width and setting the height to the initial container but we are now doing it again in the AutoZoom. So let's see if we can already add that here and also added it to the dev dependency array. Right now you can see how I expand. Let's see if anything actually changes. You can see how something is happening, right?
So at least it is flickering, right? We can see that something is going on. You can see how my container is growing a little bit bigger. So we do have some changes happening. Let's go ahead and continue with this development.
So now what I want to do is I want to get the center. So const center is going to be canvas.getCenter. Let's define the zoom ratio which will be 0.85 percent. Now let's go ahead and let's get that workspace. So I'm going to call workspace.
Let's actually call it local workspace. Canvas, get objects. And then we're going to use find. We get the individual object and we're gonna find it by name clip. So let me go ahead and show you it like this.
So we are searching for the name clip because when we initialize our workspace we gave it a name of clip. Right, so that's how we find it. And now let's go ahead and do the following. Const scale will be fabric. Let me just see if we have fabric added.
We don't. So import fabric from fabric.util. Find scale to fit. Now we have a problem with this because it doesn't exist in the types but the method is here so let's just add tsignore here just make sure you don't misspell this method you can always look at my source code but because we don't have TypeScript it is prone to errors now so we're gonna scale to fit local workspace and inside of here we're gonna add the width and the height. And then let's go ahead and let's define zoom using that scale.
So we can now write zoom ratio times scale to get the proper zoom that we need for our object. And then let's go ahead and do the following. Canvas.setViewportTransform to be fabric.imatrix.concat. And then let's do canvas, zoom to point, new fabric.point. And in the first one, we're gonna do center.left.
And in the second one, we're gonna add center.top. And then we're gonna add a comma and the zoom. There we go. We're gonna continue forward. If there is no local workspace, we're gonna break the method.
But if it is, we're gonna go ahead and align the workspace as well. So let's find the workspace center to be local workspace getCenterPoint then inside of here let's go ahead and write viewport transform to be canvas viewport transform like this then we're going to check if canvas.width is undefined or if canvas.height is undefined or if we don't have viewport transform so let me format the document So if any of this is true, whoops, I did a mistake here Like this so if we don't have canvas width or canvas height and make sure you use the Identical undefined if you just do exclamation point that's not going to be good because it can be zero right but that's still a width so if any of that is true we're going to go ahead and break the method otherwise let's go ahead and let's write viewport transform 4 will be equal to canvas.width divided by 2 minus workspace workspace center dot X times viewport transform 0 Then viewport transform 5 will be canvas.height divided by 2 minus workspace center.y times viewport transform 3. And then canvas set viewport transform and passing the new viewport transform, which we have now carefully calculated in position to our canvas and our workspace center.
And now that we've done that, let's clone the local workspace. So we have cloned which will be fabric.direct. Inside of this cloned we're going to clip our canvas again because now we have a new workspace here and canvas request render all. Like this. So let's go ahead and let's see if we've done this correctly or not.
And as you can see how I expand my workspace stays centered even on the lowest screen it stays centered right here. So no matter how I expand now, I can first of all, use my entire screen. Okay, so it seems like we have this little bug here. We're going to explore that later. But more importantly, you can see how it keeps getting centered, right?
We do have some overflow, it seems. We're going to fix that later anyway, because our editor component is not correct, right? So if I go inside of my components here, my apologies, feature editor, this is not actually correct. So I'm just using this as an example, but later we're going to have some different positioning. But I wanted to demonstrate this to you.
So you can go ahead and try and zoom in and zoom out. And you should now see that it at least should appear more stable than it is at the moment, than it was before, right? So at least it appears centered. But of course we do have this bug with some overflow happening. We are going to resolve that as well.
Great, great job!