```js // Linear gradient spanning the full width of the text const grad = ctx.createLinearGradient(x - w / 2, y, x + w / 2, y) grad.addColorStop(0, "#e63946") // start grad.addColorStop(1, "#457b9d") // end ctx.fillStyle = grad ctx.fillText(text, x, y) ``` **`fillText` vs `strokeText`** `fillText` fills the interior of each glyph. `strokeText` draws only the outline. Using both together with different colors produces interesting effects: a light fill with a dark stroke, for instance, holds up well against complex backgrounds. --- ## A detail from the original post that is worth understanding properly When you increase the text size and use a pattern as `fillStyle`, the pattern does not scale with the glyph. It keeps repeating at absolute coordinates, and the text acts as a mask that reveals portions of that pattern. This is the same behavior as CSS `background-clip: text`, but applied directly on the bitmap. A 200px text will expose a much larger window of the pattern than a 20px one. --- ## What changed from the original version The 2014 post relied on `modernizr.js` to detect Canvas support. That is no longer necessary: every modern browser supports Canvas 2D without caveats. The `jscolor.js` library was replaced by the native `type="color"` input, which has had universal support since 2016. And the state management that used to live as loose variables inside `canvasApp()` now sits explicitly and traceably in the React component's state. --- ## Next steps From this component you can add image export with `canvas.toDataURL("image/png")` and wire up a download button. You can also load Google Fonts via the `FontFace` API before drawing, which opens up a wide range of typographic options. And if you want to animate the text, a `requestAnimationFrame` loop inside `useEffect` with a time variable produces wave or rotation effects without much effort. The Canvas is one of the most powerful primitives on the web platform. Knowing how to use it well, even in an era of high-level libraries, is a genuine advantage.

