简体   繁体   中英

HTML5 Canvas: Filling transparent image with color and drawing on top

I am trying to draw an transparent image over another one filled with color. I have a code structure like this, there is a base image, another transparent image_1 is multiplied over it and then image_2 should be color filled and drawn over. Could not get it to work using fillStyle & fillRect .

image_1.src = 'image_1_url';
image_1.onload = () => {
  context.globalCompositeOperation = 'multiply';
  context.drawImage(image_1, 0, 0, canvas.width, canvas.height);

  image_2.src = 'image_2_url';
  image_2.onload = () => {
    //fill image_2 with a color and draw it on top of canvas
  }
}

In which order should I use color fill and globalCompositeOperations?

在此处输入图像描述

Simple solution: Use a second canvas.

 (async () => { const [ cat, star, hex ] = await Promise.all( loadImages( [ "kNpEG.jpg", "PPfrd.png", "Vcc8C.png" ], 'https://i.stack.imgur.com/' ) ); // the visible canvas const canvas = document.getElementById( 'canvas' ); const ctx = canvas.getContext( '2d' ); // create an offcreen copy const canvas2 = canvas.cloneNode(); const ctx2 = canvas2.getContext( '2d' ); // on the visible canvas // we can apply simply the first step source-over operation ctx.drawImage( cat, 0, 0 ); ctx.drawImage( star, 0, 0 ); // on the offsreen canvas we apply the color blending ctx2.fillStyle = "red"; ctx2.fillRect( 0, 0, 200, 200 ); ctx2.globalCompositeOperation = "destination-in"; ctx2.drawImage( hex, 0, 0 ); // now we can draw it on the visible canvas, still as source-over ctx.drawImage( canvas2, 0, 0 ); })().catch( console.error ); function loadImages( filenames, path = "" ) { return filenames.map( filename => new Promise( (res, rej ) => { const img = new Image(); img.onload = (evt) => res( img ); img.onerror = rej; img.src = path + filename; } ) ); }
 <canvas id="canvas" width="200" height="200"></canvas>

Not always possible: draw from front to back.

 (async () => { const [ cat, star, hex ] = await Promise.all( loadImages( [ "kNpEG.jpg", "PPfrd.png", "Vcc8C.png" ], 'https://i.stack.imgur.com/' ) ); // the only canvas const canvas = document.getElementById( 'canvas' ); const ctx = canvas.getContext( '2d' ); // we start with the color blending ctx.fillStyle = "red"; ctx.fillRect( 0, 0, 200, 200 ); ctx.globalCompositeOperation = "destination-in"; ctx.drawImage( hex, 0, 0 ); // and now we draw from behind ctx.globalCompositeOperation = "destination-over"; // so we need to inverse these two ctx.drawImage( star, 0, 0 ); ctx.drawImage( cat, 0, 0 ); })().catch( console.error ); function loadImages( filenames, path = "" ) { return filenames.map( filename => new Promise( (res, rej ) => { const img = new Image(); img.onload = (evt) => res( img ); img.onerror = rej; img.src = path + filename; } ) ); }
 <canvas id="canvas" width="200" height="200"></canvas>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM