Maskowanie / nakładanie obrazu na płótnie
W moim projekcie muszę zaimplementować jeden inny obraz kolorowy na innym obrazie o tym samym rozmiarze i wzorze za pomocą płótna, a obrazy nie są w kształcie okrągłym lub prostokątnym. Wszystkie są w kształcie fal i będą stosowane na jednym głównym obrazie tła do wyświetlania wielu grafik na każdej funkcji onclick
.
Nakładający się obraz powinien zostać zmieniony na inny wybrany kolor. Moje pytanie jest w jakiś sposób z użyciem canvas z tego możemy zmienić kolor obrazu, który jest rysowany przez canvas lub my trzeba zawsze używać różnych obrazów i stosować z CSS / jQuery.
Czytałem o maskowaniu i nakładaniu obrazów na płótno. Ale nie mogę zrozumieć z moich obrazów, ponieważ nie są w kształcie kwadratu lub koła, a następnie pierwszą rzeczą jest, jak rysuję wiele kształtów fal na jednym obrazie. Nie mam pojęcia, że szukałem, ale nie znalazłem idealnego rozwiązania.Moje potrzeby to po prostu narysować jeden obraz fali na płótnie i zmienić jego kolor z funkcji kliknięcia, a także ustawić inny div z tło-obraz, a także więcej niż dwa płótna będą nakładać się na siebie. Czy to możliwe?
(to znaczy: ta funkcja służy do tworzenia lub ustawiania wielu grafik na samochodzie, aby każdy obraz graficzny musiał być ustawiony na płótnie, a inna grafika musi nakładać się na div I pierwsze płótno)
2 answers
Do zastąpienia części obrazu można użyć komponowania kontekstowego.
Na przykład, jeśli masz już to niebieskie logo jako obrazek:
Jeśli chcesz, aby górna część logo miała kolor fioletowy:Możesz użyć komponowania, aby zmienić kolor górnej części obrazu.
Najpierw użyj ulubionego edytora obrazów, aby przyciąć dowolną część, której nie chcesz ponownie pokolorować.
To, co pozostało, nazywa się nakładka.
Ta nakładkowa część obrazu jest tym, co programowo przebarwimy.
Ta nakładka może być programowo przebarwiona na dowolny kolor.
Jak nakładka została programowo przebarwiona:
- narysuj nakładkę na pustym płótnie.
- Ustaw tryb komponowania na "source-in".
- efekt: tylko istniejące piksele są zastępowane-przezroczyste piksele pozostają transparent
- teraz narysuj prostokąt dowolnego koloru pokrywający płótno
- (pamiętaj, tylko istniejąca nakładka zostanie zastąpiona nowym kolorem)
Jak uzupełnić logo zmienionym kolorem nakładki
- Ustaw tryb kompozycji na "cel-szczyt"
- efekt: tylko przezroczyste piksele są zastępowane-istniejące piksele pozostają niezmienione Teraz narysuj oryginalne logo]}
- (remember, the istniejące kolorowe nakładki nie zostaną zastąpione)
Ten "cel-szczyt" efekt kompozycyjny jest czasami nazywany "rysowaniem pod".
Tę nakładkę można nawet zastąpić teksturami!
Oto kod i skrzypce: http://jsfiddle.net/m1erickson/bfUPr/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var truck,logo,overlay;
var newColor="red";
var imageURLs=[];
var imagesOK=0;
var imgs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/boxTruck.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/TVlogoSmall.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/TVlogoSmallOverlay.png");
loadAllImages();
function loadAllImages(){
for (var i = 0; i < imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){ imagesOK++; imagesAllLoaded(); };
img.src = imageURLs[i];
}
}
var imagesAllLoaded = function() {
if (imagesOK==imageURLs.length ) {
// all images are fully loaded an ready to use
truck=imgs[0];
logo=imgs[1];
overlay=imgs[2];
start();
}
};
function start(){
// save the context state
ctx.save();
// draw the overlay
ctx.drawImage(overlay,150,35);
// change composite mode to source-in
// any new drawing will only overwrite existing pixels
ctx.globalCompositeOperation="source-in";
// draw a purple rectangle the size of the canvas
// Only the overlay will become purple
ctx.fillStyle=newColor;
ctx.fillRect(0,0,canvas.width,canvas.height);
// change the composite mode to destination-atop
// any new drawing will not overwrite any existing pixels
ctx.globalCompositeOperation="destination-atop";
// draw the full logo
// This will NOT overwrite any existing purple overlay pixels
ctx.drawImage(logo,150,35);
// draw the truck
// This will NOT replace any existing pixels
// The purple overlay will not be overwritten
// The blue logo will not be overwritten
ctx.drawImage(truck,0,0);
// restore the context to it's original state
ctx.restore();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=500 height=253></canvas>
</body>
</html>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 17:54:04
Pytanie w obecnej formie jest IMO nieco niejasne. Aby dać bardziej ogólną odpowiedź, którą możesz zastosować do scenariusza, w którym potrzebujesz obcinania, możesz użyć (co najmniej) dwóch podejść:
Metoda 1 - użycie trybu kompozytowego do klipu
Tryb kompozytowy jest najprostszym sposobem, ale również najmniej elastycznym, ponieważ musisz wstępnie zdefiniować maskę przycinającą jako obraz z przezroczystym tłem (Zwykle PNG).
Możesz użyć stałych części obrazu, aby przyciąć następną narysowaną rzecz, lub użyj przezroczystych obszarów do wypełnienia.
Oto podejście, w którym używamy części stałych do przycinania następnego narysowanego kształtu / obrazu:
/// draw the shape we want to use for clipping
ctx1.drawImage(imgClip, 0, 0);
/// change composite mode to use that shape
ctx1.globalCompositeOperation = 'source-in';
/// draw the image to be clipped
ctx1.drawImage(img, 0, 0);
Tutaj globalCompositeOperation
zmienia się na source-in
, co oznacza, że obraz źródłowy (ten, który będziemy rysować obok miejsca docelowego) zostanie narysowany wewnątrz istniejących stałych danych. Nic nie zostanie przyciągnięte do przezroczystych obszarów.
Jeśli nasza maska obcinająca wygląda tak (losowe fair-use z sieci):
I nasz obraz tak:
Wynik będzie następujący:
Metoda 2-Użycie ścieżki do klipu
Można również zdefiniować ścieżkę do przycinania. Jest to bardzo elastyczne, ponieważ możesz dostosować ścieżkę lub animować ją, jeśli chcesz.
Uwaga: Należy pamiętać, że przycinanie przy użyciu ścieżki jest obecnie nieco "kruche" w przeglądarkach, więc należy rozważyć użycie save()
i restore()
przed i po ustawieniu i użyciu ścieżki klipu, ponieważ przeglądarki nie są w stanie tego zrobić zresetuj klip w tej chwili (restore
przywróci domyślny klip = pełne płótno);
Zdefiniujmy prostą ścieżkę zygzakowatą (w Twoim przypadku będą to twoje fale):
/// use save when using clip Path
ctx2.save();
ctx2.beginPath();
ctx2.moveTo(0, 20);
ctx2.lineTo(50,0);
/// ... more here - see demo
ctx2.lineTo(400, 20);
ctx2.lineTo(400, 100);
ctx2.lineTo(0, 100);
ctx2.closePath();
/// define this Path as clipping mask
ctx2.clip();
/// draw the image
ctx2.drawImage(img, 0, 0);
/// reset clip to default
ctx2.restore();
Teraz, gdy ustawiliśmy maskę przycinającą za pomocą clip
wszystko, co zostanie narysowane na płótnie, zostanie przycięte, aby zmieścić się w tym kształcie (pamiętaj, że upewniamy się, że kształt może zakończyć się tam, gdzie się rozpoczął):
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 17:35:39