Наклон изображения по отдельности с использованием холста - PullRequest
2 голосов
/ 13 февраля 2012

Я использую холст 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? Заранее спасибо!

1 Ответ

3 голосов
/ 13 февраля 2012

Здесь необходимо понять две вещи.

Когда вы применяете преобразование к контексту, вы не применяете его к чему-либо уже нарисованному.Вы применяете преобразование только к тем вещам, которые примерно должны быть нарисованы.

Другими словами, всегда - это случай, когда вы искажаете изображения при их рисовании, используя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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...