Himanshu Dhiman
Himanshu Dhiman

Reputation: 99

HTML5 Canvas Text Stroke gives unwanted overlapping in chrome but works fine in Safari

Basic text stroke code.

<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var x = 80;
  var y = 110;

  context.font = '100pt arial';
  context.lineWidth = 37;
  context.strokeStyle = "rgba(255,0,0,0.5)";
  context.strokeText('Ho', x, y);
</script>

Output in Chrome and Firefox is :

enter image description here

The overlapping area between 'H' and 'o' is darker than non overlapping area. I want to have same opacity/alpha for the stroke text.

I tried it in Safari on Mac system and there was not such a problem. In safari i got uniform opacity/alpha for both overlapping and non-overlapping region.

I need to understand why this is happening in chrome and what should i do to have uniform opacity/alpha.

Upvotes: 3

Views: 587

Answers (2)

Mobil Home
Mobil Home

Reputation: 3

You can use plain CSS gradient with alpha values, and the alpha will not add up:

background: -webkit-linear-gradient(top, rgba(10, 14, 15, 0.3), rgba(10, 14, 15, 0.3));
    -webkit-background-clip: text;
    -webkit-text-stroke: 1vw transparent;

Upvotes: 0

Blindman67
Blindman67

Reputation: 54026

The behaviour is not what is to be expected, the strokeText call one would expect to be part of a single path, and would consider it a bug in both Chrome and Firefox.

Nevertheless you need a solution. The only one I can think of is to create a second canvas. Render the text without opacity on that canvas then render that canvas onto the original canvas using ctx.globalAlpha = 0.5

Example.

var canvas = document.createElement("canvas");
canvas.width = 500;
canvas.height = 500;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var x = 40;
var y = 110;
ctx.font = '100pt arial';
ctx.lineWidth = 20;
ctx.fillRect(10,y,500,10);
ctx.strokeStyle = "rgba(255,0,0,0.5)";
ctx.strokeText('Bad', x, y);


var workCan = document.createElement("canvas");
workCan.width = canvas.width;
workCan.height = canvas.height;
var ctx1 = workCan.getContext("2d");
ctx1.font = '100pt arial';
ctx1.lineWidth = 20;
ctx1.strokeStyle = "rgba(255,0,0,1)";
x = 40;
y = 260;
ctx1.strokeText('Good', x, y);
ctx.fillRect(10,y,500,10);
ctx.globalAlpha = 0.5;
ctx.drawImage(workCan,0,0);

          

Upvotes: 3

Related Questions