Skip to content

fix(editor): render collaborator indicators on canvas#7759

Merged
ds300 merged 3 commits intomainfrom
fix/canvas-collaborator-indicators
Jan 28, 2026
Merged

fix(editor): render collaborator indicators on canvas#7759
ds300 merged 3 commits intomainfrom
fix/canvas-collaborator-indicators

Conversation

@ds300
Copy link
Copy Markdown
Collaborator

@ds300 ds300 commented Jan 28, 2026

After the 2D canvas indicator rendering change (#7708), collaborator shape indicators were no longer being rendered. This was because CanvasShapeIndicators only rendered the current user's selected shapes, while collaborator indicators went through the SVG-based CollaboratorShapeIndicator which now returns null for canvas-enabled shapes.

This PR fixes the issue by:

  • Adding collaborator indicator rendering to CanvasShapeIndicators with per-collaborator colors and 0.5 opacity
  • Extracting shared collaborator state logic to collaboratorState.ts to avoid duplication
  • Updating LiveCollaborators to only render SVG indicators for shapes that use legacy indicators (for backwards compatibility with custom shapes)

Relates to #7437

Change type

  • bugfix

Test plan

  1. Open a multiplayer session with two users
  2. Have one user select shapes
  3. Verify the other user sees the collaborator's selection indicators with the collaborator's color
  • Unit tests
  • End to end tests

Release notes

  • Fixed collaborator shape indicators not rendering after the canvas indicator change

Note

Restores collaborator selection indicators after moving shape indicators to the canvas renderer.

  • Renders collaborator shape indicators in CanvasShapeIndicators with per-collaborator color and 0.7 opacity, drawn beneath local indicators
  • Adds useActivePeerIds$ in usePeerIds to track which collaborators should be shown based on timed activity transitions
  • Extracts shared collaborator logic to utils/collaboratorState.ts (getCollaboratorStateFromElapsedTime, shouldShowCollaborator)
  • Updates LiveCollaborators to use shouldShowCollaborator and only render SVG indicators for shapes using legacy indicators (canvas handles the rest)

Written by Cursor Bugbot for commit ce0f1f9. This will update automatically on new commits. Configure here.

@vercel
Copy link
Copy Markdown

vercel bot commented Jan 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
examples Ready Ready Preview Jan 28, 2026 1:33pm
5 Skipped Deployments
Project Deployment Review Updated (UTC)
analytics Ignored Ignored Preview Jan 28, 2026 1:33pm
chat-template Ignored Ignored Preview Jan 28, 2026 1:33pm
tldraw-docs Ignored Ignored Preview Jan 28, 2026 1:33pm
tldraw-shader Ignored Ignored Preview Jan 28, 2026 1:33pm
workflow-template Ignored Ignored Preview Jan 28, 2026 1:33pm

Request Review

The collaborator state calculation in CanvasShapeIndicators was using
Date.now() inside a computed value, which isn't reactive to time
passing. Added useActivePeerIds$() hook that handles time-based state
transitions by periodically re-evaluating collaborator states on the
same interval as LiveCollaborators.

Also extracted shared collaborator state logic into collaboratorState.ts
to avoid duplication between LiveCollaborators and CanvasShapeIndicators.
@ds300 ds300 force-pushed the fix/canvas-collaborator-indicators branch from 7b03cd7 to 64a9a3c Compare January 28, 2026 13:08
ds300 added 2 commits January 28, 2026 13:27
When a collaborator has no lastActivityTimestamp, using 0 would result
in a very large elapsed time. Using Infinity ensures Math.max returns 0,
treating them as recently active until their state can be determined.
Improves visibility of collaborator shape indicators while still
maintaining visual distinction from local selection indicators.
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

ctx.lineWidth = 1.5 / zoom
for (const collaborator of collaboratorIndicators) {
ctx.strokeStyle = collaborator.color
ctx.globalAlpha = 0.7
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Canvas collaborator opacity doesn't match SVG indicator

Medium Severity

The comment on line 206 states "Use 0.5 opacity to match the original SVG-based collaborator indicators", but the code on line 210 sets ctx.globalAlpha = 0.7. The SVG-based CollaboratorShapeIndicator in LiveCollaborators.tsx uses opacity={0.5}. This mismatch causes collaborator selection indicators to appear at different opacities depending on whether the shape uses canvas-based or legacy SVG-based rendering.

Fix in Cursor Fix in Web

Merged via the queue into main with commit 09e80a0 Jan 28, 2026
17 checks passed
@ds300 ds300 deleted the fix/canvas-collaborator-indicators branch January 28, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant