Можно ли сделать градиентно-прозрачное / маскирующее изображение слоя, используя холст? - PullRequest
13 голосов
/ 23 июля 2010

Я следил за уроками о прозрачности и градиентах на сайте Mozilla: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors, но я не смог понять это.

Я знаю, что могу добиться этих эффектов с помощью изображения PNG; однако в программе, над которой я работаю, градиент будет постоянно изменяться в зависимости от того, куда изображение перемещено.

Вот пример эффекта, который я ищу. http://home.insightbb.com/~epyonxl1/gradientex.jpg

Ответы [ 4 ]

16 голосов
/ 01 августа 2012

Возможно использовать context.globalCompositeOperation для создания маски

context.drawImage(img, 0, 0, img.width, img.height, 0,0, img.width, img.height);
context.globalCompositeOperation = "destination-out";
gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.fillStyle = gradient;
context.fillRect(0, 0, img.width, img.height);

Это не относится к манипуляциям с пикселями и должно быть быстрее

10 голосов
/ 28 февраля 2015

Чтобы правильно объединить два изображения с помощью маски прозрачности, сначала необходимо взять одно из двух изображений и поместить его на холст за пределами экрана и добавить желаемую маску прозрачности, используя context.globalCompositeOperation = destination-out per @ Tommykaответ

var offscreen = document.createElement('canvas'); // detached from DOM
var context = offscreen.getContext('2d');
context.drawImage(image1, 0, 0, image1.width, image1.height);

var gradient = context.createLinearGradient(0, 0, 0, img.height);
gradient.addColorStop(0, "rgba(255, 255, 255, 0.5)");
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
context.globalCompositeOperation = "destination-out";
context.fillStyle = gradient;
context.fillRect(0, 0, image1.width, image1.height);

Затем, чтобы фактически объединить два изображения, вам нужно нарисовать другое изображение на другом холсте, а затем просто нарисовать альфа-композицию закадрового холста поверх этого:

var onscreen = document.getElementById('mycanvas');
var context2 = onscreen.getContext('2d');
context2.drawImage(image2, 0, 0, image2.width, image2.height);
context2.drawImage(offscreen, 0, 0, onscreen.width, onscreen.height);

Демо на http://jsfiddle.net/alnitak/rfdjoh31/4/

7 голосов
/ 23 июля 2010

Я добавил здесь некоторый код http://code.google.com/p/canvasimagegradient/, который добавляет функцию drawImageGradient к CanvasRenderingContext2D. Вы можете нарисовать изображение с линейным или радиальным градиентом. Он не работает в IE, даже с excanvas, из-за отсутствия поддержки getImageData / putImageData.

Следующий код, например, нарисует изображение с радиальным градиентом (извлечение контекста и загрузка изображения не показаны):

var radGrad = ctx.createRadialGradient(
    img.width / 2, img.height / 2, 10, 
    img.width / 2, img.height / 2, img.width/2);
radGrad.addColorStop(0, "transparent");
radGrad.addColorStop(1, "#000");

ctx.drawImageGradient(img, 112.5, 130, radGrad);

Код работает следующим образом:

  1. Динамически создайте элемент canvas и нарисуйте на нем изображение.
  2. Получите imageData для этого нового холста.
  3. Получите imageData для местоположения на холсте, на котором вы хотите нарисовать изображение.
  4. Выполните итерацию по целевому imageData и обновите каждый пиксель, добавив вместе процент (полученный из значения прозрачности градиента) значений изображения и целевого пикселя.
  5. Наконец, поместите обновленные данные изображения обратно на холст назначения.

Очевидно, что производительность является проблемой, поскольку изображения становятся больше. Изображение на http://code.google.com/p/canvasimagegradient/ занимает около 6-10 мс. Для изображения 1024x768 требуется около 100-250 мс. Тем не менее, можно использовать, пока вы не оживляете.

0 голосов
/ 23 июля 2010

Если вам нужно сделать изображение прозрачным, установите ctx.globalAlpha на то, что вам нужно (1, без прозрачности, по умолчанию). Затем сбросьте его после того, как вы нарисуете свое изображение. Этот URL, вероятно, также поможет https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Compositing.

...