Come modificare l'opacità (alfa, trasparenza) di un elemento in un elemento tela dopo che è stato disegnato?


196

Usando l' <canvas>elemento HTML5 , vorrei caricare un file di immagine (PNG, JPEG, ecc.), Disegnarlo sulla tela in modo completamente trasparente e quindi sfumarlo. Ho capito come caricare l'immagine e disegnarla sul tela, ma non so come modificarne l'opacità una volta disegnata.

Ecco il codice che ho finora:

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

Qualcuno può indicarmi la giusta direzione come una proprietà da impostare o una funzione da chiamare che cambierà l'opacità?

Risposte:


307

Sto anche cercando una risposta a questa domanda (per chiarire, voglio essere in grado di disegnare un'immagine con opacità definita dall'utente come come puoi disegnare forme con opacità) se disegni con forme primitive puoi impostare riempimento e tratto colore con alfa per definire la trasparenza. Per quanto ho concluso in questo momento, questo non sembra influenzare il disegno dell'immagine.

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

Ho concluso che l'impostazione dei globalCompositeOperationlavori con le immagini.

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

Mi chiedo se esiste un terzo tipo di impostazione del colore per poter tingere le immagini e renderle facilmente trasparenti.

MODIFICARE:

Dopo ulteriori approfondimenti, ho concluso che è possibile impostare la trasparenza di un'immagine impostando il globalAlphaparametro PRIMA di disegnare l'immagine:

//works with images
ctx.globalAlpha = 0.5

Se vuoi ottenere un effetto di dissolvenza nel tempo, hai bisogno di un qualche tipo di loop che cambi il valore alfa, questo è abbastanza facile, un modo per raggiungerlo è la setTimeoutfunzione, cerca quello per creare un loop da cui modifichi l'alfa sopra tempo.


7
globalAlpha funziona perfettamente. Fa parte dello standard: whatwg.org/specs/web-apps/current-work/multipage/…
Aleris

42
Per essere precisi, non è l' canvaselemento che ha la globalAlphaproprietà, ma il contesto che si ottiene dalla tela.
Steve Blackwell,

8
Il commento di Ian di seguito su ctx.save () e ctx.restore () impedisce a globalAlpha di influenzare il resto dell'area di disegno.
Arosboro,

1
Mi sembra piuttosto che controllare l'opacità di ciò che è disegnato sulla tela, sarebbe più semplice e servirebbe ancora allo scopo di controllare l'opacità dell'intera tela stessa dopo che l'immagine è stata disegnata (solo una volta). Usa i soliti metodi CSS / style per fare questo (canvaselement.style.opacity = '0.3'; ecc.) Successivamente con CSS3 puoi persino rinunciare del tutto al ciclo e lasciare che il browser gestisca invece lo sbiadimento (qualcosa come- transizione: NNNms opacità facilità-in-out), o addirittura "animare" la dissolvenza.
Chuck Kollars,

1
Sfortunatamente, canvas2d.fillStyle = "rgba(255, 255, 255, 0.5)";non funziona. Il valore deve essere in esadecimale.
WebWanderer,

113

Un codice di esempio più semplice per l'utilizzo globalAlpha:

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

Se devi imgessere caricato:

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

Appunti:

  • Imposta l' 'src'ultimo, per garantire che il onloadgestore sia chiamato su tutte le piattaforme, anche se l'immagine è già nella cache.

  • Avvolgi le modifiche a cose come globalAlphatra a savee restore(in effetti usale molte), per assicurarti di non ostruire le impostazioni da altrove, in particolare quando i bit di codice di disegno verranno chiamati dagli eventi.


globalAlpha sfocerà tutte le immagini o i disegni su una tela, non è quello che vuoi.
Grumpy,

6
@Grumpy - no, globalAlphanon offusca nulla. Imposta l'alfa per tutti i disegni successivi (non cambia nulla di già disegnato), motivo per cui nel codice di esempio lo avvolgo savee restore, per limitare ciò a cui si applica.
Ian

non sei sicuro che ctx.restore () ripristinerà globalAlpha potresti anche doverlo fare alla fine (almeno dovevo farlo nelle versioni precedenti di Chrome) ctx.globalAlpha = 1;
Sean,

1
@Sean - Se non sei sicuro, dovresti controllare. Deve essere stato un Chrome molto vecchio, ora funziona su tutte le piattaforme: jsfiddle.net/y0z9h9m7
Ian

14

Modificare: La risposta contrassegnata come "corretta" non è corretta.

È facile da fare. Prova questo codice, scambiando "ie.jpg" con qualsiasi immagine tu abbia a portata di mano:

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

La chiave è la proprietà globalAlpha.

Testato con IE 9, FF 5, Safari 5 e Chrome 12 su Win7.


13

Il post è vecchio finora andrò con il mio suggerimento. Il suggerimento si basa sulla manipolazione di pixel nel contesto 2D della tela. Da MDN:

È possibile manipolare direttamente i dati pixel nei canvas a livello di byte

Per manipolare i pixel utilizzeremo due funzioni qui: getImageData e putImageData

Utilizzo della funzione getImageData:

var myImageData = context.getImageData (sinistra, alto, larghezza, altezza);

e sintassi putImageData:

context.putImageData (myImageData, dx, dy); // offset dx, dy - xey sulla tela

Dove contesto è il tuo contesto di tela 2d

Quindi per ottenere i valori rosso verde blu e alfa, faremo quanto segue:

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

Dove x è offset x, y è offset y sulla tela

Quindi abbiamo un codice che rende l'immagine semi-trasparente

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

Puoi creare i tuoi "shader" - vedi l'articolo completo di MDN qui


7

Puoi. La tela trasparente può essere rapidamente sbiadita utilizzando l'operazione composita globale di destinazione . Non è perfetto al 100%, a volte lascia alcune tracce ma potrebbe essere modificato, a seconda di ciò che è necessario (ad esempio, usa 'source-over' e riempilo di colore bianco con alfa a 0,13, quindi sbiadisc per preparare la tela).

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

Penso che questo risponda meglio alla domanda, in realtà cambia il valore alfa di qualcosa che è già stato disegnato. Forse questo non faceva parte dell'api quando è stata posta questa domanda.

dato contesto 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 );
}

In che modo questa risposta è diversa dalla risposta di Soul_man data con maggiori dettagli 7 anni prima?
BReddy

-2

Se si utilizza la libreria jCanvas è possibile utilizzare la proprietà di opacità durante il disegno. Se hai bisogno di un effetto di dissolvenza, ridisegna semplicemente con valori diversi.


-11

Non puoi. È grafica in modalità immediata. Ma puoi simularlo disegnando un rettangolo su di esso nel colore di sfondo con un'opacità.

Se l'immagine si trova su qualcosa di diverso da un colore costante, allora diventa un po 'più complicato. In questo caso dovresti essere in grado di utilizzare i metodi di manipolazione dei pixel. Basta salvare l'area prima di disegnare l'immagine, quindi fonderla nuovamente con un'opacità in seguito.


5
Questa non è la risposta giusta, vedi sotto
Ryan Badour,

Hai ragione, anche se non puoi cambiare l'opacità di uno degli elementi che hai disegnato nella tela, puoi cambiare l'opacità dell'intera tela. In alcuni casi ciò potrebbe essere sufficiente.
MPG

2
MPG - anche il tuo commento (11 maggio) è sbagliato. Puoi cambiare l'opacità della tela, ma non è quello che voleva l'OP, né ciò che viene suggerito nelle risposte sopra.
Ian,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.