Bir tuval öğesindeki çizildikten sonra bir öğenin opaklığını (alfa, saydamlık) nasıl değiştirebilirim?


196

HTML5 <canvas>öğesini kullanarak, bir görüntü dosyası (PNG, JPEG, vb.) Yüklemek, tamamen şeffaf bir şekilde tuvale çizmek ve daha sonra solmak istiyorum. Görüntüyü nasıl yükleyeceğimi ve tuval, ama çizildikten sonra opaklığını nasıl değiştireceğimi bilmiyorum.

İşte şimdiye kadar sahip olduğum kod:

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';
}

Birisi beni opaklığı değiştirecek bir özellik veya çağrılacak bir işlev gibi doğru yöne yönlendirir mi?

Yanıtlar:


307

Ayrıca bu soruya bir cevap arıyorum, (açıklığa kavuşturmak için, opaklıkla şekilleri nasıl çizebileceğiniz gibi kullanıcı tanımlı opaklığa sahip bir resim çizmek istiyorum), ilkel şekillerle çizerseniz dolgu ve kontur ayarlayabilirsiniz saydamlığı tanımlamak için alfa ile renk. Şu anda sonuçlandırdığım kadarıyla, bu resim çizimini etkilemiyor gibi görünüyor.

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

globalCompositeOperationÇalışmaları görüntülerle ayarlamanın sonucuna vardım .

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

Renkleri ayarlamanın ve kolayca şeffaf hale getirebilmemiz için bir tür üçüncü renk ayarı olup olmadığını merak ediyorum.

DÜZENLE:

Daha fazla kazma işleminden sonra globalAlpha, görüntüyü çizmeden ÖNCE parametresini ayarlayarak görüntünün saydamlığını ayarlayabileceğinize karar verdim :

//works with images
ctx.globalAlpha = 0.5

Zamanla solma efekti elde etmek istiyorsanız, alfa değerini değiştiren bir tür döngüye ihtiyacınız vardır, bu oldukça kolaydır, bunu başarmanın bir yolu setTimeoutişlevdir, alfa üzerinde değiştirdiğiniz bir döngü oluşturmak için yukarı bak zaman.


7
globalAlpha mükemmel çalışır. Standardın bir parçasıdır: whatwg.org/specs/web-apps/current-work/multipage/…
Aleris

42
Kesin olmak gerekirse, bu özelliğe canvassahip öğe değil globalAlpha, tuvalden aldığınız bağlam.
Steve Blackwell

8
Ian'ın aşağıdaki ctx.save () ve ctx.restore () ile ilgili yorumu, globalAlpha'nın tuvalin geri kalanını etkilemesini engelliyor.
Arosboro

1
Tuval üzerine çizilenlerin opaklığını kontrol etmek yerine bana benziyor, daha basit olurdu ve yine de görüntü çizildikten sonra tüm tuvalin opaklığını kontrol etme amacına hizmet ediyor (sadece bir kez). Bunu yapmak için her zamanki CSS / stil yöntemlerini kullanın (canvaselement.style.opacity = '0.3'; vb.) Daha sonra CSS3 ile döngüden tamamen vazgeçebilir ve tarayıcının solma yerine işlemesine izin verebilirsiniz (geçiş gibi: NNNms) opaklık kolaylık-in-out), hatta solma "animasyon".
Chuck Kollars

1
Ne yazık ki, canvas2d.fillStyle = "rgba(255, 255, 255, 0.5)";çalışmıyor. Değer onaltılık olmalıdır.
WebWanderer

113

Kullanmak için bazı basit örnek kodlar globalAlpha:

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

Yüklemeniz gerekiyorsa img:

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

Notlar:

  • Görüntü önbellekte olsa bile 'src', onloadişleyicinizin tüm platformlarda çağrıldığından emin olmak için sonuncuyu ayarlayın .

  • Özellikle çizim kodu bitleri olaylardan çağırılacaksa, ayarları başka bir yerden hızlandırmamaya dikkat etmek için globalAlphaa saveve restore(aslında lotları kullanın) gibi şeylere yapılan değişiklikleri sarın .


globalAlpha bir tuval üzerindeki tüm görüntüleri veya çizimleri bulanıklaştırır, istediğiniz şey bu değildir.
Huysuz

6
@Grumpy - hayır, hiçbir globalAlphaşey bulanık değil. Sonraki tüm çizim için alfa ayarlayacaktır (önceden çizilen hiçbir şeyi değiştirmez), bu yüzden örnek kodda onu sarıyorum saveve restorene için sınırlandığını.
Ian

ctx.restore () 'in globalAlpha' yı geri yükleyeceğinden emin değilsiniz, bunu sonunda yapmanız gerekebilir (en azından Chrome'un önceki sürümlerinde yapmak zorundaydım) ctx.globalAlpha = 1;
Sean

1
@Sean - Emin değilseniz, kontrol etmelisiniz. Çok eski bir Chrome olmalıydı, şu anda tüm platformlarda çalışıyor: jsfiddle.net/y0z9h9m7
Ian

14

Düzenle: "Doğru" olarak işaretlenen cevap doğru değil.

Yapması kolay. "İe.jpg" yi kullandığınız resim ile değiştirerek bu kodu deneyin:

<!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>

Anahtar globalAlpha özelliğidir.

Win7'de IE 9, FF 5, Safari 5 ve Chrome 12 ile test edildi.


13

Mesaj şu ana kadar eski benim önerim ile gideceğim. Öneri tuval 2d bağlamında piksel manipülasyonuna dayanmaktadır. MDN'den:

Tuvallerdeki piksel verilerini bayt düzeyinde doğrudan işleyebilirsiniz

Pikselleri değiştirmek için burada iki işlevi kullanacağız - getImageData ve putImageData

getImageData işlevi kullanımı:

var myImageData = context.getImageData (sol, üst, genişlik, yükseklik);

ve putImageData sözdizimi:

context.putImageData (myImageData, dx, dy); // tuvalinizde dx, dy - x ve y ofseti

Bağlam 2d bağlamınız nerede

Kırmızı yeşil mavi ve alfa değerlerini almak için aşağıdakileri yapacağız:

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];

Burada x x ofset, y y tuval üzerinde ofset

Bu yüzden görüntüyü yarı şeffaf yapan kodumuz var

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';

Tam MDN makalesine bakın - Sen "gölgelendiricileri" kendi yapabilir burada


7

Yapabilirsin. Şeffaf tuval hızla kullanılarak soluk alınabilir hedef aşımı küresel kompozit operasyonu. % 100 mükemmel değil, bazen bazı izler bırakıyor, ancak neye ihtiyaç duyulduğuna bağlı olarak ayarlanabiliyor (yani 'source-over' kullanın ve 0.13'te alfa ile beyaz renkle doldurun, sonra tuvali hazırlamak için solmaya başlayın).

// 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';

3

Bence bu en iyi soruyu cevaplıyor, aslında çizilen bir şeyin alfa değerini değiştiriyor. Belki de bu soru sorulduğunda API'nin bir parçası değildi.

2d bağlamı verilmiştir 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 );
}

Bu cevap, 7 yıl önce daha ayrıntılı olarak verilen Soul_man'ın cevabından nasıl farklı?
BReddy

-2

Eğer kullanırsanız jCanvas kütüphanesini kullanabilirsiniz donukluk çizerken özelliği. Bunun üzerine solma efektine ihtiyacınız varsa, farklı değerlerle yeniden çizin.


-11

Yapamazsın. Anında mod grafikleri. Ancak, bir opaklıkla arka plan renginde bir dikdörtgen çizerek benzetebilirsiniz.

Görüntü sabit bir renkten başka bir şeyin üzerindeyse, biraz daha zorlaşır. Bu durumda piksel işleme yöntemlerini kullanabilmeniz gerekir. Görüntüyü çizmeden önce alanı kaydedin ve daha sonra bir opaklıkla tekrar üstüne karıştırın.


5
Bu doğru cevap değil aşağıya bakınız
Ryan Badour

Haklısınız, ancak tuvale çizdiğiniz öğelerden birinin opaklığını değiştiremeseniz de, tüm tuvalin opaklığını değiştirebilirsiniz. Bazı durumlarda bu yeterli olabilir.
MPG

2
MPG - yorumunuz (11 Mayıs) da yanlış. Tuvalin opaklığını değiştirebilirsiniz, ancak OP'nin istediği bu değildir ya da yukarıdaki cevaplarda önerilen şey değildir.
Ian
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.