Skip to content

fix: bake node color into canvas texture to preserve emoji colors#4

Merged
chiefcll merged 1 commit into
mainfrom
fix/canvas-emoji-color-tint
May 8, 2026
Merged

fix: bake node color into canvas texture to preserve emoji colors#4
chiefcll merged 1 commit into
mainfrom
fix/canvas-emoji-color-tint

Conversation

@chiefcll
Copy link
Copy Markdown
Contributor

@chiefcll chiefcll commented May 8, 2026

Summary

  • Bake node.color into CanvasTextRenderer.fillStyle instead of hardcoding white — text glyphs render in the correct color directly on the canvas, and emoji glyphs retain their native browser colors since they bypass fillStyle
  • Force shader tint to white (with worldAlpha) for canvas text nodes so the GPU doesn't double-tint the already-colored texture
  • Re-render canvas text on color change by overriding the color setter in CoreTextNode to invalidate layout when color changes on a canvas text node

Why

CanvasTextRenderer hardcoded context.fillStyle = 'white', producing a texture with white text + natively colored emoji. The shader then multiplied the entire texture by node.color. For dark text colors (light theme), this crushed emoji to near-black silhouettes.

Closes #1

Trade-off

Gradient-tinted canvas text (non-uniform colorTl/Tr/Bl/Br) will no longer produce a gradient since the shader corners are forced to white. This is acceptable because canvas text color is now baked into the texture, and gradient text is an edge case that's better served by the SDF renderer.

Test plan

  • Render <Text color={0x0f172aff}>🔥 hello</Text> with CanvasTextRenderer — emoji should retain native colors, text should be dark
  • Render <Text color={0xf1f5f9ff}>🔥 hello</Text> — both text and emoji should appear correctly (regression check)
  • Change color dynamically — text should re-render with the new color
  • Verify alpha/worldAlpha fading still works on canvas text nodes
  • SDF text rendering is unaffected

🤖 Generated with Claude Code

CanvasTextRenderer hardcoded fillStyle='white', causing the GPU shader
to multiply the texture by node.color as a tint. This crushed native
emoji colors to near-black when text color was dark (e.g. light theme).

Bake node.color directly into the canvas fillStyle so text glyphs render
in the correct color and emoji glyphs retain their native colors. Force
the shader tint to white (with worldAlpha) so the texture passes through
untinted. Re-render canvas text when color changes.

Closes #1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chiefcll chiefcll merged commit 2b24607 into main May 8, 2026
1 check failed
@chiefcll chiefcll deleted the fix/canvas-emoji-color-tint branch May 8, 2026 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 [BUG] - CanvasTextRenderer tints color-emoji glyphs with node.color, crushing native emoji colors

1 participant