The Final DrawingEditor Modifications

Our save function will need to exist on the Razor Page code-behind file. Because of this, we require a way for our main DrawingEditor class to use that function as a callback. We also need to be able to create the JSON for the current drawing, and lucky for us, FabricJS provides a way to do exactly that:

Note the saveDrawing() function; this is not implemented quite yet. The next thing we need is to make the page handler that will "process" the POSTed drawing JSON. Since we're not actually doing anything with the JSON, the code is very short:

In a production system, we'd need to persist the drawing JSON to a datastore or database.

In normal circumstances, we'd almost certainly want the OnPostSave() method to return something, be it IActionResult, JsonResult, or just a string.

The Final Script

Now we need to return to the Razor Page and implement the saveDrawing() function to call the new OnPostSave() method. We also need to show and hide the "saving" status message on the status bar immediately below the canvas.

One additional thing Chris decided to do was put some extra code in to prevent "double-click" saving, so our save method can only be called one second after it was last called. You can see all of this code below:

The Last Hotkey

There's one last little thing we should do: since we already have hotkeys for cut, copy, paste, etc. we should implement the hotkey for save (Ctrl+S) as well. Here's the modifications we need to make to DrawingEditor to realize this:

GIF Time!

Let's see how this works in a GIF:

Pay special attention to the lower-right side of the GIF, where the "Saving" message will appear very briefly.

Conclusion

That's it! With this last feature, we have made our drawing canvas match the goal photo from the beginning of the series! Thank you, dear readers, for reading these posts about creating a drawing canvas with FabricJS and TypeScript! Chris and I are pretty proud of this sample, and we hope it helps you all in your projects.

For the final time, don't forget to check out the sample project for this series over on GitHub. It contains the final, working code for this series. Don't be afraid to make pull requests if you see a way we can improve!