Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML Canvas - Create a Highlighter Effect

I am creating a two layer canvas. The bottom layer is a screenshot. The top layer is the drawing surface. I figured out a basic pen. I want to create a highlighter effect - meaning a larger line with a set opacity .5 or less. The problem I am having is that when I draw over the same area more than once the colors paint on top of each other. Eventually, the highlight will turn solid and block out the lower layer. I want to highlight evenly with the original color and be able to draw over existing highlights without the colors adding up.

I have been messing around with globalCompositeOperation but cannot get the desired results with the settings I have tried. Below i am trying color and using a globalAlpha setting. I have also tried using rgba colors. I also tried just using one layer, but I wanted to be able to clear doodles and erase easily so I went with two. Some of my source code is in the picture, but I'm not sure how helpful code is for my question. I can provide more if needed. Thanks.

enter image description here

EDIT: After using multiply as the globalCompositionOperation the color #FF0 aka yellow works great, among other colors. Some colors still have the original build-to-black effect, like the blue I use in the bottom picture. As a side note, these pictures are not to share my code, they are to show the highlighter effect. As a side note, this an Electron app so it is using Chromium ~ 61 at this time.

enter image description here

like image 585
benjaminadk Avatar asked Apr 27 '26 13:04

benjaminadk


1 Answers

The normal way to create a highlighter effect is to use the blending mode "multiply".

This will be like on real paper (subtractive light, not technically but in appearance) so drawing on a dark background will produce an almost invisible highlighter effect.

Note that not all browsers support blending modes (this includes <= IE11).

const ctx = c.getContext("2d");
ctx.globalCompositeOperation = "multiply";
ctx.font = "40px sans-serif";
ctx.fillText("HIGHLIGHT ME", 5, 84);        // replace with bg image
ctx.fillStyle = "#ff0";
c.onmousemove = e => ctx.fillRect(e.clientX-10, e.clientY-10, 20,20);
html, body {margin:0}
#c {border:1px solid}
<canvas id=c></canvas>

On dark background:

const ctx = c.getContext("2d");
ctx.fillStyle = "#333";
ctx.fillRect(0,0,c.width,c.height);
ctx.font = "40px sans-serif";
ctx.fillStyle = "#fff";
ctx.fillText("HIGHLIGHT ME", 5, 84);        // replace with bg image
ctx.fillStyle = "#ff0";
ctx.globalCompositeOperation = "multiply";
c.onmousemove = e => ctx.fillRect(e.clientX-10, e.clientY-10, 20,20);
html, body {margin:0}
#c {border:1px solid}
<canvas id=c></canvas>