I tried to make this happen with canvas' globalCompositeOperation
, but had no luck so I'm asking here. There are similar questions here, but I did not find my case among them.
I have layers in my canvas area as so (drawing order from bottom to top):
house
is a picture of a house. The background is transparent. (see below)roofOverlay
is an overlay "masking" image that has the roof area coloured red (can be anything, but red for clarity, see below)Both images take up the whole canvas and are lined up perfectly on top of each other, so that the red roof area matches the house.
I then have a repeating background repeatPattern
pattern what I want to use ONLY inside the red areas: to fill the red area with repeatPattern
. (can be anything, but assume hexagons or whatever)
In pseudocode, this would ideally be something in the lines of:
roofOverlay.maskBackground(repeatPattern)
(On a sidenote, I would also like to be able to mess with the background pattern HSL-values, but I think that's quite straightforward once I get the pattern to even display)
The expected result would be a house which roof is textured with the repeatPattern image.
Note: I'm aware of clipping paths with masks, but I cannot use them here. The example is simplified and drawing all the paths for multiple different houses would be way too much work. I only have the overlayed png-files for the roof.
house
roofOverlay
As well as adding elements such as images, icons, and text, you have the option to personalize the background of your canvas. Applying a different background can completely change the appearance of your creation.
Here’s how to composite your “roof pattern” on top of your “house” using “roofOverlay”
This is a multi-part process:
Here is a Fiddle that loads grass on your roof: http://jsfiddle.net/m1erickson/SWP6v/
And here is code that uses a lattice pattern fill on your roof:
Note: I'm assuming that you want the house and roof on separate canvases so you can flip through a variety of roof choices. If you need everything on 1 canvas, you can just draw the roof canvas onto the house canvas.
<!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; }
canvas{border:1px solid red;}
#container{position:relative;}
#house{position:absolute; top:0; left:0;}
#canvas{position:absolute; top:0; left:0;}
</style>
<script>
$(function(){
var house=document.getElementById("house");
var ctxHouse=house.getContext("2d");
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var red=new Image();
red.onload=function(){
canvas.width=red.width;
canvas.height=red.height;
var houseImage=new Image();
houseImage.onload=function(){
house.width=houseImage.width;
house.height=houseImage.height;
ctxHouse.drawImage(houseImage,0,0);
}
houseImage.src="https://dl.dropbox.com/u/1122582/stackoverflow/house.png";
ctx.drawImage(red,0,0);
var imageObj = new Image();
imageObj.onload = function() {
var pattern = ctx.createPattern(imageObj, 'repeat');
ctx.globalCompositeOperation = 'source-in';
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = pattern;
ctx.fill();
};
imageObj.src = "http://dl.dropbox.com/u/139992952/stackoverflow/lattice.jpg";
}
red.src="https://dl.dropbox.com/u/1122582/stackoverflow/roof-overlay.png";
}); // end $(function(){});
</script>
</head>
<body>
<div id="container">
<canvas id="house" width=300 height=300></canvas>
<canvas id="canvas" width=300 height=300></canvas>
</div>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With