В HTML5 canvas, как замаскировать изображение с фоном по моему выбору?
Я пытался сделать это с canvas'globalCompositeOperation
, но не повезло, поэтому я спрашиваю здесь. Здесь есть аналогичные вопросы, но я не нашел среди них своего случая.
у меня есть слои в моей области холста так (порядок рисования снизу вверх):
- основание холста заполнено чистым белым цветом (#fff, с fillRect)
- первое изображение
house
картинка дом. Фон прозрачен. (см. ниже) - второе изображение
roofOverlay
является наложением "маскирующего" изображения, которое имеет область крыши красного цвета (может быть что угодно, но красный для ясности, см. ниже)
оба изображения занимают весь холст и выстроились идеально друг на друге, так что красная крыша соответствует дому.
у меня тогда есть повторяющийся фон repeatPattern
шаблон, который я хочу использовать только внутри красных областей: заполнить красную область с repeatPattern
. (может быть что угодно, но предположим, что шестиугольники или все, что угодно)
в псевдокоде это было бы идеально что-то в строках:
roofOverlay.maskBackground(repeatPattern)
(на sidenote, я также хотел бы иметь возможность возиться с фоновым шаблоном HSL-значений, но я думаю, что это довольно просто, как только я получаю шаблон даже для отображения)
ожидаемый результат:
ожидаемым результатом будет дом, крыша которого текстурирована с изображением repeatPattern.
Примечание: я в курсе отсечения пути с масками, но я не могу использовать их здесь. Пример упрощен, и рисование всех путей для нескольких разных домов было бы слишком большой работой. У меня есть только наложенные png-файлы для крыши.
картинки для ссылок
house
roofOverlay
1 ответов
вот как составить ваш "рисунок крыши" поверх вашего "дома", используя "кровельную кладку"
это процесс из нескольких частей:
- нарисуйте дом на холсте№1.
- нарисуйте красный roofOverlay на холсте#2.
- установить контекст холста#2.globalCompositeOperation = 'source-in'
- нарисуйте желаемый рисунок на холсте#2
- Compositing вызовет желаемый шаблон для замены красного наложения-только в красной области наложения.
вот скрипка, которая загружает траву на крышу:http://jsfiddle.net/m1erickson/SWP6v/
и вот код, который использует заполнение решетки на вашей крыше:
примечание: Я предполагаю, что вы хотите, чтобы дом и крыша на отдельных холстах, чтобы вы могли пролистывать различные варианты крыши. Если вам нужно все на 1 холсте, вы можете просто нарисовать холст крыши на дом холст.
<!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>