canvas-fill-and-stroke

[CanvasRenderingContext2D] fill-and-stroke function

Status: explainer
Ticket: Open

CanvasRenderingContext2D offer the possibility to fill or stroke a path. Problem is, these are two separate action taken by the renderer. Meaning that doing both can lead to unexpected conflict between the two functions.

For example, setting shadow option and calling fill and stroke will draw a shadow for the fill and the stroke. There’s currently no easy way to draw one shadow for both fill and stroke.
Also, when using a lower than 1 globalAlpha value, fill and stroke will overlap.

Moreover, the order in which fill and stroke are called can drastically change the resulting output. Putting users are risk of generating unexpected result.

Proposal

interface CanvasRenderingContext2D {
    void fillAndStroke();
};

fillAndStroke will do both fill and stroke action according to the current CanvasRenderingContext2D state. However, both will be done in a single call and will share the same side effects.

Open issues and questions

Example usage

// Javascript example
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");

context.globalAlpha = 0.5;
context.beginPath();
context.rect(50, 50, 100, 100);
context.fillAndStroke();

Demonstration

| Test | Result | Result (stroke first) | Expected | | — | — | — | — | | Opacity |test opacity result |test opacity result with stroke first |test opacity result expected | | Shadow |test shadow result |test shadow result with stroke first |test shadow result expected |

Click on images to see the live version

Alternatives considered

Alternative 1

As per the proposed polyfill file, one could draw in an OffscreenCanvas and render the whole result in one call with drawImage. However, this has a few drawbacks:

For a peek at the performance drop, check out the Benchmark page.

References

none