Question

In HTML5 CanvasRenderingContext2D, is it possible to add text to the current path, e.g. for clipping?

// rectangle clip
context.beginPath();
context.rect(0,0,100,100);
context.clip();

// clip to text
context.beginPath();
context.text("HELLO WORLD", 0, 20); // this function does not exist
context.clip();
Was it helpful?

Solution 2

Is it possible to add text to the current path, e.g. for clipping?

The simple answer is no, text paths are not exposed to us through canvas context so we cannot use them for things such as clipping.

The only way is either to:

  • Use composite mode to "punch" a hole for the text. Works much in the same way as clipping but is related to mattes more than paths.
  • Extract the text paths from fonts as polygons manually and use that with line, Bezier etc. A library that can help extract font paths could be opentype.js.

OTHER TIPS

You can use compositing to draw into text (effectively clipping to inside the text)

context.globalCompositeOperation="source-in" will draw new drawings only where the exsiting text and the new shapes overlap (any non-overlapping areas are made transparent).

Here's example code and a Demo: http://jsfiddle.net/m1erickson/yWuw7/

enter image description here

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var img=new Image();
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/water.jpg";
    function start(){

        canvas.width=img.width;
        canvas.height=img.height;

        ctx.font="138 verdana";
        ctx.fillText("See the",20,150);
        ctx.fillText("Sea",20,300);
        ctx.globalCompositeOperation="source-in";
        ctx.drawImage(img,0,0);

    }

}); // end $(function(){});
</script>
</head>
<body>
    <h4>Water image clipped to text using Compositing.</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

If you want to put a rectangle around the text, you can then use another composite ("destination-over") which lets you draw new shapes under existing pixels

ctx.globalCompositeOperation="destination-over";
ctx.fillRect(15,20,275,150);

enter image description here

[ Addition: applying clipped text to an existing background ]

If you want to preserve the background, you can easily create an offscreen canvas and do the text-composite-drawImage on that temporary canvas. Then draw the temporary canvas to your visible canvas with drawImage. That way you have your clipped text plus keep the existing background.

A Demo: http://jsfiddle.net/m1erickson/n7x8y/

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top