Skip to content

Add gradient support to renderer API#1353

Merged
obiot merged 10 commits intomasterfrom
feature/gradient-support
Apr 4, 2026
Merged

Add gradient support to renderer API#1353
obiot merged 10 commits intomasterfrom
feature/gradient-support

Conversation

@obiot
Copy link
Copy Markdown
Member

@obiot obiot commented Apr 4, 2026

Summary

Closes #1352

  • New Gradient class with addColorStop(), matching the Canvas 2D API
  • createLinearGradient(x0, y0, x1, y1) and createRadialGradient(x0, y0, r0, x1, y1, r1) on both renderers
  • setColor() accepts Gradient objects — works with all fill methods (fillRect, fillEllipse, fillArc, fillPolygon, fillRoundRect)
  • Canvas renderer: uses native CanvasGradient directly as fillStyle
  • WebGL renderer: renders gradient to CanvasRenderTarget texture via drawImage; non-rect shapes use stencil masking
  • Gradient state tracked in RenderState and saved/restored with save()/restore()
  • New gradients example showcasing sky backgrounds, health/mana bars, metallic button, gradient-filled shapes, and rainbow star polygon

Test plan

  • 24 unit tests: API, caching, setColor, fillRect, color/gradient mixing, save/restore
  • Visual parity verified between Canvas and WebGL renderers
  • Gradient example works on both renderers (AUTO, CANVAS)

🤖 Generated with Claude Code

…Gradient)

Closes #1352

- New Gradient class with addColorStop(), matching Canvas 2D API
- createLinearGradient() and createRadialGradient() on base Renderer
- setColor() accepts Gradient objects on both Canvas and WebGL renderers
- Canvas: uses native CanvasGradient directly as fillStyle
- WebGL: renders gradient to CanvasRenderTarget texture, draws via drawImage
- WebGL non-rect shapes (ellipse, arc, polygon, roundRect) use stencil masking
- Gradient state saved/restored with save()/restore() via RenderState
- Canvas renderer restore() handles CanvasGradient fillStyle gracefully
- New gradients example showcasing sky, health bars, shapes, rainbow star
- 24 unit tests covering API, caching, save/restore, and color/gradient mixing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 4, 2026 10:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class gradient fills to the melonJS renderer abstraction, aligning the engine’s drawing API more closely with the Canvas 2D API while supporting both Canvas and WebGL backends.

Changes:

  • Introduces a new Gradient class (addColorStop, canvas/texture generation + caching) and exposes createLinearGradient / createRadialGradient on the base Renderer.
  • Extends Canvas and WebGL renderers to accept gradients via setColor() and render gradient fills across primitive fill methods.
  • Adds unit tests, a new gradients example, and updates docs/changelog to reflect the new API.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Links the rendering API bullet to the wiki page.
packages/melonjs/tests/gradient.spec.js Adds unit tests for the new Gradient API and renderer integration.
packages/melonjs/src/video/webgl/webgl_renderer.js Implements gradient support in WebGL, including stencil-based masking for non-rect shapes.
packages/melonjs/src/video/renderstate.js Tracks gradient state in the save/restore render state stack.
packages/melonjs/src/video/renderer.js Adds gradient factory methods to the base renderer API.
packages/melonjs/src/video/gradient.js New Gradient implementation (color stops, canvas gradient, POT texture canvas).
packages/melonjs/src/video/canvas/canvas_renderer.js Implements gradient support for Canvas via native CanvasGradient.
packages/melonjs/src/index.ts Exports Gradient from the public API.
packages/melonjs/CHANGELOG.md Documents the new gradient renderer API.
packages/examples/src/main.tsx Registers the new Gradients example route.
packages/examples/src/examples/gradients/ExampleGradients.tsx Adds a gradients showcase example scene.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…ting, cache example

- WebGL setColor: preserve existing alpha instead of forcing 1.0
- WebGL restore: sync _currentGradient from renderState
- #gradientMask: nest within existing mask levels instead of clearing stencil
- Example: cache gradients in onActivateEvent, reuse across frames

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

obiot and others added 2 commits April 4, 2026 18:37
…s, test name

- RenderState: add @import for Gradient type
- Gradient.addColorStop: validate offset is 0.0-1.0
- WebGL renderer: fix orphaned #generateTriangleFan JSDoc block
- Test: rename misleading "Color objects" test to "store color stop as string"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… cache invalidation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 4, 2026 10:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

obiot and others added 2 commits April 5, 2026 06:44
Closes #1351

- setLineDash() and getLineDash() on base Renderer, matching Canvas 2D API
- Canvas renderer: pass-through to native ctx.setLineDash()
- WebGL renderer: #dashSegments splits line segments based on dash pattern
- Dash applied to strokeLine, path-based stroke, and strokePolygon
- Dash state saved/restored via RenderState
- Graphics example: second zigzag line now uses dashed pattern
- 9 unit tests covering API, stroke, paths, and save/restore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- drawImage: force GPU texture re-upload for gradient canvases
- Gradient: keep _renderTarget on addColorStop (prevent GL texture leak)
- Gradient: fix class JSDoc to reference base Renderer methods
- toCanvas: document canvas resize cache invalidation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 4, 2026 22:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

obiot and others added 2 commits April 5, 2026 07:05
- setLineDash: filter rejects negative, NaN, and Infinity values
- #dashSegments: skip zero/negative dash values to prevent infinite loop
- drawImage: only re-upload gradient texture when dirty
- Canvas renderer: fix JSDoc ordering for strokeLine/setLineDash
- Remove orphan JSDoc block in WebGL renderer
- 23 linedash tests: validation, edge cases, all stroke methods, save/restore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…clone)

setLineDash() creates a new array via filter(), so the reference is safe
to store directly. Added test proving nested save/restore stays correct.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 4, 2026 23:12
- Remove lineDashOffset from RenderState (never read, only written to 0)
- Add tests: solid after restore, dashed after restore, alternating 3-level
  nested save/restore, mixed dashed strokeLine with solid path stroke

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

packages/melonjs/src/video/renderstate.js:58

  • New state fields currentGradient, lineDash, and lineDashOffset are introduced here, but RenderState.reset() doesn’t currently restore them to their defaults. That means renderer.reset() can leave gradient/dash state active across resets. Please update RenderState.reset() to set these back to null / [] / 0 alongside the other state resets.
		/**
		 * current gradient fill (null when using solid color)
		 * @type {Gradient|null}
		 */
		this.currentGradient = null;

		/**
		 * current line dash pattern (empty array = solid line)
		 * @type {number[]}
		 */
		this.lineDash = [];

		/**
		 * current blend mode
		 * @type {string}
		 */
		this.currentBlendMode = "none";

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Replace _needsReupload hack with proper invalidate(renderer) call
- toCanvas() now accepts renderer parameter for GPU texture invalidation
- Fix all-zero dash infinite loop with early bail-out
- Add infinite loop tests for all-zero dash patterns

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@obiot obiot merged commit ee6f2b4 into master Apr 4, 2026
6 checks passed
@obiot obiot deleted the feature/gradient-support branch April 4, 2026 23:33
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.

Renderer: add gradient support

2 participants