Как изменить непрозрачность (альфа, прозрачность) элемента в элементе canvas после его отрисовки? - PullRequest
180 голосов
/ 02 марта 2010

Используя элемент HTML5 <canvas>, я хотел бы загрузить файл изображения (PNG, JPEG и т. Д.), Полностью нарисовать его на холсте, а затем добавить его. Я выяснил, как загрузить изобразить и нарисовать его на холсте, но я не знаю, как изменить его непрозрачность, как только он был нарисован.

Вот код, который у меня есть:

var canvas = document.getElementById('myCanvas');

if (canvas.getContext)
{
    var c           = canvas.getContext('2d');
    c.globalAlpha   = 0;

    var img     = new Image();
    img.onload  = function() {
        c.drawImage(img, 0, 0);
    }
    img.src     = 'image.jpg';
}

Кто-нибудь, пожалуйста, укажет мне правильное направление, например, свойство для установки или вызываемая функция, которая изменит непрозрачность?

Ответы [ 8 ]

284 голосов
/ 20 апреля 2010

Я также ищу ответ на этот вопрос (чтобы уточнить, я хочу иметь возможность рисовать изображение с определенной непрозрачностью, например, как вы можете рисовать фигуры с непрозрачностью), если вы рисуете с примитивными фигурами, которые вы можете установить заливка и обводка цвета альфа, чтобы определить прозрачность. Насколько я пришел к выводу, это никак не влияет на рисование изображений.

//works with shapes but not with images
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";

Я пришел к выводу, что установка globalCompositeOperation работает с изображениями.

//works with images
ctx.globalCompositeOperation = "lighter";

Интересно, есть ли какой-то третий способ настройки цвета, чтобы мы могли тонировать изображения и делать их прозрачными.

EDIT:

После дальнейшего копания я пришел к выводу, что вы можете установить прозрачность изображения, установив параметр globalAlpha ДО того, как вы нарисуете изображение:

//works with images
ctx.globalAlpha = 0.5

Если вы хотите добиться эффекта затухания с течением времени, вам нужен какой-то цикл, который изменяет альфа-значение, это довольно просто, одним из способов добиться этого является функция setTimeout, посмотрите, чтобы создать цикл из который вы изменяете альфа со временем.

108 голосов
/ 04 ноября 2011

Несколько простых примеров кода для использования globalAlpha:

ctx.save();
ctx.globalAlpha = 0.4;
ctx.drawImage(img, x, y);
ctx.restore();

Если вам нужно загрузить img:

var img = new Image();
img.onload = function() {
    ctx.save();
    ctx.globalAlpha = 0.4;
    ctx.drawImage(img, x, y);
    ctx.restore()
};
img.src = "http://...";

Примечания:

  • Установите последний 'src', чтобы гарантировать, что ваш обработчик onload вызывается на всех платформах, даже если изображение уже находится в кэше.

  • Оберните изменения в такие вещи, как globalAlpha между save и restore (на самом деле используйте их много), чтобы убедиться, что вы не забиваете настройки из другого места, особенно когда биты кода рисования будет вызываться из событий.

14 голосов
/ 22 июня 2011

Редактировать: Ответ, помеченный как «правильный», является неправильным.

Это легко сделать. Попробуйте этот код, поменяйте местами «ie.jpg» с любым изображением, которое у вас есть под рукой:

<!DOCTYPE HTML>
<html>
    <head>
        <script>
            var canvas;
            var context;
            var ga = 0.0;
            var timerId = 0;

            function init()
            {
                canvas = document.getElementById("myCanvas");
                context = canvas.getContext("2d");
                timerId = setInterval("fadeIn()", 100);
            }

            function fadeIn()
            {
                context.clearRect(0,0, canvas.width,canvas.height);
                context.globalAlpha = ga;
                var ie = new Image();
                ie.onload = function()
                {
                    context.drawImage(ie, 0, 0, 100, 100);
                };
                ie.src = "ie.jpg";

                ga = ga + 0.1;
                if (ga > 1.0)
                {
                    goingUp = false;
                    clearInterval(timerId);
                }
            }
        </script>
    </head>
    <body onload="init()">
        <canvas height="200" width="300" id="myCanvas"></canvas>
    </body>
</html>

Ключ - это свойство globalAlpha.

Протестировано с IE 9, FF 5, Safari 5 и Chrome 12 на Win7.

11 голосов
/ 21 февраля 2012

Пост пока старый, я пойду с моим предложением. Предложение основано на манипулировании пикселями в контексте Canvas 2D. От MDN:

Вы можете напрямую манипулировать данными пикселей в холстах на уровне байтов

Для работы с пикселями мы будем использовать две функции: getImageData и putImageData

Использование функции getImageData:

var myImageData = context.getImageData (слева, сверху, ширина, высота);

и синтаксис putImageData:

context.putImageData (myImageData, dx, dy); // dx, dy - x и y смещение на вашем холсте

Где context - это ваш холст 2d context

Таким образом, чтобы получить значения красного, зеленого, синего и альфа, мы сделаем следующее:

var r = imageData.data[((x*(imageData.width*4)) + (y*4))];
var g = imageData.data[((x*(imageData.width*4)) + (y*4)) + 1];
var b = imageData.data[((x*(imageData.width*4)) + (y*4)) + 2];
var a = imageData.data[((x*(imageData.width*4)) + (y*4)) + 3];

Где x - смещение по x, y - смещение по y на холсте

Итак, у нас есть код, делающий изображение полупрозрачным

var canvas = document.getElementById('myCanvas');
var c = canvas.getContext('2d');
var img = new Image();
img.onload  = function() {
   c.drawImage(img, 0, 0);
   var ImageData = c.getImageData(0,0,img.width,img.height);
   for(var i=0;i<img.height;i++)
      for(var j=0;j<img.width;j++)
         ImageData.data[((i*(img.width*4)) + (j*4) + 3)] = 127;//opacity = 0.5 [0-255]
   c.putImageData(ImageData,0,0);//put image data back
}
img.src = 'image.jpg';

Вы можете создавать свои собственные "шейдеры" - см. Полную статью MDN здесь

7 голосов
/ 08 октября 2012

Можно. Прозрачный холст можно быстро убрать, используя глобальную составную операцию destination-out . Он не идеален на 100%, иногда оставляет некоторые следы, но его можно настроить, в зависимости от того, что необходимо (например, используйте «source-over» и залейте его белым цветом с альфа-каналом в 0,13, затем потушите, чтобы подготовить холст).

// Fill canvas using 'destination-out' and alpha at 0.05
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = "rgba(255, 255, 255, 0.05)";
ctx.beginPath();
ctx.fillRect(0, 0, width, height);
ctx.fill();
// Set the default mode.
ctx.globalCompositeOperation = 'source-over';
1 голос
/ 14 апреля 2019

Я думаю, что это лучше всего отвечает на вопрос, на самом деле оно меняет альфа-значение того, что уже нарисовано. Может быть, это не было частью API, когда был задан этот вопрос.

заданный 2d контекст c.

function reduceAlpha(x, y, w, h, dA) {
    var screenData = c.getImageData(x, y, w, h);
    for(let i = 3; i < screenData.data.length; i+=4){
    screenData.data[i] -= dA; //delta-Alpha
    }
    c.putImageData(screenData, x, y );
}
0 голосов
/ 09 ноября 2014

Если вы используете библиотеку jCanvas , вы можете использовать свойство opacity при рисовании. Если вам нужен эффект затухания, просто перерисовайте его с другими значениями.

0 голосов
/ 16 марта 2010

Вы не можете. Это графика в непосредственном режиме. Но вы можете имитировать его, рисуя поверх него прямоугольник в цвете фона с непрозрачностью.

Если изображение над чем-то иным, чем постоянный цвет, то оно становится немного сложнее. Вы должны быть в состоянии использовать методы манипуляции с пикселями в этом случае. Просто сохраните область перед тем, как нарисовать изображение, а затем смешайте его снова с непрозрачностью.

...