HTML5详细介绍及使用
一、HTML5简介
1、HMTL5的定义
HTML是一种用符号来创建结构文档的语义。比如标题、章节、列表、链接、引用和其他各种元素都可以包含在结构文档中。
HTML5在W3C中的定义:HTML 5 是下一代的 HTML,设计HTML5最初目的是为了在移动设备上支持多媒体。HTML5规范于2014年10月29日由万维网联盟正式宣布,HTML万维网不等同于互联网,HTML是万维网最核心的超文本标记语言。但它是依靠互联网运行的服务之一,万维网又简写为www,它可以实现在互联网的帮助下,访问由许多互相链接的超文本组成的系统。
2、HTML5的发展历史
在1984年那个时候,世界上没有浏览器,也没有万维网(WWW),人们传递信息与资源交换也只能通过电话和邮件的方式进行。Tim Berners-Lee对此很感兴趣,努力之后,世界上第一款浏览器Enguire也因此诞生(用于数据的浏览与共享)。随后,Tim Berners-Lee仍在研究,并在1989年开发出了世界上第一个Web服务器与Web客户端,并将这项发明取名为world wide web,也就是我们现在所说的WWW万维网。HTML也因此诞生。
2014年10月29日,万维网联盟泪流满面地宣布,经过几乎8年的艰辛努力,HTML5标准规范终于最终制定完成了,并已公开发布。
HTML | 1991 | 1991年WWW在互联网上首次露面,也随之引起了巨大的轰动。 |
HTML+ | 1993 | 1993年ITEF(因特网工作小组)发布了一个草案,那时没有HTML的官方文档,各种标签(Tag)也很混乱。 这个草案HTML tags可以算是HTML的第一个版本。1994年,Tim Berners-Lee创建了非盈利性的 W3C(world wild web consortium万维网联盟),并邀请了当时的155家互联网巨头(如Microsoft、IBM、APPLE等公司),致力使得WWW有一套更加标准化的协议,能够让资源按照这套标准的协议进行处理与共享。那个时候W3C的根本目的就是为了维护互联网的对等性,为了让它保持最起码的秩序。 |
HTML 2.0 | 1995 | 1995年,HTML2.0发布 |
HTML 3.2 | 1996 | 1996年,由Tim Berners-Lee组织的W3C对HTML语言进行规范化,HTML3.2发布,1997年发布,W3C推荐标准。 |
HTML 4.01 | 1999 | 1999年,HTML4.01发布,同一年,W3C对HTML的未来做了展望。他们认为HTML存在一些缺陷,例如HTML的形式与内容无法分离、标记单一等等,前途不是很光明。于是W3C转向语言更加规范的XML,以便于弥补HTML的不足(XML全称Extensible Markup Language可拓展标记语言),但是从1991年HTML在互联网上出现到1999年这个时候已经过去8年了,全世界已经有成千上万的网页经由HTML编写,突然间更改一种语言是不现实的,故W3C只能放慢脚步,开始了HTML到XML的过渡。于是也就出现了XHTML。 |
XHTML 1.0 | 2000 | 2000年发布,XHTML1.0与HTML4.01内容是一样的,但是XHTML使用了新的语法规则。规定了所有元素、属性必须使用小写字母,属性值必须加引号,规定每个标签都必须有与之对应的结束标签。与这些规则相比起来HTML4.01的语法就显得很松散 |
XHTML1.1 | 2001 | XHTML1.1于2001年发布,在最开始W3C最终的目的就是为了使得HTML完全标准化,该版本的XHTML强制性的规定了文档必须标注为xml而不是html。 然而很多浏览器并不能很好的解析XML格式的文档,W3C这一步似乎走的太快了。 |
XTML2.0 | 2004 | 2004年,各大浏览器厂商也相继脱离了W3C,成立了新的小组WHATWG(超文本应用技术工作组world hypertext application technique work group)开始对HTML进行修缮,开始了向HTML5之路的进军。 XHTML生态环境渐渐破碎,2006年,XTML2没有实质性进展。Tim Berners-Lee反思,决定重组HTML工作组 |
HTML5 | 2014 | 2007年,W3C工作组重建,在WHATWG的基础上继续研究,规范也交付给WHATWG来制定。因此,也就出现了现如今的"一种格式,两个版本(HTML/XHTML)"的局面,但随着HTML5的到来,一种更加简洁的doctype(<!DOCTYPE html>)也逐渐运用到各大网站。 HTML 5 的第一份正式草案已于2008年1月22日公布。2009年,W3C也宣布停止XHTML2的研究工作。 2012年12月17日,万维网联盟(W3C)正式宣布凝结了大量网络工作者心血的HTML5规范已经正式定稿。 2013年5月6日, HTML 5.1正式草案公布。 2014年10月29日,万维网联盟泪流满面地宣布,经过几乎8年的艰辛努力,HTML5标准规范终于最终制定完成了,并已公开发布。 |
3、HTML5做了哪些改变
1)HTML 声明不同:HTML 4.01 规定了三种不同的 <!DOCTYPE> 声明,分别是:Strict、Transitional 和 Frameset。 HTML5 中仅规定了一种:<!DOCTYPE html>;
2)新语义标签的引入,淘汰过时的或冗余的属性;语义化的区块和段落元素:<section>
,<article>
,<nav>
,<header>
,<footer>
,<aside>
和<hgroup>
,除了节段,媒体和表单元素之外:<mark>
,<figure>
,<figcaption>
,<data>
,<time>
,<output>
,<progress>等;
3)HTML多媒体元素引入音频和视频:<audio>
和<video>
元素嵌入和允许操作新的多媒体内容;
4)新表单控件引入(date、time...)及input的属性;
5)脱离Flash 和Silverlight直接在浏览器中显示图形或动画。canvas标签(图形设计);
6)本地数据库(本地存储);
7)对本地离线存储有更好的支持;
8)一些API(文件读取、地址位置、网络信息...);
4、HTML5新增的元素
以前<div>(division,分区)元素,可以把整个HTML文档分隔为页眉、导航条、正文、页脚等在辅以少量的CSS就可以了,<div>+样式是蛮强大的,但是不够透明,在查看源码时,要区分哪个<div>表示什么还是有点费劲的,作为一个独立的区块,却不容易知道那个区块的意图。为此新增了一些语义元素,所有语义元素都有一个显著的特征:不真正做任何事情;
语义元素特性:1)让网页的结构更清晰;2)容易修改和维护;3)无障碍;4)搜索引擎优化;5)未来的功能。
5、HTML5中移除的元素
HTML5一方面添加了新元素,另一方面也从官方标准中剔除了少量的元素。这些元素仍然可以得到浏览器的支持,但是任何遵循规范的HTML5验证都会给出错误提示。HTML5沿袭了不欢迎表现性元素(为页面添加样式)的思想,这些都可以在样式中完成的。
二、HTML5中标签元素介绍
1、块级语义标签
一个语义元素能够清楚的描述其意义给浏览器和开发者。无语义元素实例: <div> 和 <span> - 无需考虑内容。语义元素实例: <form>, <table>, and <img> - 清楚的定义了它的内容。HTML5中新增了较多的语义元素来明确一个Web页面的不同部分。
元素 | 说明 |
<header> | (新增)表示增强型的标题,可以包含HTML标题和其他内容。其他内容可以是标志、作者署名、或一组指向后面内容的导航链接 |
<hgroup> | (新增)表示增强型的标题,分组两个或多个标题元素,不包含其他内容。其主要目的是把标题和副标题联系到一起 |
<nav> | (新增)表示页面中的重要的一组链接。其中的链接可以指向当前页的主题,也可以指向网站的其他页面。实际上,一个页面中包含多个<nav>也很正常 |
<section> | (新增)表示文档中的一个区块,或者一组文档。<section>是一个通用容器,只有一条规则;其中的内容必须始于一个标题。应该在其他语义元素(如<article>和<aside>)不适用的情况下再选择 |
<article> | (新增)表示一篇任何形式的文章,即类似新闻报道、论坛帖子或者博客文章(不包括评论或者作者简介)等能够独立的内容区块 |
<aside> | (新增)表示独立于周围环境内容的一个完整的内容块。例如,可以用<aside>创建一个附注栏,其中包含于主文章相关的内容或者链接 |
<figure> | (新增)表示一副插图,<figure>元素标注<figcaption>和插入图片的<img>元素。目标是反映图片与图题直接是关联的 |
<figcaption> | (新增)<figcaption>标注图题(插图的标题) |
<footer> | (新增)表示页面的底部页脚。通常是很小的一块内容,包括小号字的版权声明、简单的链接等; |
测试代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试语义标签</title>
<style type="text/css">
#s2{width:800px;height:300px;border: 2px red double;}
aside{width:60px;height:100%;float: left;text-align: left;border: 2px blue double;}
#a2{width:730px;height:100%;float: left;border: 2px yellow double;}
</style>
</head>
<body>
<nav>
<a href="yybq.html">首页</a>
<a href="#">标签变化</a>
<a href="#">网页布局</a>
<a href="">属性变化</a>
<a href="">音视频</a>
<a href="">表单验证</a>
<a href="">基础测试</a>
</nav>
<article>
<header>
<h1>我是一级标题</h1>
<p><time pubdate datetime="2020-11-27"></time></p>
</header>
<p>我是文章内容。。。中间省略1万字</p>
</article>
<section>
<figure>
<!--媒体内容块-->
<figcaption>音视频标题名称</figcaption>
<div class="video">...</div>
</figure>
</section>
<section id="s2">
<!--区块-->
<aside>
<!--内容侧边栏导航-->
<a href="#h1">article1</a>
<a href="#h2">articl2</a>
<a href="#h3">articl3</a>
</aside>
<article id="a2">
<!--文章-->
<h1>我是文章内容标题1</h1>
<h2>我是文章内容标题2</h2>
<h3>我是文章内容标题3</h3>
</article>
</section>
<footer><!--底部块-->
版权所有someContent...
</footer>
</body>
</html>
2、文本级语义元素
元素 | 说明 |
<time> | (新增)定义公历的时间(24 小时制)或日期,时间和时区偏移是可选的。 |
<mark> | (新增)定义带有记号的文本。(默认标记黄色背景) |
3、WEB表单
我们通常所说的web表单就是一组文本框、列表、按钮及其他可以点击的小控件,通过这些小控件可以收集网站访客的某些信息;HTML5中新增了一种机制,支持控件把他放在表单外面,使用新的from属性引用表单ID(如果浏览器没有实现则无效)。
表单元素 | 说明 |
<form> | 定义一个 HTML 表单,用于用户输入。 |
<input> | 定义一个输入控件 |
<textarea> | 定义多行的文本输入控件。 |
<button> | 定义按钮。 |
<select> | 定义选择列表(下拉列表)。 |
<optgroup> | 定义选择列表中相关选项的组合。 |
<option> | 定义选择列表中的选项。 |
<label> | 定义 input 元素的标注。 |
<fieldset> | 定义围绕表单中元素的边框。 |
<legend> | 定义 fieldset 元素的标题。 |
<datalist> | (新增)规定了 input 元素可能的选项列表。 |
<keygen> | (新增)规定用于表单的密钥对生成器字段。 |
<output> | (新增)定义不同类型的输出,比如脚本的输出。 |
1)<form>元素属性
属性 | 值 | 描述 |
---|---|---|
accept | MIME_type | HTML 5 中不支持。 |
accept-charset | charset_list | 规定服务器可处理的表单数据字符集。 |
action | URL | 规定当提交表单时向何处发送表单数据。 |
autocomplete | on、off |
(新增)规定是否启用表单的自动完成功能。 |
enctype | 见说明 | 规定在发送表单数据之前如何对其进行编码。 |
method | get、post |
规定用于发送 form-data 的 HTTP 方法。 |
name | form_name | 规定表单的名称。 |
novalidate | novalidate | (新增)如果使用该属性,则提交表单时不进行验证。 |
target | _blank、_self、_parent 、_top、framename |
规定在何处打开 action URL。 |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--form 的两个新属性:
autocomplete:浏览器会记住email之前输入过的值
novalidate:(不写H5会验证邮箱格式)规定在提交表单时不应该验证 form 或 input 域。
-->
<form action="index.html" autocomplete="on" novalidate>
E-mail: <input type="email" name="user_email" autocomplete="on"><br>
TelPh: <input type="tel" name="user_tel" autocomplete="off"><br>
<input type="submit">
</form>
</body>
</html>
b)enctype属性
在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型。
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 默认。在发送前对所有字符进行编码(将空格转换为 "+" 符号,特殊字符转换为 ASCII HEX 值)。窗体数据被编码为名称/值对。这是标准的编码格式。 |
multipart/form-data | 不对字符编码。当使用有文件上传控件的表单时,该值是必需的。 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分,这个一般文件上传时用。 |
text/plain | 将空格转换为 "+" 符号,但不编码特殊字符。窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。 |
案例如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/urlencoded?firstname=sid slayer&lastname=sloth" method="POST" enctype="application/x-www-form-urlencoded">
<input type="text" name="username" value="sid the sloth"/><br>
<input type="text" name="password" value="slothsecret"/><br>
<input type="submit" value="Submit" />
</form>
</body>
</html>
enctype="application/x-www-form-urlencoded" 编码方式,使用火狐浏览器查看请求数据(network):
POST /urlencoded?firstname=sid%20slayer&lastname=sloth HTTP/1.1 (在请求连接中空格使用%20代替)
username=sid+the+sloth&password=slothsecret (表单提交中空格使用+代替)
提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。Servlet的API提供了对这种编码方式解码的支持,只需要调用ServletRequest 类中的getParameter()方法就可以得到表单中提交的数据。
在传输大数据量的二进制数据时,必须将编码方式设置成enctype="multipart/form-data",当以这种方式提交数据时,如果以这种方式提交数据就要用request.getInputStream()或request.getReader()来获取提交的数据 ,用 request.getParameter()是获取不到提交的数据的。
2)<input>元素属性
属性 |
值 | 描述 |
---|---|---|
accept | mime_type | 规定通过文件上传来提交的文件的类型。 |
align | left、right、top、middle 、bottom |
不赞成使用。规定图像输入的对齐方式。 |
alt | text | 定义图像输入的替代文本。 |
autocomplete | on、off |
(新增)规定是否使用输入字段的自动完成功能。(会记住之前提交的记录,利与快速填写) |
autofocus | autofocus | (新增)规定输入字段在页面加载时是否获得焦点。 (不适用于 type="hidden") |
checked | checked | 规定此 input 元素首次加载时应当被选中。 |
disabled | disabled | 当 input 元素加载时禁用此元素。 |
form | formname | (新增)规定输入字段所属的一个或多个表单。 |
formaction | URL | (新增)覆盖表单的 action 属性。 (适用于 type="submit" 和 type="image") |
formenctype | 见注释 | (新增)覆盖表单的 enctype 属性。 (适用于 type="submit" 和 type="image") |
formmethod | get、post |
(新增)覆盖表单的 method 属性。 (适用于 type="submit" 和 type="image") |
formnovalidate | formnovalidate | (新增)覆盖表单的 novalidate 属性。 如果使用该属性,则提交表单时不进行验证。 |
formtarget | _blank、_self、_parent 、_top、framename |
(新增)覆盖表单的 target 属性。 (适用于 type="submit" 和 type="image") |
height | pixels、% |
(新增)定义 input 字段的高度。(适用于 type="image") |
list | datalist-id | (新增)引用包含输入字段的预定义选项的 datalist 。 |
max | number、date |
(新增)规定输入字段的最大值。 请与 "min" 属性配合使用,来创建合法值的范围。 |
maxlength | number | 规定输入字段中的字符的最大长度。 |
min | number、date |
(新增)规定输入字段的最小值。 请与 "max" 属性配合使用,来创建合法值的范围。 |
multiple | multiple | (新增)如果使用该属性,则允许一个以上的值。 |
name | field_name | 定义 input 元素的名称。 |
pattern | regexp_pattern | (新增)规定输入字段的值的模式或格式。 例如 pattern="[0-9]" 表示输入值必须是 0 与 9 之间的数字。 |
placeholder | text | (新增)规定帮助用户填写输入字段的提示。 |
readonly | readonly | 规定输入字段为只读。 |
required | required | (新增)指示输入字段的值是必需的。 |
size | number_of_char | 定义输入字段的宽度。 |
src | URL | 定义以提交按钮形式显示的图像的 URL。 |
step | number | (新增)规定输入字的的合法数字间隔。 |
type | button、checkbox、file 、hidden、image、password、 radio、reset、submit、text |
规定 input 元素的类型。 |
value | value | 规定 input 元素的值。 |
width | pixels、% |
(新增)定义input 字段的宽度。(适用于 type="image") |
案例如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--form 的两个新属性:
autocomplete:浏览器会记住email之前输入过的值
novalidate:(不写H5会验证邮箱格式)规定在提交表单时不应该验证 form 或 input 域。
-->
<form action="index.html" autocomplete="on" id="form1"> <!--novalidate-->
<!--input 的新属性:
autocomplete:浏览器会记住email之前输入过的值
autofocus:打开或者刷新时自动聚焦到该文本框上。
-->
E-mail: <input type="email" name="user_email" autocomplete="on" autofocus><br>
TelPh: <input type="tel" name="user_tel" autocomplete="off" ><br>
<!--type="number" 只能输入数字-->
age:<input type="number" id="age"/><br />
<input type="submit" value="提交"><br>
<!--input 的新属性:
formaction:覆盖表单的 action 属性。
height:定义 input 字段的高度。(适用于 type="image")
width:定义input 字段的宽度。(适用于 type="image")
formnovalidate:提交时可跳过验证提交,没加则无法跳过验证提交
-->
<input type="submit" formaction="index.html" value="暂存">
<input type="image" height="40px" width="120px" src="./img/2020050918313952.jpg"/>
</form>
Name: <input type="name" name="user_name" autocomplete="on" form="form1"><br>
</body>
</html>
3)<datalist>元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>datalist</title>
</head>
<body>
<form action="demo-form.php" method="get">
<!--datalist提供一个下拉选项-->
<input list="browsers" name="browser">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
<input type="submit">
</form>
</body>
</html>
4、部分新增元素及属性
元素/属性 | 说明 |
<progress> | 定义运行中的任务进度(进程)。 |
<meter> | 定义度量衡。仅用于已知最大和最小值的度量。meter控件为计量条控件,表示某种计量,适用于温度、重量、金额等量化的表现。 |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="button" value="下载" onclick="myFunction()"/><br />
进度条:
<progress id="jdt" value="10" max="100"><br /></progress>
无值时来回滚动:
<progress></progress>
<p>展示给定的数据范围:表示某种计量,适用于温度、重量、金额等量化的表现</p>
<meter id="mt" value="1" min="0" max="10">2 out of 10</meter><br>
<meter value="0.6">60%</meter><br />
</body>
</html>
<script type="text/javascript">
function myinterval(){
var vl = document.getElementById("jdt").getAttribute("value");
var v2 = document.getElementById("mt").getAttribute("value");
var v1 = Number(vl);
var v2 = Number(v2);
if(v1<100){
document.getElementById("jdt").setAttribute("value",(v1+10));
}
if(v2<10){
document.getElementById("mt").setAttribute("value",(v2+1))
}
}
function myFunction() {
var vl = document.getElementById("jdt").getAttribute("value");
var v = Number(vl);
if(v<100){
myVar = setInterval(myinterval, 1000);
}
}
</script>
5、音频与视频 (<video> )
以前添加视频使用最多的还是浏览器插件(比如Adobe Flash、微软的Silverlight),当然HTML5推出音频视频还是有很多限制和不足的地方的。HTML5视频没有任何版权保护措施,可以像保存图片一样保存视频,且支持的视频格式有限(有些MP4格式只有进度条,格式虽然都是MP4但是html中只支持H.264的编码格式)
标签元素 | 说明 |
<audio> | (新增)定义声音,比如音乐或其他音频流。支持的3种文件格式:MP3(最流行的音频格式,非免费)、Wav(未加工的音频格式)、Ogg(免费开放)。 |
<video> | (新增)定义视频,比如电影片段或其他视频流。支持三种视频格式:MP4、WebM(Google买下VP8后,此为免费标准)、Ogg(免费开发的视频标准)。 |
<video>音频格式的 MIME(内容) 类型(网页的MIME类型就是text/html)
格式 | MIME-type |
---|---|
MP4 | video/mp4(文件使用 H264 视频编解码器和AAC音频编解码器) |
WebM | video/webm(文件使用 VP8 视频编解码器和 Vorbis 音频编解码器) |
Ogg | video/ogg(文件使用 Theora 视频编解码器和 Vorbis音频编解码器) |
测试案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>音频与视频</title>
</head>
<body>
<!--<video src="video/测试影1.avi" type="video/mp4"></video>-->
<!--<video src="video/cs.mp4" type="video/mp4">播放</video><br />-->
<!--<video src="video/hh.mp4" type="video/mp4">hh</video>-->
<!--controls 属性向用户显示音频控件
preload="auto" 自动预加载-->
<!--<audio src="video/Beyond喜欢你.mp3" type="audio/mp3" controls preload="auto">mp3</audio>-->
<!--使用flash播放-->
<!--<object type="application/x-shockwave-flash" width="700" height="400" >
<param name="movie" value="video/flash8277.swf">
<param name="allowFullScreen" value="true">
</object>-->
<!--兼容性:不支持video的则会显示video中的内容使用flash-->
<video controls width="700" height="400">
<source src="video/cs.mp4" type="audio/mp4" preload="auto"></source>
<source src="video/cs.ogv" type="audio/ogg"></source>
<object type="application/x-shockwave-flash" width="700" height="400" >
<param name="movie" value="./video/flash8277.swf">
<param name="allowFullScreen" value="true">
</object>
</video>
</div>
</body>
</html>
三、Canvas绘图
1、Canvas发展史
Canvas的概念最初是由苹果公司提出的,用在Mac OS X Webkit中创建控制板部件(dashboard widget)。在Canvas出现之前,开发人员要在浏览器中使用绘图API,只能使用Adobe的Flash和SVG(Scalable Vector Graphics,可伸缩矢量图形)插件,或者只有IE才支持的VML(Vector Markup Language,矢量标记语言),以及其他一些稀奇古怪的JavaScript技巧。
Canvas本质上是一个位图画布,其上绘制的图形是不可缩放的,不能像SVG图像那样可以被放大放小。此外,用Canvas绘制出来的对象不属于页面DOM结构或者任何命名空间——这一点被认为是一个缺陷。SVG图像却可以在不同分辨率下流畅地缩放,并且支持单击检测(能检测到鼠标单击了图像上的那个点)。
既然如此,为什么WHATWG[Apple、Mozilla、Opera共同成立了WHATWG(网页超文本应用技术工作小组是一个以推动网络HTML 5 标准为目的而成立的组织),并制定Web Applications规则。这个规则就是HTML5的蓝本 ]的HTML5规范不使用SVG呢?尽管Canvas有明显的不足,但HTML Canvas API有两方面优势可以弥补:首先,不需要将所绘制图像中的每个图元当做对象存储,因此执行性能非常好;其次,在其他编程语言现有的优秀二绘图API的基础上实现Canvas API相对来说简单。
微软并没有参加WHATWG,所以Internet Explorer虽然是占有率最高的浏览器,却不支持Canvas,终于在IE9中加入了Canvas支持。
2、Canvas简介
在网页上使用Canvas元素时,它会创建一块矩形区域。默认情况下该矩形区域宽为300像素,高为150像素,但也可以自定义具体的大小或者设置Canvas的其他特性。在页面中加入canvas元素后,我们可以通过JavaScript来*的控制它。Canvas专注于线条、图像和色彩,本身并不可以做动画。如果需要实现动画,就需要使用Javascript一帧一帧的绘制。 canvas 是一个二维网格(暂不支持3维)。canvas 的左上角坐标为 (0,0)。
3、Canvas属性和方法
1)颜色、样式和阴影
属性 |
描述 |
---|---|
fillStyle | 设置或返回用于填充绘画的颜色、渐变或模式。 |
strokeStyle | 设置或返回用于笔触的颜色、渐变或模式。 |
shadowColor | 设置或返回用于阴影的颜色。 |
shadowBlur | 设置或返回用于阴影的模糊级别。 |
shadowOffsetX | 设置或返回阴影与形状的水平距离。 |
shadowOffsetY | 设置或返回阴影与形状的垂直距离。 |
方法 |
描述 |
---|---|
createLinearGradient() | 创建线性渐变(用在画布内容上)。 |
createPattern() | 在指定的方向上重复指定的元素。 |
createRadialGradient() | 创建放射状/环形的渐变(用在画布内容上)。 |
addColorStop() | 规定渐变对象中的颜色和停止位置。 |
2)线条样式
属性 | 描述 |
---|---|
lineCap | 设置或返回线条的结束端点样式。 |
lineJoin | 设置或返回两条线相交时,所创建的拐角类型。 |
lineWidth | 设置或返回当前的线条宽度。 |
miterLimit | 设置或返回最大斜接长度。 |
3)矩形
方法 | 描述 |
---|---|
创建矩形。 | |
fillRect() | 绘制"被填充"的矩形。 |
strokeRect() | 绘制矩形(无填充)。 |
clearRect() | 在给定的矩形内清除指定的像素。 |
4)路径
方法 | 描述 |
---|---|
fill() | 填充当前绘图(路径)。 |
stroke() | 绘制已定义的路径。 |
beginPath() | 起始一条路径,或重置当前路径。 |
moveTo() | 把路径移动到画布中的指定点,不创建线条。 |
closePath() | 创建从当前点回到起始点的路径。 |
lineTo() | 添加一个新点,然后在画布中创建从该点到最后指定点的线条。 |
clip() | 从原始画布剪切任意形状和尺寸的区域。 |
quadraticCurveTo() | 创建二次贝塞尔曲线。 |
bezierCurveTo() | 创建三次贝塞尔曲线。 |
arc() | 创建弧/曲线(用于创建圆形或部分圆)。 |
arcTo() | 创建两切线之间的弧/曲线。 |
isPointInPath() | 如果指定的点位于当前路径中,则返回 true,否则返回 false。 |
5)转换
方法 | 描述 |
---|---|
scale() | 缩放当前绘图至更大或更小。 |
rotate() | 旋转当前绘图。 |
translate() | 重新映射画布上的 (0,0) 位置。 |
transform() | 替换绘图的当前转换矩阵。 |
setTransform() | 将当前转换重置为单位矩阵。然后运行 transform()。 |
6)文本
属性 | 描述 |
---|---|
font | 设置或返回文本内容的当前字体属性。 |
textAlign | 设置或返回文本内容的当前对齐方式。 |
textBaseline | 设置或返回在绘制文本时使用的当前文本基线。 |
方法 | 描述 |
---|---|
fillText() | 在画布上绘制"被填充的"文本。 |
strokeText() | 在画布上绘制文本(无填充)。 |
measureText() | 返回包含指定文本宽度的对象。 |
7)图像绘制
方法 | 描述 |
---|---|
drawImage() | 向画布上绘制图像、画布或视频。 |
8)像素操作
属性 | 描述 |
---|---|
width | 返回 ImageData 对象的宽度。 |
height | 返回 ImageData 对象的高度。 |
data | 返回一个对象,其包含指定的 ImageData 对象的图像数据。 |
方法 | 描述 |
---|---|
createImageData() | 创建新的、空白的 ImageData 对象。 |
getImageData() | 返回 ImageData 对象,该对象为画布上指定的矩形复制像素数据。 |
putImageData() | 把图像数据(从指定的 ImageData 对象)放回画布上。 |
9)合成
属性 | 描述 |
---|---|
globalAlpha | 设置或返回绘图的当前 alpha 或透明值。 |
globalCompositeOperation | 设置或返回新图像如何绘制到已有的图像上。 |
10)其他
方法 | 描述 |
---|---|
save() | 保存当前环境的状态。 |
restore() | 返回之前保存过的路径状态和属性。 |
createEvent() | 创建新的 Event 对象 |
getContext() | 获得用于在画布上绘图的对象 |
toDataURL() | 导出在 canvas 元素上绘制的图像 |
4、绘制线条和矩形
语法:
ctx.stroke();//绘制已定义的路径
ctx.rect(x,y,width,height) ;//创建矩形
fillRect(x,y,width,height) ;//绘制"被填充"的矩形。
strokeRect(x,y,width,height);//绘制矩形(无填充)。
ctx.clearRect(x,y,width,height);//在给定的矩形内清除指定的像素。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<!--定义线条画布-->
<canvas id="drawCanvas" width="500" height="300"></canvas>
</body>
</html>
<script>
var canvas = document.getElementById("drawCanvas");
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext("2d");
// 绘制对角线
ctx.beginPath(); //起始一条路径,或重置当前路径。
ctx.moveTo(0,0);//把路径移动到画布中的指定点,不创建线条。
ctx.lineTo(500,300);//添加一个新点,然后在画布中创建从该点到最后指定点的线条。
//绘制矩形(只画线)
ctx.rect(300,50,100,50);
ctx.stroke();//绘制已定义的路径
//绘制填充矩形
ctx.fillRect(100,200,100,50);
//清除给定矩形内的像素
ctx.clearRect(100,200,10,10);
//绘制无填充矩形
ctx.strokeRect(100,120,100,50);
</script>
5、绘制圆弧
语法:
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
//x,y为圆心坐标,radius为半径,startAngle,endAngle为开始/结束划圆的角度,anticlockwise为是否逆时针画圆(true为逆时针,false为顺时针)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<canvas id="c1" width="150" height="150"></canvas>
<canvas id="c2" width="150" height="150"></canvas>
<canvas id="c3" width="150" height="150"></canvas>
<canvas id="c4" width="150" height="150"></canvas>
</body>
</html>
<script>
onload = function() {
draw1();
draw2();
draw3();
draw4();
};
//ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
//x,y为圆心坐标,radius为半径,startAngle,endAngle为开始/结束划圆的角度
//anticlockwise为是否逆时针画圆(true为逆时针,false为顺时针)。
/* 整个圆 */
function draw1() {
var canvas = document.getElementById('c1');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(70, 70, 60, 0, Math.PI*2, false);
ctx.stroke();
}
/* 0° ~ 90°,顺时针无填充 */
function draw2() {
var canvas = document.getElementById('c2');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(70, 70, 60, 0 * Math.PI / 180, 90 * Math.PI / 180, false);
ctx.stroke();
}
/* 0° ~ 90°,逆时针填充 */
function draw3() {
var canvas = document.getElementById('c3');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(70, 70, 60, 0 * Math.PI / 180, 90 * Math.PI / 180, true);
ctx.fill();
}
/*示意图*/
function draw4() {
var canvas = document.getElementById('c4');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(70, 70, 60, 0, Math.PI*2, false);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0,70);
ctx.lineTo(150,70);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(70,0);
ctx.lineTo(70,150);
ctx.stroke();
}
</script>
6、颜色和渐变
设置颜色:指定绘制线的颜色:ctx.strokeStyle = color、指定填充的颜色:ctx.fillStyle = color、指定透明度:ctx.globalAlpha = alpha(也可在rgba(r, g, b, tmd)中设置)。
渐变:所谓线性渐变,是指从开始地点到结束地点,颜色呈直线的徐徐变化的效果。在Canvas中,不仅可以只指定开始和结尾的两点,中途的位置也能任意指定,所以可以实现各种奇妙的效果。线性渐变使用createLinearGradient方法
,这个方法可以获得一个CanvasGradient对象,使用这个对象的addColorStop
方法添加颜色,就可以了。径向渐变使用createRadialGradient方法;
-----------------------线性渐变---------------------------
CanvasGradient = ctx.createLinearGradient(x0, y0, x1, y1)
渐变的开始地点(x0, y0),结束地点(x1, y1)指定后,返回线性渐变对象CanvasGradient。
然后我们通过addColorStop方法,offset为0的地方为开始地点的颜色,offset为1的则为结束地点的颜色。另外,很明显的,x0=x1并且y0=y1的时候,不会有渐变效果出现。
CanvasGradient.addColorStop(offset, color)
这个方法就是增加点的颜色,如果offset大于1或者小于0,会发生INDEX_SIZE_ERR异常;color可以是任何合法的CSS颜色,如果不是,则会发生SYNTAX_ERR异常。
如果offset是指定0到1之间的值,则是对应中间的比例位置。
-----------------------径向渐变---------------------------
CanvasGradient = ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
起始的圆的圆心为(x0, y0)半径为r0,终了的圆的圆心为(x1, y1)半径为r1。如果半径为负数,INDEX_SIZE_ERR异常发生,而圆心半径都相等的话,理所当然的,没有渐变效果了(相信没人会这么做的)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>颜色和渐变</title>
<style>
canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<canvas id="c1" width="150" height="150"></canvas>
<canvas id="c2" width="150" height="150"></canvas>
<canvas id="c3" width="150" height="150"></canvas>
<canvas id="c4" width="150" height="150"></canvas>
<canvas id="c5" width="150" height="150"></canvas>
</body>
</html>
<script>
onload = function() {
draw();
//纵向渐变
draw_xxjb("c2",0,150);
//横向渐变
draw_xxjb("c3",150,0);
//倾斜渐变
draw_xxjb("c4",150,150);
//径向渐变
draw_jxjb();
};
/*设置填充颜色*/
function draw() {
var canvas = document.getElementById('c1');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
// ctx.globalAlpha = 0.6;
ctx.fillStyle = 'rgba(192, 80, 77, 0.7)'; //
ctx.arc(70, 45, 35, 0, Math.PI*2, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(155, 187, 89, 0.7)'; //
ctx.arc(45, 95, 35, 0, Math.PI*2, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(128, 100, 162,0.7)'; //
ctx.arc(95, 95, 35, 0, Math.PI*2, false);
ctx.fill();
}
/*渐变*/
function draw_xxjb(id,x1,y1) {
var canvas = document.getElementById(id);
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
/* 指定渐变区域 */
var grad = ctx.createLinearGradient(0,0, x1,y1);
/* 指定几个颜色 */
grad.addColorStop(0,'rgb(192, 80, 77)'); // 红
grad.addColorStop(0.5,'rgb(155, 187, 89)'); // 绿
grad.addColorStop(1,'rgb(128, 100, 162)'); // 紫
/* 将这个渐变设置为fillStyle */
ctx.fillStyle = grad;
/* 绘制矩形 */
// ctx.rect(0,0, 150,150);
// ctx.fill();
//上面两个方法等效于这个方法
ctx.fillRect(0,0, 150,150);
}
/*径向渐变*/
function draw_jxjb() {
var canvas = document.getElementById('c5');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
/* 设定渐变区域 */
var grad = ctx.createRadialGradient(75,75,20,75,75,75);
/* 设定各个位置的颜色 */
grad.addColorStop(0,'red');
grad.addColorStop(0.5,'yellow');
grad.addColorStop(1,'blue');
ctx.fillStyle = grad;
/* 还是画一个矩形! */
ctx.rect(0,0, 150,150);
// ctx.arc(75,75, 75, 0, Math.PI*2);
ctx.fill();
}
</script>
7、阴影和变形(移动)
对canvas中特定元素的旋转平移等操作实际上是对整个画布进行了操作,所以如果不对canvas进行save以及restore,那么每一次绘图都会在上一次的基础上进行操作,最后导致错位。
阴影语法:
shadowOffsetX : 阴影的横向位移量(默认值为0)
shadowOffsetY : 阴影的纵向位移量(默认值为0)
shadowColor : 阴影的颜色
shadowBlur : 阴影的模糊范围(值越大越模糊)
图形变形语法:
translate(x,y): 平移 x:坐标原点向x轴方向平移x y:坐标原点向y轴方向平移y
scale(x,y): 缩放 x:x坐标轴按x比例缩放 y:y坐标轴按y比例缩放
rotate(angle): 旋转 angle:坐标轴旋转x角度
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>阴影和平移</title>
<style>
canvas{border:1px dashed black;}
</style>
</head>
<body>
<canvas id="c1" width="150" height="150"></canvas>
<canvas id="c2" width="150" height="150"></canvas>
</body>
</html>
<script>
onload = function() {
draw();
changeGraph();
}
function draw() {
var canvas = document.getElementById('c1');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.fillStyle = 'rgba(192, 80, 77,0.95)'; //设置图形颜色红色
ctx.shadowOffsetX = 10; // 设置水平位移
ctx.shadowOffsetY = 45; // 设置垂直位移
ctx.shadowBlur = 5; // 设置模糊度:数值越高,模糊程度越大
ctx.shadowColor = "rgba(0,0,0,0.3)"; // 设置阴影颜色
ctx.arc(70, 45, 35, 0, Math.PI*2, false);
ctx.fill();
}
//平移
function changeGraph() {
var canvas = document.getElementById("c2");
if ( ! canvas || ! canvas.getContext ) { return false; }
var context = canvas.getContext('2d');
context.save(); //保存了当前context的状态
context.fillStyle ='rgba(128, 100, 162,0.7)';//紫色
context.fillRect(0, 0, 150, 150);
context.fillStyle = "rgba(255,0,0,0.5)";//红色
//平移
context.translate(75, 75);
// 缩放
context.scale(0.5, 0.5);
//旋转
context.rotate(Math.PI / 4);
context.fillRect(0, 0, 50, 50);
context.restore(); //恢复到刚刚保存的状态(就是恢复到上一个调用context.save()的状态时候的所有属性)
context.save(); //保存了当前context的状态(再次保存这个状态)
//移动的是坐标轴、缩放的是坐标轴比例、旋转的是坐标轴、平移 缩放 旋转 三者的顺序不同都将画出不同的结果
context.fillStyle = "rgba(255,0,0,0.5)";//红色
//平移
context.translate(50, 50);
// 缩放
context.scale(0.5, 0.5);
//旋转
context.rotate(Math.PI / 4);
context.fillRect(0, 0, 50, 50);
//save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。
//restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。
//如果注释掉则相当于在上一个状态下再次平移,就不会在一条线上
context.restore(); //恢复到刚刚保存的状态
context.save(); //保存了当前context的状态
context.fillStyle = "rgba(255,0,0,0.5)";//红色
//平移
context.translate(25, 25);
// 缩放
context.scale(0.5, 0.5);
//旋转
context.rotate(Math.PI / 4);
context.fillRect(0, 0, 50, 50);
}
</script>
扩展:保存和恢复
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>保存恢复</title>
<style>
canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<canvas id="c1" width="150" height="150"></canvas>
</body>
</html>
<script>
onload=function(){
saveAndRestore();
}
function saveAndRestore() {
var canvas = document.getElementById("c1");
if (canvas == null) {
return false;
}
var context = canvas.getContext('2d');
context.fillStyle = "red";
context.save(); //保存了当前context的状态(保存未设置的红色)
context.fillStyle = "black";//现在使用黑色填充
context.fillRect(0, 0, 150, 100);
context.restore();//恢复到刚刚保存的状态(恢复到了红色属性的状态)
context.fillRect(0,120,150,150);//填充的是之前保存的红色
}
</script>
8、贝塞尔曲线
贝塞尔曲线于1959年,由法国物理学家与数学家Paul de Casteljau所发明,于1962年,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,并用于汽车的车身设计。贝赛尔曲线为计算机矢量图形学奠定了基础,它的主要意义在于无论是直线或曲线都能在数学上予以描述。贝塞尔曲线分为两种:二次贝塞尔曲线和三次贝塞尔曲线。
quadraticCurveTo()方法绘制二次贝塞尔曲线:二次贝塞尔曲线是一种二次曲线,它只能向一个方向弯曲,由三个点来定义:两个锚点及一个控制点,控制点用来控制曲线的形状。由于二次贝塞尔曲线只有一个控制点,所以它永远只能画向一个方向弯曲的弧线,画不出S形曲线。要绘制S形曲线,还需要使用三次贝塞尔曲线。
bezierCurveTo()方法绘制三次贝塞尔曲线:三次贝塞尔曲线是一种三次曲线,由四个点来定义:两个锚点及两个控制点,两个控制点用来控制曲线的形状。
贝塞尔二次曲线:quadraticCurveTo(controlX, controlY, endingPointX, endingPointY)
以下实例使用quadraticCurveTo(cpx,cpy,x,y)方法来绘制一条二次曲线,其中,起点是由上下文维护,控制点为(cpx,cpy),终点为(x,y)。
贝塞尔三次曲线:bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endPointX, endPointY)
以下实例使用bezierCurveTo(cp1x,cp1y, cp2x,cp2y,x,y)方法来绘制一条二次曲线,其中,起点是由上下文维护,控制点为(cp1x,cp1y)和(cp2x,cp2y),终点为(x,y)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>贝塞尔曲线</title>
<style>
canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<canvas id="c1" width="150" height="150"></canvas>
<canvas id="c2" width="150" height="150"></canvas>
</body>
</html>
<script>
onload=function(){
draw_bse2();
draw_bse3();
}
/*贝塞尔二次曲线*/
function draw_bse2() {
var canvas = document.getElementById("c1");
if ( ! canvas || ! canvas.getContext ) { return false; }
var context = canvas.getContext("2d");
context.moveTo(20, 30);
context.quadraticCurveTo(150,60,20,100);
context.strokeStyle='blue';
context.stroke();
}
/*贝塞尔三次曲线*/
function draw_bse3() {
var canvas = document.getElementById("c2");
if ( ! canvas || ! canvas.getContext ) { return false; }
var context = canvas.getContext("2d");
//设置线条宽度
context.lineWidth = 10;
context.beginPath();
context.moveTo(30, 30);//设置起点
//控制点(65,95)(125,25)终点(140,90)
context.bezierCurveTo(65, 95, 125, 25,140,90);
context.strokeStyle='blue';
context.stroke();
}
</script>
9、绘制文字
语法:
填充文字:fillText(text,x,y)
绘制文字轮廓: strokeText(text,x,y)
计算字体长度(px): measureText(text)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>设置字体</title>
<style>
canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<canvas id="c1" width="240" height="240"></canvas>
</body>
</html>
<script>
onload=function(){
drawText();
}
function drawText() {
var canvas = document.getElementById("c1");
if ( ! canvas || ! canvas.getContext ) { return false; }
var context = canvas.getContext('2d');
//设置地图颜色
context.fillStyle = "#EEEEFF";
context.fillRect(0,0,400,300);
context.fillStyle = "#00f";
//文本内容的当前字体属性(默认:10px sans-serif)
context.font = "italic 30px sans-serif";
//填充字符串
var txt="填充示例文字";
context.fillText(txt, 0, 30);
//txt文字的长度,context.measureText(txt)返回对象,包含宽度属性
var length=context.measureText(txt);
context.fillText("长" + length.width + "px", 0, 80);
//设置为粗体
context.font = "bolid 30px sans-serif";
txt = "填充示例文字";
length = context.measureText(txt);
context.strokeText(txt,0,130);
context.fillText("长" + length.width + "px", 0, 180);
//设置渐变字体
context.font="30px Verdana";
txt ="Big smile!";
length = context.measureText(txt);
var gradient=context.createLinearGradient(0,200,length.width,length.width);
gradient.addColorStop("0","red");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1","magenta");
// 填充一个渐变
context.fillStyle=gradient;
context.fillText(txt,0,220);
}
</script>
10、图形组合
语法:
globalCompositeOperation=type
使用说明:
source-over(默认值):在原有图形上绘制新图形
destination-over:在原有图形下绘制新图形
source-in:显示原有图形和新图形的交集,新图形在上,所以颜色为新图形的颜色
destination-in:显示原有图形和新图形的交集,原有图形在上,所以颜色为原有图形的颜色
source-out:只显示新图形非交集部分
destination-out:只显示原有图形非交集部分
source-atop:显示原有图形和交集部分,新图形在上,所以交集部分的颜色为新图形的颜色
destination-atop:显示新图形和交集部分,新图形在下,所以交集部分的颜色为原有图形的颜色
lighter:原有图形和新图形都显示,交集部分做颜色叠加
xor:重叠飞部分不现实
copy:只显示新图形
测试案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图形组合及绘制五角星</title>
<style>
canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<canvas id="c1" width="150" height="150"></canvas>
</body>
</html>
<script>
var canvas = document.getElementById("c1");
if ( ! canvas || ! canvas.getContext ) { return false; }
var context = canvas.getContext("2d");
//开始绘制圆
context.fillStyle = "#FFFF00";
context.arc(75, 75, 50, 0, Math.PI*2, false);
context.fill();
//显示新图形和交集部分,新图形在下,所以交集部分的颜色为原有图形的颜色
// context.globalCompositeOperation="destination-atop";//黄色五角星
//只显示原图非叠加部分
// context.globalCompositeOperation="destination-out";//圆中被挖掉了个白色的五角星("xor"效果同)
//显示原有图形和新图形的交集
// context.globalCompositeOperation="source-in";//只有红色五角星
//在原图上画五角星
context.globalCompositeOperation="source-over";//默认值
//开始绘制五角星
context.beginPath();
for(var i = 0; i < 5; i++) {
//根据余弦计算X坐标Math.cos(angle) * r;Math.sin(angle) * r;//根据正弦计算y坐标 外五点半径50
context.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI) * 50 + 75, -Math.sin((18 + i * 72) / 180 * Math.PI) * 50 + 75);
//内半径20
context.lineTo(Math.cos((54 + i * 72) / 180 * Math.PI) * 20 + 75, -Math.sin((54 + i * 72) / 180 * Math.PI) * 20 + 75);
}
context.closePath();
//设置边框样式以及填充颜色
context.fillStyle = "red";
//线条设置为白色
context.strokeStyle = "wheat";
context.fill();
context.stroke();
</script>
11、绘制图像
drawImage() 方法用于在画布上绘制图像、画布或视频,也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸。
语法:
在画布上定位图像:drawImage(image,x,y)
x:绘制图像的x坐标
y:绘制图像的y坐标
在画布上定位图像,并规定图像的宽度和高度:drawImage(image,x,y,w,h)
x:绘制图像的x坐标
y:绘制图像的y坐标
w:绘制图像的宽度
h:绘制图像的高度
剪切图像,并在画布上定位被剪切的部分:drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)
sx:图像上的x坐标
sy:图像上的y坐标
sw:矩形区域的宽度
sh:矩形区域的高度
dx:画在canvas的x坐标
dy:画在canvas的y坐标
dw:画出来的宽度
dh:画出来的高度
案例1:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>绘图</title>
<style>
canvas{
border:1px dashed black;
}
#tp{
border:1px dashed black;
width: 501px;
height: 589px;
float: left;
}
#jtdx{
width: 150px;
height: 200px;
border:1px dashed red;
margin-left: 100px;
margin-top: 30px;
position: absolute;
color: red;
}
</style>
</head>
<body>
<div id="tp">
<img src="img/ht.jpg">
</div>
<!--截图起点(100,30)绘图范围[150,200]矩形大小的范围-->
<div id="jtdx">画布3绘图范围</div>
<!--原图片500*588-->
画布1<canvas id="c1" width="150" height="200"></canvas>
画布2<canvas id="c2" width="150" height="200"></canvas>
画布3<canvas id="c3" width="150" height="200"></canvas>
</body>
</html>
<script>
onload = function() {
draw();
draw_dx();
draw_jb();
}
//drawImage()方法绘图
function draw() {
//获取Canvas对象(画布)
var canvas = document.getElementById("c1");
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext("2d");
//创建新的图片对象
var img = new Image();
//指定图片的URL:原图片500*588
img.src = "img/ht.jpg";
//浏览器加载图片完毕后再绘制图片
img.onload = function(){
//以Canvas画布上的坐标(0,0)为起始点,绘制图像
ctx.drawImage(img, 0, 0);
}
}
//指定大小绘图
function draw_dx() {
//获取Canvas对象(画布)
var canvas = document.getElementById("c2");
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext("2d");
//创建新的图片对象
var img = new Image();
//指定图片的URL:原图片500*588
img.src = "img/ht.jpg";
//浏览器加载图片完毕后再绘制图片
img.onload = function(){
//以Canvas画布上的坐标(0,0)为起始点,绘制图像
ctx.drawImage(img, 0, 0,150,200);
}
}
//局部绘图
function draw_jb() {
//获取Canvas对象(画布)
var canvas = document.getElementById("c3");
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext("2d");
//创建新的图片对象
var img = new Image();
//指定图片的URL:原图片500*588
img.src = "img/ht.jpg";
//浏览器加载图片完毕后再绘制图片
img.onload = function(){
//以Canvas画布上的坐标(100,30)为起始点,截[150,200]矩形,放到(0,0)开始到[150,200]的画布中
ctx.drawImage(img, 100, 30,150,200,0,0,150,200);
}
}
</script>
案例2:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#c1{
box-shadow: 0 0 5px gold;
}
</style>
</head>
<body>
<canvas id="c1" width="500" height="280"></canvas>
<video width="500" height="280" id="video">
<source src="video/cs.mp4" type="video/mp4" preload="auto"></source>
</video>
</body>
</html>
<script>
var canvas = document.getElementById("c1");
var ctx = canvas.getContext("2d");
var video = document.getElementById("video");
//当浏览器能够开始播放指定视频或者音频时触发
video.oncanplay = function(){
video.play();
//绘制方法
function drawVideo(){
//绘制到画布
ctx.drawImage(video,0,0,500,280);
//延时定时器功能类似,但是没有延迟
/*
requestAnimationFrame:可以使动画绘制和浏览器自身绘制频率保持一致
* */
window.requestAnimationFrame(drawVideo);
}
drawVideo();
};
</script>
12、保存文件
在canvas中绘出的图片只是canvas标签而已,且有些浏览器(比如IE11)并不支持,右键保存图片(火狐谷歌支持)。我们可以利用canvas.toDataURL()这个方法把canvas绘制的图形生成一幅图片,生成图片后,就能对图片进行相应的操作了。
语法:
canvas.toDataURL(type, encoderOptions);
type默认:image/png
encoderOptions可选:在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值0.92
案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>IE绘图和保存图片</title>
<style>
#im,canvas{
border:1px dashed black ;
}
</style>
</head>
<body>
<canvas id="c1" width="150" height="150"></canvas>
<img id="im" width="150" height="150"/>
</body>
</html>
<script>
onload = function() {
draw();
toimg();
};
/*设置填充颜色*/
function draw() {
var canvas = document.getElementById('c1');
if ( ! canvas || ! canvas.getContext ) { return false; }
var ctx = canvas.getContext('2d');
ctx.beginPath();
// ctx.globalAlpha = 0.6;
ctx.fillStyle = 'rgba(192, 80, 77, 0.7)'; //
ctx.arc(70, 45, 35, 0, Math.PI*2, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(155, 187, 89, 0.7)'; //
ctx.arc(45, 95, 35, 0, Math.PI*2, false);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(128, 100, 162,0.7)'; //
ctx.arc(95, 95, 35, 0, Math.PI*2, false);
ctx.fill();
}
//设置到img标签中
function toimg(){
var canvas = document.getElementById('c1');
if ( ! canvas || ! canvas.getContext ) { return false; }
var base64 = canvas.toDataURL();
console.log(base64);
var img = document.getElementById('im');
img.src=base64;
}
</script>