canvas教程

突袭HTML5之Canvas 2D入门3-变换与组合

字号+ 作者:H5之家 来源:H5之家 2017-06-02 11:05 我要评论( )

知识准备 - 坐标系 在真正开始总结变换之前,我们需要先了解一下canvas的相关坐标系知识。ldquo;像素坐标系rdquo;:在HTML中,我们会设置canvas的属性:width和h

突袭HTML5之Canvas 2D入门3-变换与组合

分享:

知识准备 - 坐标系

  在真正开始总结变换之前,我们需要先了解一下canvas的相关坐标系知识。

“像素坐标系”:在HTML中,我们会设置canvas的属性:width和height,它们是以像素为单位的,它们描述了canvas最终的呈现区域,我形象称之为“像素坐标”(自创,不是很贴切,行家别见笑),这个坐标系原点在canvas的左上角,这个坐标系当canvas创建完成以后,就不会变了(当然了,修改width与height的时候会变的),原点一直位于左上角;x与y各有多少像素,都已经由width和height决定了。说白了,这个东西就像画画时的画布,你给多大就多大。

“网格坐标系”:在绘图的时候使用的坐标系。我们绘图时所有的单位使用的并不是像素坐标,而是这个称为网格的坐标系。为了在有限的画布内,画出各种比例的图形,我们可能就要对这个坐标系进行各种变换(平移、旋转、缩放)。所以后面总结的各种变换都是针对网格坐标系的。

  这两个坐标系的关系其实就像显示器与桌面的关系一样,显示器就相当于像素坐标系,它的点都是固定的,造出来什么样就什么样。桌面就像是网格坐标系,我们可以随时移动,旋转桌面,修改桌面分辨率来看更多的内容。

  在canvas中,默认情况下,网格坐标与像素坐标是一一对应的,原点都在左上角,每1个网格单位对应1个像素单位。canvas里的所有物体的位置都是相对于网格坐标的原点而言的。如下面图中所示,默认情况下,蓝色方块的位置就是距左边x单位和距上边y单位(坐标(x, y))。

  

 

知识准备 - 状态保持
  在正式介绍变形之前,还需要先了解一下两个绘制复杂图形就必不可少的方法,这两个方法在变形中应用的相当广泛。
  保存状态:context.save()
  恢复状态:context.restore()
  save和restore方法是用来保存和恢复canvas状态的,都没有参数。canvas的状态就是当前画面应用的所有样式和变形的一个快照。
  canvas状态是以堆(stack)的方式保存的,每一次调用save方法,当前的状态就会被推入堆中保存起来。这种状态包括:
• 当前应用的变形(即移动,旋转和缩放);
• 所有样式:strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值;
• 当前的裁切路径(clipping path)。
  你可以调用任意多次save方法,将canvas状态入栈。每一次调用restore方法,上一个保存的状态就从堆中弹出,所有设定都恢复。
下面的例子能很容易的说明save与restore的使用方法:
function draw() { 
  var ctx = document.getElementById('lesson01').getContext('2d'); 
 
  ctx.fillRect(0,0,150,150);   // Draw a rectangle with default settings 
  ctx.save();                  // Save the default state 
 
  ctx.fillStyle = '#09F'       // Make changes to the settings 
  ctx.fillRect(15,15,120,120); // Draw a rectangle with new settings 
 
  ctx.save();                  // Save the current state 
  ctx.fillStyle = '#FFF'       // Make changes to the settings 
  ctx.globalAlpha = 0.5;     
  ctx.fillRect(30,30,90,90);   // Draw a rectangle with new settings 
 
  ctx.restore();               // Restore previous state 
  ctx.fillRect(45,45,60,60);   // Draw a rectangle with restored settings 
 
  ctx.restore();               // Restore original state 
  ctx.fillRect(60,60,30,30);   // Draw a rectangle with restored settings 
}

  在上面的例子中可以看到,如果每次都手动修改各个样式的值,那将会很麻烦,特别是样式的值很多的时候,更是容易出错。这个时候使用save/restore还是很方便的。
变换
  学过图形学的都知道,变换有这么几种:移动,旋转和缩放。为了弄清楚变换的效果,我们一定要理解,变换的目标是哪个。上面我也说了,这些变换都是针对网格坐标系的。下面分别看一下这些变换。
平移变换:将网格坐标系的原点移动指定的偏移量。
context.translate(x, y)
translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量。
在做变形之前先保存状态是一个良好的习惯。大多数情况下,调用restore方法比手动恢复原先的状态要简单得多。特别是在循环中,更要注意保存和恢复canvas的状态。
旋转变换:将网格坐标系沿着自己的原点顺时针旋转指定的角度。
context.rotate(angle)
这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。旋转的中心点始终是 canvas 的原点。
缩放变换:将网格坐标系的坐标单位按照指定的比例进行缩小或放大。
context.scale(x, y)
scale 方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。
  因为像素大小是不变的,所以这个变换实际的效果就是同样大小的画布内,能画的东西多了或少了。
  变换例子如下:
function draw() { 
  var ctx = document.getElementById('lesson01').getContext('2d'); 
  ctx.lineWidth = 1.5; 
  ctx.fillRect(0,0,300,300);  

  ctx.translate(150,150); 
  ctx.rotate(Math.PI/4);
  ctx.scale(0.5,0.5);
  ctx.clearRect(-40,-40, 80,80);
}

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
网友点评
o