原文:HTML5新增核心工具——canvas

Canvas元素称得上是HTML5的核心所在,它是一个依靠JavaScript绘制华丽图像的元素。

Canvas由一个可绘制地区HTML代码中的属性定义决定高度和宽度,JavaScript代码可以访问该地区,通过一套完整的绘图功能类似于其他通用二维的API,从而生成动态的图形。

Canvas可以在浏览器中绘制出十分华丽的图形,比如:

当然这应该算比较高级的用法了,本菜也不会=.=

Canvas一个很大的作用就是制作游戏,本文通过博主之前做的一个小游戏来从零介绍Canvas的用法,先展示下吧:

OK,这就是用Canvas来完成的游戏。

绘制之前的准备工作:

1.在body中加入canvas标签,设置它的id、width、height,当然也可以动态设置它的宽高。

 <canvas id="mycanvas" width="1200" height="500"></canvas>

2.获得canvas对象的上下文obj.getContext(par),par参数为“2d”,目前canvas只支持二维效果。

var ctx = document.getElementById("mycanvas").getContext("2d");

如此你便有了一张1200*500的“画布”和一支名为“ctx”的画笔,接下来我们从一些最简单的图形开始绘制。

绘制矩形:

示例代码如下:

var ctx=document.getElementById("container").getContext("2d");

    ctx.fillStyle="blue";
ctx.fillRect(10,10,200,100); ctx.lineWidth=10;
ctx.strokeStyle="red";
ctx.strokeRect(300,10,200,100);

其中fill表示填充,stroke表示仅绘制边框。

同理fillRect表示实心矩形,strokeRect表示矩形边框,他们都有四个参数:x,y,w,h 分别为横纵坐标、宽、高。

fillStyle表示填充样式,strokeStyle表示边框样式。

lineWidth表示线宽。

显示结果:

需要注意的是,设置样式等应写在绘制图形之前,否则样式会渲染不上。

在绘制多个图形时,应该在绘制一个图形之前开绘制路径,定制完成后关闭绘制路径并绘制定制好的图形。例如上例标准写法应为:

   var ctx=document.getElementById("container").getContext("2d");
ctx.beginPath();
ctx.fillStyle="blue";
ctx.fillRect(10,10,200,100);
ctx.closePath();
ctx.stroke(); ctx.beginPath();
ctx.lineWidth=10;
ctx.strokeStyle="red";
ctx.strokeRect(300,10,200,100);
ctx.closePath();
ctx.stroke();

beginPath()开启绘制路径,closePath()闭合绘制路径,stroke()绘制定制图形。在之后的练习中一定要养成习惯,否则当绘制线条时就会发现由于未闭合绘制路径所出现的线条错连。

绘制线条:

示例代码如下:

var ctx=document.getElementById("container").getContext("2d");
ctx.beginPath();
ctx.moveTo(400,100);
ctx.lineTo(300,200);
ctx.lineTo(350,200);
ctx.lineTo(250,300);
ctx.lineTo(400,300);
ctx.closePath();
ctx.stroke();

其中,moveTo表示将画笔移动到某个坐标上,lineTo指以画笔落点开始画到哪个位置。本次我们想要画一个简单的树冠,结果:

可见,这里我们只画了一半。(400,100)位置为树顶,(400,300)位置为树底中部,线条自动闭合正是我们关闭绘制路径所产生的效果。

接下来我们把另一半画完,并给这棵树填充上绿色:

 var ctx=document.getElementById("container").getContext("2d");
ctx.beginPath();
ctx.fillStyle="green";
ctx.moveTo(400,100);
ctx.lineTo(300,200);
ctx.lineTo(350,200);
ctx.lineTo(250,300);
ctx.lineTo(400,300);
ctx.lineTo(550,300);
ctx.lineTo(450,200);
ctx.lineTo(500,200);
ctx.lineTo(400,100);
ctx.fill();
ctx.closePath();
ctx.stroke();

注意写在最后的fill()为填充样式:

绘制圆形:

示例代码:

 var ctx=document.getElementById("container").getContext("2d");
ctx.beginPath();
ctx.arc(200,200,100,0,360*Math.PI/180,true);
ctx.closePath();
ctx.stroke();

arc(x,y,r,starta,enda,anti);参数分别代表:圆心横、纵坐标,半径、起始角(需转换成弧度值)、终止角、绘制方向。

用canvas绘制圆,如果你是刚接触一定觉得很纠结,因为它的参数有很多都是相反的。这里为了大家不纠结,我多罗嗦几句。

起、止角的计算与我们数学上的角度计算不同,数学中的角度逆时针为正,而这里的起止角是以顺时针为正,也就是当你起角设为0度,止角设为120度。它是从右边水平位置向下旋转计算角度。

还有就是绘制方向上,true代表逆时针,false代表顺时针。晕了的同学看下面的例子:

 ctx.arc(200,200,100,0,120*Math.PI/180,true);

设起角为0,止角120。按数学上的思想应该是一个小于半圆的上半边的弧,而结果:

这里true表示逆时针绘制,所以绘出了的图形大于半圆。若改为false:

此时顺时针绘制出的图形小于半圆,这里大家应该也可以理解arc的角度计算方向是与数学相反的。要想画一个位于上方的小半圆?止角设为-120度,绘制方向true即可。

这里罗嗦这么多就是希望刚接触的朋友们少走弯路,不像我们研究半天。

绘制阴影:

 var ctx=document.getElementById("container").getContext("2d");
ctx.beginPath();
ctx.fillStyle="gray";
ctx.shadowOffsetX=5;
ctx.shadowOffsetY=5;
ctx.shadowColor="gold";
ctx.shadowBlur=5;
ctx.fillRect(10,10,100,100);
ctx.closePath();
ctx.stroke();

shadowOffsetX、shadowOffsetY表示阴影横、纵向偏移量,shadowColor表示阴影颜色,shadowBlur表示模糊等级。

由于在之前CSS3相关博文中已经讲了不少关于阴影的东西了,这里就一笔带过。依然需要注意的是,先设置样式,最后再绘制矩形,顺序反了效果会渲染不上。

绘制渐变:

线性渐变:

   ctx.beginPath();
var Color=ctx.createLinearGradient(500,500,500,0);
Color.addColorStop(0.3,"orange");
Color.addColorStop(0.5,"yellow");
Color.addColorStop(1,"gray");
ctx.fillStyle=Color;
ctx.fillRect(0,0,1200,500);
ctx.closePath();
ctx.stroke();

写法为:将ctx.createLinearGradient()赋值给一颜色变量,颜色变量可以添加多个渐变颜色,addColorStop其共有两个参数,1.偏移量(0-1)2.颜色。最后将颜色变量赋给fillStyle。

createLinearGradient()共有四个参数:1、2表示起始面,3、4表示终于面。

径向渐变:

   ctx.beginPath();
ctx.arc(500,300,100,0,360*Math.PI/180,true);
var Color=ctx.createRadialGradient(500,300,30,500,300,100);
Color.addColorStop(0,"red");
Color.addColorStop(0.5,"orange");
Color.addColorStop(1,"yellow");
ctx.fillStyle=Color;
ctx.fill();
ctx.closePath();
ctx.stroke();

与线性渐变比较相似,不同的是其名为createRadialGradient()中有六个参数:1、2.渐变开始圆的圆心坐标,3.渐变开始圆的半径,4、5.渐变结束圆的圆心坐标,6.渐变结束圆的半径。

绘制文字:

ctx.beginPath();
ctx.strokeStyle="gold";
ctx.fillStyle="bule";
ctx.font="50px 微软雅黑";
ctx.strokeText("hello world!",700,200);
ctx.font="30px 幼圆";
ctx.fillText("hello kitty?",700,300);
ctx.fill();
ctx.closePath();
ctx.stroke();
fillText(text,x,y,[maxwidth])绘制字符串,text表示文字内容,x,y文字坐标位置。[maxwidth]可选,设置字符最大宽大防止溢出。font设置字体。
其它参数:
textAlign 设置文字水平对齐方式 value 为 start|end|left|right|center  默认值为start
textBaseline 设置文字垂直对齐方式 value 为 top|hanging|middle|alphabetic|ideographic|bootom  默认为alphabetic
大家有兴趣自己试试吧。
 
图片绘制:
呼.....写了半天终于写到正题了,相对于上面简单图形的绘制,图片绘制要用的更多一些,尤其是在游戏中。
这里介绍一种较简单的方法,首先在body中写上:
   <div class="hide">
<img src="" id="myImg">
</div>

将你想要绘制的图片先加入body中,然后将父级div隐藏,一个隐藏的div中可以放入一个项目中所有需要绘制的图片甚至是音频文件,就好像一个别人看不见的素材库。

然后:

 var ctx = document.getElementById("mycanvas").getContext("2d");
var img=document.getElementById("myImg");
ctx.beginPath();
ctx.drawImage(img,x,y);
ctx.closePath();
ctx.stroke();

得到你想要绘制的图片对象,通过drawImage来绘制。这里drawImage()可以有3个参数,5个参数,9个参数。

3个参数:1.需要绘制的图片对象 2,3.图片坐标;

5个参数:1.需要绘制的图片对象 2,3.图片坐标 4,5.图片宽高;

9个参数:1.需要绘制的图片对象 2,3.绘制图片的横纵向切割点 4.横向切割宽度 5.纵向切割高度 6,7.切割好的图片坐标 8,9.切割好的图片宽高。

前两个比较好理解,第三种参数模式怎么用呢?这里举个例子:在最开始展示的游戏中,会走路的怪物并不是gif,而是如下的背景透明的PNG格式:

我们通过一定的时间间隔截取图片中不同的区域,连贯起来就成了动画的效果了。说起切割图片,学过Web性能优化的人很容易想起 Spirite,它就是通过把一网页上的所需的图片全部汇集到一张图上,用哪部分就截取哪部分。

扯远了,现在我们试着让这种绿怪物走起来:

 var ctx=document.getElementById("container").getContext("2d");
var img=document.getElementById("myImg");
var X=0;
var countNum=0;
function picRun(){
ctx.clearRect(0,0,1200,1000);
countNum++;
if(countNum==10){
X+=129;
countNum=0;
}
if(X>=387){
X=0;
}
ctx.beginPath();
ctx.drawImage(img,X,0,129,135,100,100,129,135);
ctx.closePath();
ctx.stroke();
}
window.setInterval(picRun,30);

*** 首先加入图片,获取图片对象。分析下怪物走路那张图片,宽为515px,高为135px,也就是说每个单独的怪物宽为四分之一即129px,高为135px。

将横向切割点设为变量X,由于此图只需横切不需要纵切,纵向切割点设为常量,实际上做法一样。

在drawImage中填入参数,就本例而言只有横向切割点一个变量。通过setInterval来循环执行picRun函数,每30毫秒执行一次。countNum俗称计数器,在做游戏中比较常见,目的是为了控制图片的切换频率。

(由于一个游戏中通常有多个动作频率不同的对象,所以当然不能随便改变setInterval的执行频率。加入了计数器,就能很好的控制各个对象的动作频率了)

本例中图片切换频率为30*10即300毫秒一次,切换时横向切割点右移135px即怪物宽度,当横向切割点大于3个怪物宽度时回0坐标重新切割。

clearRect()是为了清除之前的图层,始终只显示一张图片,否则每次切出的新图会不停叠加。

结果:

本文到此结束,下篇介绍HTML另一核心工具——本地存储,敬请期待。

HTML5新增核心工具——canvas的更多相关文章

  1. HTML5新增核心工具——本地存储

    除了Canvas元素外,HMTL5另外一个新增的非常重要的功能是可以在客户端本地存储数据库的Web Storage.本文就介绍下Web Storage以及SQLLite操作. Web Storage分 ...

  2. Html5新增元素中Canvas 与内联SVG的比较!

    SVG与Canvas的区别与比较如下: svg:使用xml描述2D图形,canvas使用javascript描述2D图形. Canvas 是逐像素进行渲染的,在 canvas 中,一旦图形被绘制完成, ...

  3. html5新增及删除标签

    一.新增标签 有一种划分为,功能性标签[html5新增,如canvas,旧浏览器没有]和语义性标签[如header等只是增强语义,没有新功能].下面按照分几个小类来说. 1.结构标签 新增的结构标签, ...

  4. HTML5 的绘图支持- canvas

    Canvas HTML5新增了一个canvas元素,它是一张空画布,开发者需要通过JavaScript脚本进行绘制. 在canvas上绘图,经过如下3步 (1) 获取canvas元素对应的DOM对象. ...

  5. HTML5新增Canvas标签及对应属性、API详解(基础一)

    知识说明: HTML5新增的canvas标签,通过创建画布,在画布上创建任何想要的形状,下面将canvas的API以及属性做一个整理,并且附上时钟的示例,便于后期复习学习!Fighting! 一.标签 ...

  6. HTML5新增及移除的元素

    HTML经过10多年的发展,其元素经历了废弃与不断重新定义的过程.为了更好的处理现在的互联网应用,HTML5新增了图形绘制.多媒体播放.页面结构.应用程序存储.网络工作等新元素.http://hove ...

  7. HTML5新增的属性

    关于html5新增的属性: HTML5现在已经不是SGML的子集,主要是增加了关于图像,位置,存储,多任务等功能. 绘画CANVAS; 用于播放媒体的video和audio元素: 本地离线存储loca ...

  8. HTML5界面开发工具jQuery EasyUI更新至v1.3.5

    本文转自:evget.com HTML5界面开发工具 jQuery EasyUI 最新发布v1.3.5,新版修复了多个bug,并改进了menu,tabs和slider等多个控件.jQuery Easy ...

  9. 优秀工具推荐:两款很棒的 HTML5 游戏开发工具

    HTML5 众多强大特性让我们不需要多么高深技术就能创建好玩的网页游戏,同时证明了开放的 Web 技术能与任何其他在游戏开发中使用的技术竞争.正如标题所说,这篇文章推荐的几款很棒 HTML5 游戏开发 ...

随机推荐

  1. HDU 4946 Area of Mushroom 凸包

    链接:pid=4946">http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点 ...

  2. C语言API编写窗口界面和button

            近期有个同学的程序须要用对话框的方式实现,但前面都是通过黑框形式完毕的,老师突然让添加一个界面,本来准备採用MFC完毕的,但后来一想,该程序核心东西是体如今它的算法上,控制台的程序并不 ...

  3. c#左右socket连接超时控制方案

    之前有一个项目中使用Remoting技术.当远程地址无效或server不执行,访问远程对象的方法,它会经过几十秒的时间来抛出异常秒. 由于我使用tcp状态.因此,认为可以使用socket为了测试连接, ...

  4. CPU 风扇清理灰尘加油全过程图解

    主机电源风扇因为使用时间长,风扇轴承的润滑油耗尽,导致风扇转速下降或是不转,引起电源热量无法有效排除而造成电脑常常死机,解决的方法有几种. 现图讲解明最简单省钱的办法例如以下: 1.把电源从主机上拆下 ...

  5. 补间动画实现(tween)

    1.补间动画的概念: 补间动画:仅仅须要开发人员设置好动画的開始与结束的关键帧 中间帧有喜用计算机补齐. 2.种类:分为4种: ①alpha 透明度 ②alpha 透明度 ③translate 位置移 ...

  6. MFC属性页对话框

    属性页对话框 分类 分页和引导 类 CPropertyPage-父亲CDialog类别,所谓的属性页或网页对话框. CPropertySheet-父类是CWnd,称为属性表单. 一个完整的属性页对话框 ...

  7. YUV422蓝色屏幕输出的调试援助

    YUV422蓝色屏幕输出的调试援助 YUV422有YUYV,YVYU,UYVY,VYUY四种,以下笔者就就以UYVY为例介绍一下数据构成.因为常常要跟视频输入打交道,所以YUV422这种常见的视频信号 ...

  8. Ruby: Count unique elements and their occurences in an array

    Is there a method in Ruby that takes an array, and counts all unique elements and their occurrences ...

  9. Ubuntu 中查看内核版本和系统版本的三个命令

    一.查看内核版本:cat /proc/version 二.查看内核版本:uname -a 三.查看系统版本:lsb_release -a 四.查看发行版类型:cat /etc/issue

  10. 博客测试:博客系统i94web beta1.0 申请测试

    如何做了最近的博客更新,因为已经在线路和代码,我写了一个小博客系统:i94web,草草宣布beta1.0,请求您测试各种漏洞. 先看几张截图. 首页: watermark/2/text/aHR0cDo ...