使用画布单独倾斜图像

Skewing images individually using canvas

本文关键字:倾斜 图像 布单独      更新时间:2023-09-26

我使用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绘制图像时,有没有一种方法可以扭曲图像?提前感谢!

这里有两件事你必须理解。

将转换应用于上下文时,不会将其应用于已绘制的任何内容。您只将转换应用于要绘制的关于的内容。

换句话说,当您使用drawImage绘制图像时,总是倾斜图像的情况!这是唯一的办法。

这个规则有一个例外,您应该记住,因为您使用的是imageData:将imageData放到画布上是像素完美的,并且忽略任何变换矩阵。

因此,如果你想对每个阴影有不同的倾斜,你所要做的就是变换上下文,画出a,然后用其他方式恢复和变换上下文,然后画出B。

下面是一个使用代码的示例:

http://jsfiddle.net/QfrVB/


顺便说一句,您根本不需要在这里使用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/