爱妃科技Canvas进阶教程(一):基础回顾 | | 爱妃科技
正在加载
请稍等

菜单

红楼飞雪 梦

15526773247

文章

Home web前端开发 Canvas进阶教程(一):基础回顾
Home web前端开发 Canvas进阶教程(一):基础回顾

Canvas进阶教程(一):基础回顾

web前端开发 by

html5中最强大的武器当属canvas莫属。从文字处理到电子游戏,canvas都会提供给你而且总体而言运行速度相当快,而且编码良好的canvas应用程序无需修改即可在任何兼容html5浏览器中进行运行。

偶尔因为canvas更新而浏览器版本跟不上导致细微差别。而针对低版本ie的兼容我们过会儿再说。

我们先从canvas基本开始走起:

实现canvas首先要在页面中定义一个canvas元素,该元素与普通页面元素无差别<canvas></canvas>即可,在不定义其宽高时候默认宽高是300*150个像素。

而我们可以在元素上进行修改其默认宽高如下:

1
<canvas id="canvas" width="600" height="400" style="solid thin #aaa"></canvas>

大家可能注意到其中的width以及height值后面没有跟px像素,这是canvas规范所要求的,其规范规定宽高的值是数字类型,所以我们遵循规范即可。有的同学可能认为页面与样式应该分离,其实分离未尝不可,只是如果进行分离时候canvas宽高默认的300*150像素会保持在绘图环境中,

而你在css中定义的canvas元素的宽高只是定义canvas元素宽高,实际绘图环境还是不会改变的,这样一来我们画出来的东西可能跟我们初衷效果会不一样,这点需要注意,所以我们尽量不在css中定义宽高,但是可以定义其他canvas样式,例如边框大小样式等。

因为canvas是基于html5而来,html5尚有一些ie低版本浏览器不支持,更何况canvas,不过canvas在不支持canvas的浏览器中进行默认兼容,即:如果你的浏览器不支持canvas那么显示以下p标签内容:

1
<canvas id='canvas' width="600" height="400" style="border thin #aaa"><p>亲,你的浏览器不支持canvas,该更新浏览器版本了</p></canvas>

当然其中的p标签你可以根据业务需要换成图片或者任何其他浏览器可以识别的元素来供用户浏览。然后我们可以跟其他js写法一样新建一个js文件或者在html页面书写js代码:

1
2
3
4
5
6
<script type="text/javascript">
window.onload=function(){
var canvas=document.getElementById('canvas'),
context=canvas.getContext("2d");
}
</script>

我们在加载页面完成之后(在此为了之后为ie低版本做兼容才在页面加载后执行canvas)首先得到对canvas的引用,然后利用canvas建立一个 2d环境的绘图对象context,之后我们就可以利用context来实现我们想要的文本动画图片等“绘图”操作了。

我们先来画一条线段

首先我们要指定开始点:

1
context.moveTo(10,10);

moveTo方法定义绘图的起始点,整个canvas坐标从左上角开始是(0,0)向右边下边为正并且增加相当于一个倒立的二维坐标系。

然后定义线段结束点context.lineTo(10,50);

这样我们就定义了一个长为40像素的一条线段,但是到现在为止canvas画布上没有出现线段,我们需要用stroke方法来完成绘图操作,刚才的两个方 法只是绘制一条路径,但并未真正的进行绘图,利用context.stroke()就完成了一条默认黑色宽度为1像素的线段。

我们可以继续context.lineTo(20,100)来以最后一个结束点为开始点进行继续画线段,如果要重新定位的话则需要moveTo方法。

画图不能只能画线段吧,下面我们来画矩形:

画矩形有几种方式 1.context.rect(0,0,100,100)定义一个以canvas左上角为矩形左上角坐标,宽高各为100像素矩形,然后context.stroke()完成绘制

2.context.rect(0,0,100,20)定义一个以canvas左上角为矩形左上角坐标,宽高各为100像素矩形,然后context.fill()完成绘制

3.直接context.strokeRect(0,0,100,100)实现同上面1一样结果

4.context.fillRect(0,0,100,100)绘制一个默认用黑色填充的宽高100像素的矩形与2一样效果

矩形画完了,我们来画圆:

画圆或者圆弧的方法是arc:context.arc(canvas.width/2,canvas.height/2,100,0,Math.PI*2,true);其中包含五个参数依次代表为圆心xy坐标,半径,圆弧起始点(三点钟方向为0),圆弧长度。

ok有了线段矩形圆弧我们就可以综合做很多东西了,在实际工作中我们一般还会用到beginPath以及clearRect方法,beginPath定义一个路径的开始,clearRect方法清除指定的矩形内容。

在某一时刻,canvas中只能存在一条路径也就是当前路径,通过beginPath我们可以清除当前路径来进行下一个路径开始举个例子:

我们画两个矩形分别应用beginPath以及不应用beginPath方法:

1
2
3
4
5
context.rect(10,10,100,100);
context.stroke();
context.beginPath();
context.rect(50,50,100,100);
context.stroke();

这样一来我们就绘制了两个我们初衷的矩形。假如不用beginPath方法呢?

1
2
3
4
context.rect(10,10,100,100);
context.stroke();
context.rect(50,50,100,100);
context.stroke();

在不用beginPath方法时候我们创建两个矩形,这样一来绘图环境就包含了两个路径,结果是第一个矩形没什么影响,而第二个矩形在第一个矩形路径基础上又一次stroke,这样第二个路径(矩形)就又一次被描边。如图所示:

兼容性问题

canvas在ie8以及低版本中都不被支持,可以下载excanvas.js来通过vml进行兼容,下载地址为excanvas兼容js,下载解压后拿出里面的excanvas.js放置我们工作目录下即可,不过有些地方还是不支持。

1.动态生成的Canvas对象将不支持getContext方法,

2.drawImage方法不能用Canvas对象作为第一个参数,

3.不支持fillText等方法;

针对三种问题在excanvas里面做兼容如下:

1.动态创建的标签:因为excanvas只是页面已有的canvas标签然后执行G_vmlCanvasManager_.initElement()进行初始化。我们动态生成的就要刻意初始化一下所以修改如下:

1
2
3
4
5
var cav = document.createElement("canvas"); 
if(!cav.getContext) { 
  G_vmlCanvasManager.initElement(cav);
var ctx = cav.getContext("2d");

2.不能用canvas对象作为第一个参数:大家都知道drawImage方法的第一个参数可以是image也可以是当前或者其他canvas对象,但是在ie下引进excanvas后不支持canvas,修改如下:

1
2
3
4
5
6
contextPrototype.drawImage = function(image, var_args) { 
//增加以下if三行代码
    if (image.getContext) { // draw canvas 
      this.element_.innerHTML += image.getContext("2d").element_.innerHTML; 
    
  var dx, dy, dw, dh, sx, sy, sw, sh;

3.不支持fillText方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
contextPrototype.measureText= function(textToDraw) { 
  var hiddenSpan = document.createElement('span'); 
  hiddenSpan.style.font = this.font; 
  hiddenSpan.innerHTML = textToDraw; 
  var bodyNode = document.getElementsByTagName("body")[0]; 
  bodyNode.appendChild(hiddenSpan); 
  var width = hiddenSpan.offsetWidth; 
  bodyNode.removeChild(hiddenSpan); 
  return {"width" : width + 1}; 
}  contextPrototype.fillText = function(textToDraw, x, y) { 
  var vmlStr = []; 
  var textHeightStr = this.font.split("px")[0].replace(/(^\s+)|(\s+$)/g, ""); 
  var textHeight = /^\d+$/.test(textHeightStr) ? parseInt(textHeightStr) : 0; 
  vmlStr.push('<g_vml_:shape style="font:' + this.font + ';'
                  ' color:' + this.fillStyle + ';'
                  ' position:absolute;'
                  ' left:' + x + 'px;'
                  ' top:' + (y - textHeight) + 'px;'
                  ' width:' + this.measureText(textToDraw).width + 'px;'
                  ' height:' + textHeight + 'px;"'
                  ' ><g_vml_:textbox inset="0,0,0,0">' + textToDraw, 
                  ' </g_vml_:textbox>'
                  '</g_vml_:shape>');
  this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); 
}

增加两个方法,通过在页面临时增加一个myText隐藏文字容器并获得其宽高,另外属性中增加默认字体:

1
2
3
this.strokeStyle = '#000'
this.fillStyle = '#000'
this.font = '12px sans-serif';

另外:google的excanvas要求在ie下必须通过window.onload()加载完之后再去调用canvas。

至此我们的canvas基本就可以对ie进行兼容了。

如果需要对html5进行兼容可以下载html5.js:html5.js下载

如果需要支持css3效果可以下载css3兼容下载,然后在需要支持css3的样式选择器中增加behavior: url(/public/ie-css3.htc)

;

 

11 2015-04

 

我要 分享

 

 

本文 作者

 

相关 文章