У меня есть прямоугольный холст с нарисованным на нем изображением. Когда пользователь перемещает курсор по холсту, я хотел бы сделать холст полупрозрачным за исключением небольшого прямоугольника вокруг курсора, который я хотел бы сохранить в полной непрозрачности базового содержимого изображения.

Итак, вкратце мой вопрос заключается в том, как «заглушить» холст, за исключением небольшого прямоугольника.

Моя первая мысль заключалась в том, чтобы создать полупрозрачное наложение на весь холст, а затем просто закрасить прямоугольную область, которая снова должна быть полностью непрозрачной, но это заставит фон исчезнуть, а я хочу сохранить его с непрозрачностью 0,2:

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

elem.width = 400;
elem.height = 300;

ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, elem.width, elem.height);

elem.addEventListener('mousemove', function(e) {
  ctx.globalAlpha = 0.2;
  ctx.fillStyle = '#ffffff';
  ctx.fillRect(0, 0, elem.width, elem.height);
  var x = e.clientX;
  var y = e.clientY;
  var d = 30;
  ctx.fillStyle = '#ff0000';
  ctx.fillRect(x-d, y-d, d*2, d*2);
})
<canvas/>

Кто-нибудь знает наиболее эффективный способ отключить фон до 0,2 непрозрачности, сохранив прямоугольник вокруг курсора при полной непрозрачности? Любые указатели были бы очень полезны!

0
duhaime 14 Сен 2020 в 02:22

1 ответ

Лучший ответ

Вот два метода холста:

var elemA = document.querySelector('#a');
var elemB = document.querySelector('#b');
var ctx = elemA.getContext('2d');
var bctx = elemB.getContext('2d');

elemA.width = elemB.width = 400;
elemA.height = elemB.height = 300;

ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, elemA.width, elemA.height);
elemB.addEventListener('mousemove', function(e) {
  bctx.clearRect(0, 0, elemB.width, elemB.height);
  
  var x = e.clientX;
  var y = e.clientY;
  var x0 = x-10;
  var x1 = x+10;
  var y0 = y-10;
  var y1 = y+10;

  // draw boxes; origin is top left
  bctx.globalAlpha = 0.8;
  bctx.fillStyle = '#ffffff';
  bctx.fillRect(0, 0, elemA.width, y0); // top
  bctx.fillRect(0, y0, x0, elemB.height+20); // left
  bctx.fillRect(x0, y1, elemB.width+20, elemB.height); // bottom
  bctx.fillRect(x1, y0, elemA.width, y1-y0); // right
})
* {
  margin: 0;
}

#c {
  position: relative;
}

#a, #b {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

#b {
  z-index: 1;
  opacity: 0.5;
}
<div id='c'>
  <canvas id='a'></canvas>
  <canvas id='b'></canvas>
</div>
0
duhaime 14 Сен 2020 в 01:16