Anu*_*nup 29 javascript canvas composition html5-canvas
在我的项目中,我必须使用画布在另一个相同尺寸和图案图像上实现一个不同的彩色图像,并且图像不是圆形或矩形形状.所有这些都是波浪形状,它将应用于单个主背景图像,以在每个onclick功能上显示多个图形.
重叠图像应更改为另一种选定颜色.我的问题是否有任何使用画布的方法我们可以改变画布绘制的图像颜色,或者我们需要总是使用不同的图像并应用CSS/jQuery.
我读到了关于画布图像遮罩和重叠的内容.但不能理解我的图像,因为它不是方形或圆形,那么首先是我如何在单个图像上绘制多个波形.我不知道我搜索但没有找到完美的解决方案.
我需要的是在画布上绘制一个波形图像并从点击功能中更改其颜色,并设置另一个带背景图像的div,还有两个画布将重叠.这可能吗?
(这意味着:此功能用于在汽车上创建或设置多个图形,因为每个图形图像需要在画布中设置,而另一个图形需要在div和第一个画布上重叠)
小智 54
目前的问题是IMO有点不清楚.要给出一个更通用的答案,您可以应用于需要裁剪的场景,您可以使用(至少)两种方法:
复合模式是最简单的方式,但也是最不灵活的,因为您需要将剪贴蒙版预先定义为具有透明背景的图像(通常为PNG).
您可以使用图像的实体部分剪切下一个绘制的事物,也可以使用透明区域填充.
这是一种方法,我们使用实体部分剪切下一个绘制的形状/图像:
/// 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);
Run Code Online (Sandbox Code Playgroud)
这里globalCompositeOperation改为,source-in这意味着源图像(我们将在目标旁边绘制的图像)将被绘制在现有的实体数据中.透明区域不会被吸引.
如果我们的剪贴蒙版看起来像这样(从网上随机公平使用):

我们的形象是这样的:

结果将是这样的:

您还可以为剪辑定义路径.这非常灵活,因为您可以根据需要调整路径或设置动画.
注意:请记住,使用Path的剪辑目前在浏览器中有点"脆弱",因此您应该考虑使用save()和restore()设置之前和之后使用剪辑路径,因为浏览器此刻无法重置剪辑(restore将恢复default clip = full canvas);
让我们定义一个简单的之字形路径(在你的情况下这将是你的波浪):
/// 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();
Run Code Online (Sandbox Code Playgroud)
现在我们已经使用clip绘制到画布的任何东西来设置剪贴蒙版,然后将剪裁以适合该形状(注意我们确保形状可以在它开始的地方结束):

mar*_*rkE 46
您可以使用上下文合成来替换图像的一部分.
例如,如果您已将此蓝色徽标作为图像:

任何你想要徽标的顶部是紫色的:

您可以使用合成来重新着色图像的顶部.
首先,用你最喜爱的图像编辑器来裁剪掉你的任何一部分不希望重新着色.
剩下的东西称为叠加层.
图像的这个叠加部分是我们将以编程方式重新着色的部分.

该叠加可以以编程方式重新着色为任何颜色.


叠加层是如何以编程方式重新着色的:
如何使用更改的叠加颜色完成徽标
这种"目的地 - 顶部"合成效果有时被称为"绘图下".
这个叠加甚至可以用纹理代替!

这是代码和小提琴: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>
Run Code Online (Sandbox Code Playgroud)