译者注:变换计算中需要用到很多矩阵变换运算,如果不熟悉矩阵变换运算,那么理解以下代码会有一定困难,建议先熟悉矩阵变换运算再阅读以下内容。这里有一篇很好的文章详细解释了矩阵运算:浅谈矩阵变换——Matrix。
为了在HTML5画布上实现平移,可以使用上下文对象的translate()方法。平移是一种移动整个画布的方法。例如,有一个在画布上绘制复杂图形的函数,并且需要平移图形,那么平移上下文要比调整组成图形的所有点的x和y位置容易得多。
平移首先通过变换画布上下文,然后再绘制图形。在本教程中,将平移画布上下文,然后在位置(0, 0)绘制矩形。由于画布上下文被平移,矩形也将被平移。
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var rectWidth = 150;
var rectHeight = 75;
// translate context to center of canvas
context.translate(canvas.width / 2, canvas.height / 2);
context.fillStyle = 'blue';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
以上代码演示了在画布上平移一个矩形到居中位置。
要缩放HTML5画布,可以使用scale()方法,此方法可缩放画布的X和Y两个方向。
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var rectWidth = 150;
var rectHeight = 75;
// translate context to center of canvas
context.translate(canvas.width / 2, canvas.height / 2);
// scale y component
context.scale(1, 0.5);
context.fillStyle = 'blue';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
以上代码演示了在画布上绘制一个矩形,并在Y方向缩放0.5倍。
要旋转HTML5画布,可以使用rotate()转换方法。旋转变换需要提供转过的弧度(注意不是角度)。为了定义旋转点,需要首先平移画布上下文对象,以便上下文的左上角位于所需的旋转点上。在本教程中,平移了画布上下文,使得上下文的左上角直接位于矩形的中心,从而产生围绕矩形中心的旋转。
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var rectWidth = 150;
var rectHeight = 75;
// translate context to center of canvas
context.translate(canvas.width / 2, canvas.height / 2);
// rotate 45 degrees clockwise
context.rotate(Math.PI / 4);
context.fillStyle = 'blue';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
以上代码演示了平移画布,绘制矩形,并将其旋转一定角度。
为了将自定义转换矩阵应用到HTML5画布,可以使用transform()方法。根据以下约定,该方法需要3×3矩阵的六个分量:
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var rectWidth = 150;
var rectHeight = 75;
// translation matrix:
// 1 0 tx
// 0 1 ty
// 0 0 1
var tx = canvas.width / 2;
var ty = canvas.height / 2;
// apply custom transform
context.transform(1, 0, 0, 1, tx, ty);
context.fillStyle = 'blue';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
以上代码演示了自定义变换。
为了在HTML5画布上实现斜切变换,可以使用transform()方法进行矩阵转换。SX定义水平方向切变,SY定义垂直方向的切变。
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var rectWidth = 150;
var rectHeight = 75;
// shear matrix:
// 1 sx 0
// sy 1 0
// 0 0 1
var sx = 0.75;
// .75 horizontal shear
var sy = 0;
// no vertical shear
// translate context to center of canvas
context.translate(canvas.width / 2, canvas.height / 2);
// apply custom transform
context.transform(1, sy, sx, 1, 0, 0);
context.fillStyle = 'blue';
context.fillRect(-rectWidth / 2, rectHeight / -2, rectWidth, rectHeight);
以上代码演示了在画布上绘制一个蓝色矩形,并进行X方向的斜切变换。
要使用HTML5 Canvas创建镜像变换,我们可以在上下文对象的x方向上应用负比例来水平翻转,或者可以在上下文对象的y方向上应用负比例来垂直翻转。
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// translate context to center of canvas
context.translate(canvas.width / 2, canvas.height / 2);
// flip context horizontally
context.scale(-1, 1);
context.font = '30pt Calibri';
context.textAlign = 'center';
context.fillStyle = 'blue';
context.fillText('Hello World!', 0, 0);
以上代码演示了在画布的X方向反转一段文字。
为了重置HTML5 Canvas矩阵变换,可以使用setTransform()方法执行以下矩阵变换,将转换矩阵设置为其默认状态:
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var rectWidth = 150;
var rectHeight = 75;
// translate context to center of canvas
context.translate(canvas.width / 2, canvas.height / 2);
context.fillStyle = 'blue';
context.fillRect(-rectWidth / 2, rectHeight / -2, rectWidth, rectHeight);
// Reset Transform
// 1 0 0
// 0 1 0
// 0 0 1
// apply custom transform
context.setTransform(1, 0, 0, 1, 0, 0);
context.fillStyle = 'red';
context.fillRect(0, 0, rectWidth, rectHeight);
以上代码演示了在画布上重置变换,并用红色绘制默认状态的图形。
为了用HTML5 Canvas保存和恢复不同的变换状态,可以使用canvas上下文对象的save()和restore()方法。
在本教程中,将通过在每次转换之前将状态推入状态堆栈来保存变换状态,也就是为上下文对象设置保存点,以便上下文能准确回复到保存点的状态。首先绘制一个蓝色矩形,恢复并弹出最后一个转换状态;再绘制一个红色矩形,恢复并弹出最后一个转换状态;再绘制一个黄色矩形,最后恢复并弹出最终转换状态;再绘制一个绿色矩形。
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var rectWidth = 150;
var rectHeight = 75;
context.save();
// save state 1
context.translate(canvas.width / 2, canvas.height / 2);
context.save();
// save state 2
context.rotate(Math.PI / 4);
context.save();
// save state 3
context.scale(2, 2);
context.fillStyle = 'blue';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
context.restore();
// restore state 3
context.fillStyle = 'red';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
context.restore();
// restore state 2
context.fillStyle = 'yellow';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
context.restore();
// restore state 1
context.fillStyle = 'green';
context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);
以上代码演示了在画布上保存和弹出状态变换。
要使用HTML5 Canvas创建一个椭圆形,可以为上下文状态设置一个保存点,然后水平拉伸画布上下文,画一个圆圈,然后再恢复画布到保存点的状态,最后应用样式。
body {
margin: 0px;
padding: 0px;
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = 0;
var centerY = 0;
var radius = 50;
// save state
context.save();
// translate context
context.translate(canvas.width / 2, canvas.height / 2);
// scale context horizontally
context.scale(2, 1);
// draw circle which will be stretched into an oval
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
// restore to original state
context.restore();
// apply styling
context.fillStyle = '#8ED6FF';
context.fill();
context.lineWidth = 5;
context.strokeStyle = 'black';
context.stroke();
以上代码演示了在画布上设置保存点,然后使画布在X方向放大2倍,再绘制一个圆(由于受到X方向放大两倍的影响,这个圆变成了椭圆),然后恢复到保存点并应用样式,最后为椭圆描边的过程。