Posts match “ Canvas ” tag:

使用canvas 需要注意的几点

clearRect(x1,x2,width,height)

原本认为canvas一个令人不愉快的地方是,它不能部分擦除,把不变的东西保留下来,把变化了的擦除进行修改。clearRect()带来了福音。它可以清除指定矩形内的像素,不管是stroke出来的线条还是填充的形状。

这是没有经过clearRect之前的效果,它由一个矩形、两个半圆和一些锯齿形线条组成。在形状的组合上还有一些情况,就是它们的边界很明显,所以拼接时在拼接处加了一个像素的重叠。

这是使用了clearRect之后的效果。整个图经过了45度的旋转,所以画起来比较方便,半圆的角度也都是π/2的整数倍。还有比较多的是给canvas重设宽高值,这样它就会自动除去整个canvas上的像素,整体擦除。

closePath()

closePath()的作用在于它可以把形状的起点和末点仪直线的形式连起来。如果之前没有定义beginPath(),则以最开始画的点为起点。否则就以最近的beginPath()为起点。beginPath()会是下个形状和上一个形状脱离,重新选择绘图起点。最好是成对出现,这样就可以避免形状之间的牵连(上个形状的末点会合下个形状的起点连在一起)。

下半部分的图没有使用任何beginPath()和closePath(),所以首末点和中间形状间的首末点都连在了一起。

save()和restore()

save()restore()是比较使用的工具,它们分别用于保存当前绘图状态,获取上一次存储的绘图状态。绘图状态是指当前绘图说用的样式(style)和变形(transform),包括strokeStylefillStyle,globalAlphalineWidth,lineCaplineJoinmiterLimit,shadowOffsetXshadowOffsetY,shadowBlurshadowColorglobalCompositeOperation等属性以及一transform和clipping path。绘图状态被存在一个栈(stack)内,每一次调用save()都会把当前的绘图状态压到栈内。每一次调用restore()都会把靠近的存储状态调出来,回到那个绘图状态。这样就可以很方便的在不同的状态之间转换,而不用重新设置。

下面是一个例子:

 

(function(){
    var canv = document.getElementById('canvas')
    ,   contxt = canv.getContext('2d');
    contxt.fillStyle = '#379aff';
    contxt.arc(200,200,100, 0, 2*Math.PI);
    contxt.fill();
    contxt.save();
    contxt.fillStyle = 'white';
    contxt.beginPath();
    contxt.arc(200,200,80, 0, 2*Math.PI);
    contxt.closePath();
    contxt.fill();
    contxt.save();
    contxt.beginPath();
    contxt.fillStyle = 'black';
    contxt.arc(200,200,60, 0, 2*Math.PI);
    contxt.fill();
    contxt.restore();//白色
    contxt.beginPath();
    contxt.arc(200,200,40, 0, 2*Math.PI);
    contxt.fill();
    contxt.restore();//蓝色
    contxt.beginPath();
    contxt.arc(200,200,20, 0, 2*Math.PI);
    contxt.fill();
})();

HTML5 canvas 实例

用THML5 canvas 画了一个表示幻灯片的icon(100px * 78px)@speakerdeck.com

这个icon的绘制首先要选中canvas元素,然后设定它的绘制环境,此时是在向量图环境下 //cont=canv.getContext ('2d'),接下来就要绘制路径,用到的方法可以参考vectors vs bitmaps 。对于arc()需要再仔细看一下。

语法:arc(圆心横坐标,圆心纵坐标,半径,圆弧起始弧度,圆弧终止弧度,是否逆时针方向)                         代码:cont.arc(x,y,radius,startAngle,stopAngle,counterclockwise)                                                   不知道别人是不是也一样,反正我一开始对于这个起始弧度和终止弧度很不明白,每次都要根据画出来的图看看弧度是不是写对了。后来在网上看到了这个图。                                                                  

canvas以其元素的左上角顶点为原点,向右为横坐标正方向,向下为纵坐标正方向(viewport 和 document也一样)。上图的PI值就是在这样一个坐标下确定的,和我们学过的坐标是一样的。有了四个方向上的PI值就可以按照顺时针或是逆时针方向很容易的选择角度了。

具体实现的程序如下:                                                                                                              

心得:
  • 用canvas画图深切让我重温了大学里用autoCAD画图的经历,最麻烦的事就是确定学要的点的坐标,遇到sin cos时很麻烦。
  • 还有一点要注意!canvas的默认大小是300px * 150px,有时候我们不需要那么大,或是需要更大。这时候可以设置canvas的width值和height值,这里设置的方法并不是像第一块代码的注释那样对css样式进行修改,而是:                                                      

    canv.setAttribute("width","300");
    canv.setAttribute("height","300");
    或是
    canv.width = "300";
    canv.height = "300";

    这修改的只是canvas能够渲染的面积,并不会对绘制的图进行缩放,而上面代码中的注释:canv.style.width=“300px";
    canv.style.height=”300px“;
    (或者直接在css中改)则会对图进行缩放,它会根据canvas的默认值300px * 150px按比例进行缩放,现在x轴方向没变,y轴方向加倍了。如下图:

canvas 做的猜字游戏

用HTML5 canvas 做的小游戏,猜字母。字母为电脑随机产生的a到z之间的一个字母,一共有3次机会(可以修改),并且每次猜测之后都会有提示,正确的字母会在游戏结束后显示。下面为主界面,它是由canvas的toDataURL()方法导出的图片。

 

程序主要分三块:initGame(),keyPressed(),drawScreen(),最后还有导出图像的函数createImageDataPressed()。

整个图形是由HTML5 canvas画的,每一次按键都会触发一次keyPressed()事件,事件触发后设置一些变量,如按下的键,剩余的猜测次数,然后对canvas重新绘制,不重新绘制它会和之前画的重叠在一起。对canvas的height或width设置一次值它就会重新绘制,这是它的巧妙之处。但是不能做到保留不变的,绘制变化的部分,所以有好有坏。这一特性经常被用来清除画布内容。

第一步:设置一些全局变量,以便各个函数能够随时读取。

以下是要设置的值:

index为待猜测字母在letters数组中的索引值,它由初始化函数initGame()产生,index = Math.floor(Math.random()*letters.length);js的Math.random()产生的是一个大于0小于1的双精度浮点数。

第二步:主要函数

初始化函数主要对前面的变量进行初始化,并且对按键事件建立监听。

事件触发之后就能绘制图像了。这里的关键就是对按键事件的监听。其中函数fromCharCode(e.keyCode)为判断按下的是什么键的提供了很大的便利。它返回按下的键的值,然后就可以在letters数组中遍历,如果没找到,即返回-1,则用户没有按要求按下字母,返回的是>=0的数字,就可以与index相比较判断用户输得字母是低了还是高了,a方为低,z方为高。如果与index相等,那用户就赢了。但是不知道是不是编码的问题,按下其他键比如空格键、分号、逗号等它显示的是希腊字母。letterToGArray[]数组初始化为空数组,只有游戏结束是才会给它push进去一个值,即letterToGuess。

drawScreen()就没有什么悬念了,都是一些基本的操作,不做展示。还需值得一提的是canvas的toDataURL(),它能将canvas以图像的形式导出。但是从它的名字可以看出,它将返回的是图像的数据,以便存储或导出。

function createImageDataPressed (e) {
    window.open(canv.toDataURL(),"cavasImage","left=0,top=0,
width="+canv.width+",height="+canv.height+",toolbar=0,
resizable=0");}

live demo: http://www.tomo.im/guess-game