TL; DR
I built a Figma clone called Bigma to showcase my portfolio in a creative way that no one has done before. You can access it here.
Below you will find:
The story behind how I got the idea.
The implementation of Bigma.
The story behind Bigma
If you have followed me for a long time, you would know I have a tradition of upgrading my website every year.
It started out in March, 2022 where I first launched my blog, which was made in Hugo using a slight mod of Paper Mod.
Then, in January 2023, I wrote a simple portfolio in Vue with some 3D CSS + ThreeJS and published it on portfolio.binhph.am (which later was moved to binhph.am as I migrated my blog to Substack)
Now, in 2024, to ignite such tradition again, I needed to build something neat to showcase my skills in a new way that nobody has done before.
What’s everybody doing?
Currently, cool websites around the globe sit nicely in 2 major categories:
3D: Sites implementing 3D elements with interaction to enhance user experience. Examples can be found on ThreeJS or Awwwards.
2D: Sites using traditional 2D design elements. Examples can be found CodePen.
If I want to build a cool site, I probably should pick a discipline to follow. To pick the discipline, I have 2 rules:
I must implement most functionalities of the site from scratch, except the core framework. This means no 3D libraries since implementing ThreeJS from scratch probably means I’m unemployed.
I must do something that nobody has done before. This means if I can find a project that has the same idea as mine, I won’t do it.
So the choice is simple: make a 2D site with a cool twist that nobody has done before.
That was the origin of Bigma.
How Bigma was built
Disclaimer: I won’t go into detail of building Bigma here. I won’t share the source code as well. However, I will share the exact resources I used and the comments I had on those resources to save your time if you want to build your own `${your_first _initial}igma`.
Why: I figure it’s a cool project for everyone try to do and learn the fun of Infinite Canvas. Besides, the code itself is not significant if you already know some frontend framework on the medium level. For example, knowing how hooks are implemented in React or how server components work in React.
Infinite Canvas: The future of collaboration.
“Infinite canvas tools are a way to view and organize information spatially, like a digital whiteboard. Infinite canvases encourage freedom and exploration, and have become a popular interface pattern across many apps.” - CEO of Obsidian, Steph Ango on JsonCanvas
The core of Figma is the usage of an Infinite Canvas. It is what sets it out from other products like Canva.
To implement an infinite canvas like Figma, there are currently two ways:
Using <Canvas/>: This is the method that’s employed by Figma. It’s versatile, has great customization space and it’s fast. There are frameworks which already support doing stuffs like this (mentioned below). Since canvas deals with the fundamental graphical elements, pixels. You are very limited in terms of interactivity and type of graphics out of the box.
Using CSS: This is the method I used. Basically I built the infinite canvas by using transform scale and transform x-y location on HTML elements. This method is versatile, but not as versatile as <canvas/>. However, it allows you to use normal CSS and HTML for your nodes, along with JS event handlers.
Using CSS
If you do it the CSS way, I recommend reading the below materials:
1. Figma-like Canvas in React by Vikram Thyagarajan
This is a great start. Vikram wrote Infinite Canvas implementations using both CSS and <canvas/>. You can learn a lot from his blog.
However, the control in his implementation is limited. He only wrote controls for wheel event. If you want to support touch, mouse and wheel event like my implementation, you will have to dig deeper into the nuances of DOM events and default browser behavior.
Secondly, there is an amount of redundant code in his implementation in React. This is because he brought most of his code from his <canvas/> version. I recommend reading his blog carefully and rewrite the implementation based on your understanding to remove redundant code, especially the state management.
2. JsonCanvas by Steph Ango
Steph Ango is the CEO of Obsidian. Yes, the Obsidian that you use to take notes.
If you know, Obsidian is famous for its infinity canvas or graph-based note taking. To support exchanging these graph-based notes between different applications, he built a standard called JsonCanvas.
Reading through the specifications of this data format will help you understand which kind of objects and classes to implement if you want to build an Infinite Canvas the standard and compatible way.
Also, Steph wrote his own implementation of Infinite Canvas based on CSS in VanillaJS. You can read the source code here.
Using <canvas/>
If you do it the <canvas/> way, I recommend reading the below materials. Since this wasn’t my method of choice, I don’t have battle-tested experience regarding this path and can only provide the links.
Using <canvas/> is popular and is employed by most large design companies. This is due to the nature of canvas that helps you export in picture formats easily. You can export to images, pdfs or svgs easily using <canvas/>.
The same cannot be true for the CSS approach, unfortunately.
1. Build and Deploy a Figma Clone by JavaScript Mastery
2. FabricJS
The Stack of Bigma
Bigma is built on NextJS, deployed on Vercel. The infinite canvas engine is wrote from scratch, including gestures and interaction with nodes.
Other supporting frameworks and libraries:
Framer Motion is used to implement animations in the Onboarding screens.
Heroicons are used for icons inside Bigma.
TailwindCSS for styling.
What’s next
I will include more interactive features on the site in the next few months. I didn’t really build the site to showcase my folio, just a way to serve my curiosity and relieve stress after work.
I think it turned out great.
If you are interested in having a chat, ping me on my LinkedIn. I’m always open for new opportunities and new friends.
Amazing work Binh! I’ve been looking into an implementation like this for a while now to try out for my own little projects 😅 but couldn’t find the right resources. Thanks for sharing them!
Mind if I ask how did you find them in the first place?