An Excalidraw clone with React and TypeScript. Rough.js is used for the sketchy, hand-drawn style. I built the side project for learning purposes. The app is not responsive. I mainly focused on the functionalities since I already have plenty of projects that are responsive.
- Framework:
React.js(TypeScript) - Build Tool:
Vite - Graphics:
Rough.js(Canvas API) - Styling:
CSS
- CI/CD:
GitHub Actions - Containerization:
Docker&Docker-Compose - Cloud Hosting:
Vercel(Edge Network) - Security:
Dependabot&npm auditoverrides
- Unit/Component Testing:
Vitest&Testing Library - E2E Testing:
Cypress - Performance:
Lighthouse CI
This project serves as a showcase for Modern DevSecOps practices. Beyond the frontend logic, I engineered a robust CI/CD infrastructure to ensure high availability, security, and performance.
-
CI/CD Orchestration: Managed via GitHub Actions with parallelized workflows for testing and deployment.
-
DevSecOps: Implemented an automated Security Audit gate. Resolved high-severity ReDoS vulnerabilities in transitive dependencies using npm overrides to maintain a zero-vulnerability posture.
-
Infrastructure as Code: Containerized the application using Docker, providing environment parity between development and production.
-
Performance Budgets: Integrated Lighthouse CI to enforce frontend performance standards (LCP, TBT) on every deployment.
-
Automated Dependency Management: Configured Dependabot to proactively manage and patch the software supply chain.
Here's what you can do with ScratchPad:
-
Choose a Tool: You have pencils, lines, rectangles, and text tools. Pick one and start creating.
-
Draw and Move: Click and drag on the canvas to draw. To move something, select it and drag it to a new spot. Also, resize elements by dragging the corners. Resizing only works on rectangles or lines.
-
Edit Text: Click on the canvas and start typing to add text to your drawings. You can also edit existing text.
-
Zoom: Use Ctrl + Scroll or click on the buttons to zoom in for detail or out to see the whole picture.
-
Pan: Hold the Space bar and drag or use the middle mouse button to move around the whiteboard canvas.
Speed up your work with these shortcuts:
- Canvas Navigation: Press the Space bar and drag or use the middle mouse button.
- Undo: Ctrl + Z.
- Redo: Ctrl + Y or Ctrl + Shift + Z.
- Zoom In: Ctrl + Plus.
- Zoom Out: Ctrl + Minus.
I started by rendering a canvas with rough.js to create the base for all the drawings. Then, I focused on drawing on the canvas, allowing users to make lines, rectangles, and other shapes.
Next, I made sure users could move elements around. This was important for adjusting drawings. After that, I added the ability to resize elements to give more control over the shapes.
To make sure mistakes could be fixed, I implemented undo and redo features. I also added freehand drawing for a more natural sketching experience and a text tool to label or note on the canvas.
To navigate larger drawings, I put in pan and zoom tools. With everything functioning, I designed the whole UI to make it user-friendly and appealing.
Finally, I added testing with Cypress and Testing Library. I conducted end-to-end tests on drawing and manipulating text, lines, rectangles, and freehand drawings to make sure everything worked smoothly.
Along the way, while building everything, I took notes on what I've learned so I don't miss out on it. I also documented the behind-the-scenes processes every time a feature was added.
This way, I understood what I've built. The funny thing is, as soon as I started to document what happened behind the scenes and the features I've added, it made me realize that we fully understand something once we've actually taken a step back, thought about it, and documented what we've done. I think this is a good practice to follow when learning something new.
While the core focus was drawing logic, I treated the Deployment Lifecycle as a first-class feature. I shifted security 'Left' by integrating automated audits directly into the pull request flow. I also decoupled the build and deployment phases, allowing for specialized quality gates that ensure only verified, high-performance artifacts reach the production environment on Vercel.
Every deployment is audited for Core Web Vitals. You can view the latest Lighthouse Report in the GitHub Actions artifacts, ensuring the application remains fast and accessible despite complex canvas rendering logic.
During this project, I've picked up important skills and a better understanding of complex ideas, which improved my logical thinking.
- Logical Thinking: Creating the
useHistoryhook taught me to think about how to manage saving, undoing, and redoing actions. I had to really understand how to track changes and plan out user actions.
- Accuracy: I've become better at working with shapes and points, like knowing if a point is inside a shape. This required careful measurements.
- Math Skills: I used math functions to make sure everything was placed correctly and to calculate distances.
- New Tools: I found out about Rough.js, which lets me make graphics look hand-drawn. This was a new and exciting tool for me.
- Complex Functions: I spent time understanding the
getSvgPathFromStrokefunction, which turns drawing movements into smooth paths.
- Working with Points: I learned how to collect and use points from drawings, which involved understanding and managing data to reflect what the user does.
- New Knowledge: I learned about
useLayoutEffect, which helps make sure changes are done before the screen updates. This was useful for certain drawing functions.
- User Interaction: I worked with the wheel event listener, which allowed me to add zooming and panning features. This made the app more interactive and user-friendly.
Each part of this project helped me understand more about building apps, managing complex information, and improving user experience. It was more than just making a tool. It was about solving problems, learning new things, and improving my skills for future work.
- Add more colors to the color picker.
- Add more tools like a circle, eraser, and more.
- Add more shapes like triangles, stars, and more.
- Add more keyboard shortcuts to make things faster.
- Add more themes like dark mode, light mode, and more.
- Add more text options like font size, font color, and more.
- Instead of have any in two places, create a type for the rough.js elements.
To run the project in your local environment, follow these steps:
Standard Setup:
- Clone the repository to your local machine.
- Run
npm installoryarnin the project directory to install the required dependencies. - Run
npm run startoryarn startto get the project started. - Open http://localhost:5173 (or the address shown in your console) in your web browser to view the app.
Docker Setup (Best Practice):
- Run the command and build the Docker image.
docker-compose up --build- The app will be available at http://localhost:5173