我正在使用HTML5画布创建一系列树及其相应的阴影。我希望每个阴影都基于光源的位置。我可以画出每一棵树和它的阴影以及同时扭曲所有的阴影,但是试图单独歪斜每个阴影都会让我感到困惑。这是我的代码:
var ctx = cvs[0].getContext('2d');
ctx.save();
//skew the canvas
ctx.transform(1,0,0.3,-1,0,0);
ctx.drawImage(tree1,74,-117,20,40);
ctx.drawImage(tree1,126,-125,20,40);
var imgd = ctx.getImageData(0, 0, 500, 300);
var pix = imgd.data;
//convert the drawn trees to shadows
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i ] = 0; // red
pix[i+1] = 0; // green
pix[i+2] = 0; // blue
// alpha
}
ctx.putImageData(imgd, 0, 0);
//remove the skewing
ctx.restore();
//draw full color trees
ctx.drawImage(tree1,50,40,20,40);
ctx.drawImage(tree1,100,50,20,40);
当我使用drawImage绘制图像时,有没有办法扭曲图像?提前谢谢!
答案 0 :(得分:3)
这里有两件事需要你理解。
将变换应用于上下文时,不会将其应用于已绘制的任何内容。您只需将转换应用于要绘制的约的内容。
换句话说,当你使用drawImage绘制图像时,总是是你扭曲图像的情况!这是它完成的唯一方式。
这个规则有一个例外,你应该记住,因为你正在使用imageData:将imageData放到画布上是完美的像素并忽略任何变换矩阵。
因此,如果你想为每个阴影设置不同的偏斜,你只需要转换上下文,绘制事物A,然后以其他方式恢复和转换上下文并绘制事物B.
以下是使用您的代码的示例:
另外,你根本不需要在这里使用imageData。使用它是一个非常慢的操作(如果你正在制作像游戏一样的动画应用程序,这很重要),如果可以,你应该避免使用它。
而不是这样做:
var imgd = ctx.getImageData(0, 0, 500, 300);
var pix = imgd.data;
//convert the drawn trees to shadows
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i ] = 0; // red
pix[i+1] = 0; // green
pix[i+2] = 0; // blue
// alpha
}
ctx.putImageData(imgd, 0, 0);
你可以这样做:
ctx.globalCompositeOperation = 'source-atop';
ctx.fillStyle = 'black';
ctx.fillRect(0,0,500,300);
ctx.globalCompositeOperation = 'source-over'; // back to normal
该代码所做的是在画布上当前存在的所有像素上绘制黑色。因为你首先绘制所有阴影,所以你可以通过一次调用fillRect来将它们全部黑掉。
看到住在这里: http://jsfiddle.net/QfrVB/2/