
Składanie kolorów w przeglądarkach
Jak już wiemy kolor RGBA może być opisany przez cztery liczby, które oznaczają odpowiednio:
- R – kolor czerwony, 0-255
- G – kolor zielony, 0-255
- B – kolor niebieski, 0-255
- A – przezroczystość, 0-255, oznaczaną jako α = 0.0 – 1.0, gdzie 0.0 oznacza zupełną przezroczystość, 1.0 zupełną nieprzezroczystość, a liczby pośrednie – kolory z pewną przezroczystością, gdzie α= A/255. Jeżeli A =200, to α = 200/255≈0.784
Mamy 2 zbiory.:
- D(destination), rgba(255,0, 0,0.5)
- S (source), rgba(0,0,255,0.6)

Jeżeli przezroczystość S wynosi
to tło ma przezroczystość
. Przenikająca część tła to
, a blokowana część tła to
.
Jeżeli przygotujemy tabelkę dla wszystkich możliwości to otrzymamy:
| S | D | ||
| tło | |||
| tło blokowane | |||
| tło przechodzące |
Rozważamy tutaj cztery możliwości w sensie teorii zbiorów:
| opis | przezroczystość | Bierzemy pod uwagę | Oznaczenie | |
| obszar poza S i obszar poza D, czyli tło T , nie zajęte ani przez S ani przez D | 0(Tło) | 0 | ||
| obszar S i obszar poza D, czyli obszar S nie nakładający się z D | 0, S | S | ||
| obszar poza S i obszar D, czyli obszar D nie nakładający się z S | 0, D | D | ||
| obszar S i obszar D, czyli obszar nakładania się S i D | 0, S, D | SD |
Reguły Portera – Duffa
Jeżeli przemnożymy liczby elementów w kolumnie 'Bierzemy pod uwagę’ to otrzymamy: 1 x 2 x 2 x 3 = 12 możliwości, które ujmujemy w tabelce:
| Reguła Portera-Duffa | FS | FD |
| clear (w JavaScript nie występuje) | 0 | 0 |
| copy | 0 | 1 |
| destination-atop | ||
| destination-in | 0 | |
| destination-out | 0 | |
| destination-over | 1 | |
| lighter | 1 | 0 |
| source-atop | ||
| source-in | 0 | |
| source-out | 0 | |
| source-over | 1 | |
| xor |
F- oznacza frakcję, w jakim kolor S lub D występuje w miejscu złożenia kolorów
Przezroczystość wynikowa
będzie wynosiła:
![]()
Kolor wynikowy
będzie wynosił:
![]()
gdzie
jest składnikiem koloru przemnożonym wstępnie przez
(jeżeli np. kolor czerwony = 255, a przezroczystość koloru wynosi
to za
podstawiamy 255*0.5 i podobnie dla
, gdzie podajemy kolor przemnożony wstępnie przez ![]()
Obliczenia
- D(destination), rgba(255,0, 0,0.5)
- S (source), rgba(0,0,255,0.6)
zastosowana była zasada source-over, a zatem
![]()
![]()
Z tabeli:
,
![]()

![]()
![]()
![]()
Kolor wynikowy to rgba (51, 0, 153, 0.8).

Do obliczenia koloru można użyć funkcji:
Listing
var kolor=function(rgba1, rgba2, rule){
var adst= rgba1.split(",");
var asrc=rgba2.split(",");
var src=parseFloat(asrc[3]);
var dst=parseFloat(adst[3]);
var fs=0;
var fd=0;
switch(rule){
case "copy":
fs=0;
fd=1.00;
break;
case "destination-atop":
fs=1.0-dst;
fd=src;
break;
case "destination-in":
fs=0;
fd=src;
break;
case "destination-out":
fs=0;
fd=1.0-src;
break;
case "destination-over":
fs=1.0-dst;
fd=1.0;
break;
case "lighter":
fs=1.00;
fd=0;
break;
case "source-atop":
fs=dst;
fd=1.0-src;
break;
case "source-in":
fs=dst;
fd=0;
break;
case "source-out":
fs=1.0-dst;
fd=0;
break;
case "source-over":
fs=1.0;
fd=1.0-src;
break;
case "xor":
fs=1.0-dst;
fd=1.0-src;
break;
}
var a=fs*src+fd*dst;
var r=fs*parseInt(asrc[0].substring(5))*src + fd*parseInt(adst[0].substring(5))*dst;
var g=fs*parseInt(asrc[1])*src + fd*parseInt(adst[1])*dst;
var b=fs*parseInt(asrc[2])*src + fd*parseInt(adst[2])*dst;
return "rgba("+Math.round(r)+","+Math.round(g)+","+Math.round(b)+","+a+")";
};
Listing
... var col1="rgba(255,0,0,0.5)";//destination var col2="rgba(0,0,255,0.6)"; //source ctx.fillStyle=kolor(col1, col2, "source-over"); ctx.fillRect(270,75, 50,50); ctx.fillText(ctx.fillStyle, 200,170);
Reguły
copy

| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | 0 | D | D |
destination-atop
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | S | 0 | D |
destination-in
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | 0 | 0 | D |
destination-out
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | 0 | D | 0 |
destination-over
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | S | D | D |
lighter
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | S | 0 | S |
source-atop
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | 0 | D | S |
source-in
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | 0 | 0 | S |
source-out
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | S | 0 | 0 |
source-over
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | S | D | S |
xor
| Obszar | 0 | S | D | SD |
| Wyświetlany | 0 | S | D | 0 |
