InterviewDB
Question
·
Los Angeles
Implement 2D Canvas: Build a Drawing Surface with Shape Rendering and Hit Testing
phone
Question Details
Round 1 Coding
Problem
Implement a 2D canvas abstraction that manages a collection of shapes and handles rendering and hit-testing:
add_shape(shape)— add a shape (Circle, Rect, or Line) with id, position, color.move_shape(id, dx, dy)— translate shape by offset.hit_test(x, y) -> str | None—
return the id of the topmost shape at point (x,y), or None.
- render() -> list[str] —
return a list of draw commands in z-order (e.g. ["draw_rect(0,0,10,10,red)", ...]).
python
class Canvas:
def add_shape(self, shape: Shape) -> None: ...
def move_shape(self, shape_id: str, dx: int, dy: int) -> None: ...
def hit_test(self, x: int, y: int) -> str | None: ...
def render(self) -> list[str]: ...
class Rect(Shape):
def contains(self, x, y) -> bool:
**return** self.x <= x <= self.x+self.w and self.y <= y <= self.y+self.h
canvas.add_shape(Rect("r1", 0, 0, 10, 10, "red"))
canvas.add_shape(Circle("c1", 5, 5, 4, "blue")) # overlaps r1 at center
canvas.hit_test(5, 5) -> "c1" # topmost
canvas.move_shape("c1", 20, 0)
canvas.hit_test(5, 5) -> "r1"
Follow-ups
- How do you determine "topmost" — insertion order, z-index property, or both?
- Your
hit_testis O(n). For a canvas with 10,000 shapes, how do you speed this up (spatial index)? - How would you implement undo/redo for
move_shapeandadd_shape? - Describe how you would serialize the canvas state to JSON and restore it.
Full Details
Round 1 Coding
Problem
Implement a 2D canvas abstraction that manages a collection of shapes and handles rendering and hit-testing:
add_shape(shape)— add a shape (Circle, Rect, or Line) with id, position, color.move_shape(id, dx, dy)— translate shape by offset.hit_test(x, y) -> str | None—
return the id of the topmost shape at point (x,y), or None.
- render() -> list[str] —
return a list of draw commands in z-order (e.g. ["draw_rect(0,0,10,10,red)", ...]).
python
class Canvas:
def add_shape(self, shape: Shape) -> None: ...
def move_shape(self, shape_id: str, dx: int, dy: int) -> None: ...
def hit_test(self, x: int, y: int) -> str | None: ...
def render(self) -> list[str]: ...
class Rect(Shape):
def contains(self, x, y) -> bool:
**return** self.x <= x <= self.x+self.w and self.y <= y <= self.y+self.h
canvas.add_shape(Rect("r1", 0, 0, 10, 10, "red"))
canvas.add_shape(Circle("c1", 5, 5, 4, "blue")) # overlaps r1 at center
canvas.hit_test(5, 5) -> "c1" # topmost
canvas.move_shape("c1", 20, 0)
canvas.hit_test(5, 5) -> "r1"
Follow-ups
- How do you determine "topmost" — insertion order, z-index property, or both?
- Your
hit_testis O(n). For a canvas with 10,000 shapes, how do you speed this up (spatial index)? - How would you implement undo/redo for
move_shapeandadd_shape? - Describe how you would serialize the canvas state to JSON and restore it.
Free preview. Unlock all Figma questions →
About This Question
This is a reported interview question from a figma interview during the phone round.
More Figma Interview Questions
LeetCode
Apollo.io | Senior Frontend Engineer | L5
1p3a
Figma Machine Learning Engineering Fulltime Onsite Interview Experience
InterviewDB
Design Elements Intersection: Find Overlapping Rectangles and Compute Intersection Areas
InterviewDB
Keyword Highlighting: Highlight Multiple Keywords in Text While Handling Overlapping Spans
InterviewDB
Layer System: Implement a Composable Rendering Layer Stack with Blend Modes