2.2.1 原点的位移
使用 translate() 方法可以将绘图原点向横向和纵向移动指定的距离(x, y),结果表现为整张图像的移动。如:
<script>
context.translate(x, y); </script>
效果图,translate方法被注释掉的效果
效果图,translate方法没有注释掉的效果
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d");
var rectWidth = 150; var rectHeight = 75;
// 把坐标原点移动到canvas中心点
// 如果本行被注释掉,结果就是上面第一张图,否则就是第二张图的效果 context.translate(canvas.width / 2, canvas.height / 2); context.fillStyle = "blue";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight); };
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.2 缩放
缩放操作使用 scale() 方法,参数x、y分别代表横向与纵向的缩放比例,两个参数都是浮点数, 1.0表示不缩放,小于1.0表示缩小,大于1.0表示放大。即,元坐标(x1, y1)上的点经 scale(x,
y) 缩放后的点将被移动到(x1*x, y1*y)。
如:
<script>
context.scale(x, y); </script>
效果图,scale方法被注释掉的效果
效果图,scale方法没有被注释掉的效果
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d");
var rectWidth = 150; var rectHeight = 75;
// 把坐标原点移动到canvas中心点
context.translate(canvas.width / 2, canvas.height / 2);
// 坐标在横向上缩小一半
context.scale(1, 0.5);
context.fillStyle = "blue";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight); };
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.3 旋转
旋转canvas用的方法是 rotate() 。此方法接受一个以弧度为单位的旋转参数,整个canvas将以坐标原点,也就是由 translate() 所确定的原点为圆心进行旋转。.在本教程中,我们将原点移动到了canvas的中心点上,这样图中的矩形就可以以其中心点进行旋转了。
如:
<script> context.rotate(angle);
</script>
效果图,scale被注释掉的效果
效果图,scale没有注释掉的效果
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d"); var rectWidth = 150; var rectHeight = 75;
// 把坐标原点移动到canvas中心点
context.translate(canvas.width / 2, canvas.height / 2);
// 顺时针旋转45度
context.rotate(Math.PI / 4);
context.fillStyle = "blue";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth,
rectHeight); };
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.4 用户自定义坐标变换
HTML5可以使用 transform() 方法以用户自定义的变换矩阵对图像坐标进行变换操作。这个方法需要6个参数组成一个 3 x 3 的转换矩阵,坐标的由 (x, y) 到 (x', y') 的转换公式如下所示:
<script>
context.transform(a, b, c, d, e, f);
</script>
效果图
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d"); var rectWidth = 150; var rectHeight = 75;
// 转换矩阵
// 1 0 tx
// 0 1 ty
// 0 0 1
var tx = canvas.width / 2; var ty = canvas.height / 2;
// 应用用户自定义转换
context.transform(1, 0, 0, 1, tx, ty);
context.fillStyle = "blue";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth,
rectHeight);
};
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.5 剪切变换
如果我们按照下面公式进行坐标变换的话,就可以对图像进行剪切变换。其中 sx 定义了水平方向
的剪切, sy 则定义了垂直方向上的剪切。
如:
<script>
context.transform(1 ,sy, sx, 1, 0, 0); </script>
效果图
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d"); var rectWidth = 150; var rectHeight = 75;
// 剪切矩阵
// 1 sx 0
// sy 1 0
// 0 0 1
var sx = 0.75; // .75 水平剪切 var sy = 0;
// 无垂直剪切
// 把坐标原点移动到中心点
context.translate(canvas.width / 2, canvas.height / 2);
// 应用用户定义转换
context.transform(1, sy, sx, 1, 0, 0);
context.fillStyle = "blue";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth,
rectHeight);
};
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.6 镜面转换
镜面转换只需要在 scale() 方法的参数中使用负值的参数,比如水平镜像就把x参数赋值一个负数,垂直镜像则是把y参数赋值一个负数。
如:
<script> // 水平镜像
context.scale(-1,1);
// 垂直镜像
context.scale(1,-1); </script>
效果图
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d");
// 把坐标原点移动到canvas中心点
context.translate(canvas.width / 2, canvas.height / 2);
// 水平翻转图像
context.scale(-1, 1);
context.font = "30pt Calibri"; context.textAlign = "center"; context.fillStyle = "blue"; context.fillText("Hello World!", 0, 0); };
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.7 重置转换如果要将坐标转换为原始状态,需要使用下面的公式调用 setTransform() 方法。
如:
<script>
context.setTransform(1, 0, 0, 1, 0, 0); </script>
效果图,红色为重置坐标到原始状态的效果
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d"); var rectWidth = 150; var rectHeight = 75;
// 把坐标原点移动到canvas中心点
context.translate(canvas.width / 2, canvas.height / 2);
context.fillStyle = "blue";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight);
// 重置转换
// 1 0 0
// 0 1 0
// 0 0 1
// 应用用户自定义转换
context.setTransform(1, 0, 0, 1, 0, 0);
context.fillStyle = "red";
context.fillRect(0, 0, rectWidth, rectHeight); };
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.8 变换状态栈
使用 save() 和 restore() 方法可以实现对坐标变换状态的保存与恢复。
在本教程中,我们在每次进行坐标转换前把当前的转换状态推进栈中。首先画一个蓝色的矩形,从状态栈中弹出恢复上一个转换状态,然后再画个红色的矩形,从状态栈中再弹出恢复上一个转换状态,再画个黄色的矩形,最后再从状态栈中再弹出恢复上最后一个转换状态,画一个绿色矩形。
如:
<script> context.save(); context.restore(); </script>
效果图
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d");
var rectWidth = 150; var rectHeight = 75;
context.save(); // 保存状态 1
context.translate(canvas.width / 2, canvas.height / 2);
context.save(); // 保存状态 2 context.rotate(Math.PI / 4);
context.save(); // 保存状态 3 context.scale(2, 2);
context.fillStyle = "blue";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight);
context.restore(); // 恢复状态 3 context.fillStyle = "red";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight);
context.restore(); // 恢复状态 2
context.fillStyle = "yellow";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight);
context.restore(); // 恢复状态 1
context.fillStyle = "green";
context.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth,
rectHeight); };
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>
2.2.9 椭圆
要画一个椭圆,我们可以这样做,首先保存转换状态,然后将canvas水平拉伸,画一个圆,恢复转换状态,然后应用样式。
效果图
代码
<!DOCTYPE HTML>
<html>
<head>
<style> body { margin: 0px; padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style> <script>
window.onload = function() {
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d");
var centerX = 0; var centerY = 0; var radius = 50;
// 保存状态 context.save();
// 移动原点
context.translate(canvas.width / 2, canvas.height / 2);
// 水平缩放
//context.scale(2, 1);
// 这里画的圆会被拉伸成椭圆
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
// 恢复原始状态
context.restore();
// 应用样式
context.fillStyle = "#8ED6FF";
context.fill();
context.lineWidth = 5; context.strokeStyle = "black";
context.stroke(); };
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>