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 |