admin管理员组

文章数量:1323029

I want to achive the following:

  1. Draw a bg-image to the canvas (once or if needed repeatedly)
  2. The image should not be visible at the beginning
  3. While i "paint" shapes to the canvas the bg-image should get visible where the shapes were drawn

The parts of the image that will be revealed shall be "painted" (like with a brush) so i want to use strokes.

What i tried: - Do not clear the canvas - Paint rects to the canvas with globalCompositeOperation = 'destination-in' This works, the rectangles reveal the image but i need strokes

If i use strokes they are ignored with 'destination-in' while i see them with normal globalCompositeOperation.

Is this intended that the strokes are ignored? Is there a workaround like somehow converting the stroke/shape to a bitmap? Or do i have have to use two canvas elements?

In OpenGL i would first draw the image with its rgb values and with a = 0 and then only "paint" the alpha in.

I want to achive the following:

  1. Draw a bg-image to the canvas (once or if needed repeatedly)
  2. The image should not be visible at the beginning
  3. While i "paint" shapes to the canvas the bg-image should get visible where the shapes were drawn

The parts of the image that will be revealed shall be "painted" (like with a brush) so i want to use strokes.

What i tried: - Do not clear the canvas - Paint rects to the canvas with globalCompositeOperation = 'destination-in' This works, the rectangles reveal the image but i need strokes

If i use strokes they are ignored with 'destination-in' while i see them with normal globalCompositeOperation.

Is this intended that the strokes are ignored? Is there a workaround like somehow converting the stroke/shape to a bitmap? Or do i have have to use two canvas elements?

In OpenGL i would first draw the image with its rgb values and with a = 0 and then only "paint" the alpha in.

Share Improve this question asked Dec 10, 2014 at 17:55 AlexAlex 5516 silver badges19 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

You can solve it by these steps:

  • Set the image as a pattern
  • Set the pattern as fillStyle or strokeStyle

When you now fill/stroke your shapes the image will be revealed. Just make sure the initial image fits the area you want to reveal.

Example showing the principle, you should be able to adopt this to your needs:

var ctx = canvas.getContext("2d"),
    img = new Image,
    radius = 40;

img.onload = setup;
img.src = "http://i.imgur./bnAEEXq.jpg";

function setup() {
  
  // set image as pattern for fillStyle
  ctx.fillStyle = ctx.createPattern(this, "no-repeat");
  
  // for demo only, reveals image while mousing over canvas
  canvas.onmousemove = function(e) {
    var r = this.getBoundingClientRect(),
        x = e.clientX - r.left,
        y = e.clientY - r.top;
    
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.arc(x, y, radius, 0, 2*Math.PI);
    ctx.fill();
  };
}
<canvas id=canvas width=900 height=600></canvas>

Hope this helps!

Alternative solution:

  1. Put the image as a normal image on your website
  2. add a canvas and use CSS positioning to place it right above the image
  3. Fill the canvas with the color you use as the page background
  4. have your paint tools erase the canvas when you draw. By the way, you can set context.globalCompositionOperation = 'destination-out' to turn all drawing operations into an eraser.

Here is an example. As you can see, the alpha properties of your tools are respected.

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

//prepare canvas
ctx.fillStyle = '#ffffff'
ctx.fillRect(0, 0, 120, 120);

//prepare a 30% opacity eraser
ctx.globalCompositeOperation = 'destination-out';
ctx.lineWidth = 5;
ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)';

// make random strokes around cursor while mouse moves
canvas.onmousemove = function(e) {
   var rect = this.getBoundingClientRect();
   var x = e.clientX - rect.left;
   var y = e.clientY - rect.top;

   ctx.beginPath();
   ctx.moveTo(x + Math.random() * 33 - 16, y + Math.random() * 33 - 16);
   ctx.lineTo(x + Math.random() * 33 - 16, y + Math.random() * 33 - 16);
   ctx.stroke();

}
<span>Move your mouse:</span>
<div>
<img src='https://upload.wikimedia/wikipedia/mons/thumb/6/61/HTML5_logo_and_wordmark.svg/120px-HTML5_logo_and_wordmark.svg.png' style='position:absolute'>
<canvas id='canvas' width=120 height=120 style='position:absolute'></canvas>
</div>

本文标签: javascriptReveal image on canvas with drawstrokespaintStack Overflow