canvas高级绘图操作(平移、缩放、旋转、矩阵变换) + 案例
●save()与restore()
context对象提供了保存于恢复canvas的状态函数
1:save() :将当前canvas中的所有状态信息保存入堆
2:restore(): 该方法用于弹出并开始使用堆最上面保存的状态信息
●translate()平移
context.translate(x,y);
x: 将坐标原点向左或右移动多少个单位
y: 将坐标原点向下或上移动多少个单位
案例 1:观察原点的位置变化
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillRect(0,0,50,50);
ctx.translate(200,200);
ctx.fillStyle = 'blue';
ctx.fillRect(-100,-100,80,80);// 从(100,100)开始绘制
var ctx2 = canvas.getContext('2d');
ctx2.fillStyle = 'red';
ctx2.fillRect(0,0,80,80);// 坐标轴原点已经改变(200,200)
</script>
案例 2:绘制不同的花
<body>
<select name="" id="draw">
<option value="1">蓬莱菊花</option>
<option value="2">令箭荷花</option>
</select>
<canvas width="200" height="200" id="canvas"></canvas>
<input type="button" id="btn" value="绘制">
</body>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var btn = document.getElementById('btn');
var A;
btn.onclick = btn_click;
function btn_click() {
var w = canvas.width;
var h = canvas.height;
var X0 = w / 2;
var Y0 = h /2;
var k = parseInt(document.getElementById('draw').value);// 默认为1
// console.log(k);
if(k == 2)
{
A = Y0*0.25;
}
else
{
A = Y0*0.75;
}
ctx.save();// 保存当前绘制的状态
ctx.clearRect(0,0,w,h);// 清除之前绘制的图形
ctx.translate(X0,Y0);// 将坐标原点移到canvas中间
ctx.beginPath();// 开始绘制
for( var B = 0;B <= 6.28;B = B+0.01)
{
draw(B);
}
ctx.closePath();
ctx.restore();// 恢复到保存前的状态
}
function draw(B){
var n = 10;
var r,x,y ;
switch(parseInt(document.getElementById('draw').value))
{
case 1:
r = A * Math.sin(n*B);
case 2:
r = A * (Math.sin(n*B)+3*Math.sin(3*n*B));
}
x = r*Math.cos(B);
y = r*Math.sin(B);
ctx.fillStyle = 'green';
ctx.strokeStyle = 'black';
ctx.lineTo(-x,-y);
ctx.fill();
ctx.stroke();
}
</script>
●scale()缩放
context.scale(x,y);
x:表示水平方向缩放的倍数;
y:表示垂直方向缩放的倍数。
案例
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.strokeStyle = "#fc0";
ctx.linewidth = 1.5;
ctx.fillRect(0,0,300,300);
ctx.save();// 保存当前的状态
ctx.translate(50,50);//平移原点坐标
draw(ctx,22,6,5);
ctx.translate(100,0);
ctx.scale(0.75,0.75);// 缩放图形
draw(ctx,22,6,5);
ctx.translate(133.133,0);// 在上一个基础上平移
ctx.scale(0.75,0.75);// 在上面的基础上缩小
draw(ctx,22,6,5);
ctx.restore();
function draw(ctx,R,r,O)
{
var x1 = R - O,y1 = 0,i = 1;
ctx.beginPath();
ctx.moveTo(x1,y1);
do{
if(i < 20000)
{
var x2 = (R + r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i * Math.PI / 72));
var y2 = (R + r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i * Math.PI / 72));
ctx.lineTo(x2,y2);
x1 = x2;
y1 = y2;
i++;
}
}while(x2 != R-O && y2 != 0);
ctx.stroke();
}
</script>
●rotate()旋转
rotate()方法用于将画布的x轴顺时针转动到与原x轴方向成angle角的位置,转动后x轴方向同时发生变化。
<script>
var ctx = document.getElementById('canvas1').getContext('2d');
ctx.translate(160,160);// 平移
ctx.fillStyle = 'rgba(200,54,54,0.5)';
for(var i = 0;i < 15; i++)
{
ctx.scale(0.98,0.98);
ctx.moveTo(0,0);// 移到原点
ctx.lineTo(30,30);
ctx.stroke();
ctx.rotate(Math.PI/10);// 将画布的x轴旋转到与原X轴成18度,每循环一次旋转18度
ctx.fillRect(0,0,100,50);
}
</script>
●transform()矩阵变换
context.transform(ma1,ma2,mb1,mb2,dx,dy);
前4个参数:修改使用这个方法之后绘制图形时的计算方法,从而达到变形的目的;
dx/dy表示将坐标原点在x轴或y轴方向上移动;
各参数说明:水平缩放、水平倾斜、垂直倾斜、垂直缩放、水平移动、垂直移动
1:平移:使用transform(1,0,0,1,x,y)或者transform(0,1,1,0,x,y)代替translate(x,y);
2:缩放:使用transform(x,0,0,y,0,0)方法代替scale(x,y);
3:旋转: 使用transform(
Math.cos(angleMath.PI/180),
Math.sin(angleMath.PI/180),
-Math.sin(angleMath.PI/180),
Math.cos(angleMath.PI/180),
)
案例
<script>
var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = '#eee';
ctx.fillRect(0,0,750,600);
var colors = ['#f00','#f90','#ff0','#090','#00f','#0051a1','#09f'];
ctx.lineWidth = 10;
ctx.transform(1,0,0,1,100,0);// 不缩放,不倾斜,将原点在x轴方向平移100px;
for(var i = 0;i<colors.length;i++)
{
ctx.beginPath();
ctx.transform(1,0,0.03,1,10,10);// 每次循环原点向右下移动10px,且倾斜0.03
ctx.strokeStyle = colors[i];
ctx.arc(150,200,150,0,2,true);
ctx.stroke();
}
</script>
●setTransform()矩阵变换
setTransform()方法将变换的矩阵进行重置,它把当前的变换矩阵重置为单位矩阵
context.setTransform(ma1,ma2,mb1,mb2,dx,dy)
各参数说明:水平旋转、水平倾斜、垂直倾斜、垂直缩放、水平移动、垂直移动