HTML5详细介绍及使用-程序员宅基地

技术标签: 原创未经允许不得转载  html5  # html学习板块  我的前端学习板块  

                                                                 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。

  a)autocompletenovalidate属性

<!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

leftrighttopmiddle

、bottom

不赞成使用。规定图像输入的对齐方式。
alt text 定义图像输入的替代文本。
autocomplete

onoff

(新增)规定是否使用输入字段的自动完成功能。(会记住之前提交的记录,利与快速填写
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

getpost

(新增)覆盖表单的 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

numberdate

(新增)规定输入字段的最大值。

请与 "min" 属性配合使用,来创建合法值的范围。

maxlength number 规定输入字段中的字符的最大长度。
min

numberdate

(新增)规定输入字段的最小值。

请与 "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、部分新增元素及属性

1)<progress><meter>

元素/属性 说明
<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)矩形

方法 描述

rect()

创建矩形。
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

案例1:

<!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>

    

案例2:下载图片

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>绘图</title>
		<style>
			canvas{
				border:1px dashed black;
			}
			#tp{
				border:1px dashed black;
				width: 150px;
				height: 200px;
				position:absolute;
				top:0px; left:0;
			}
			#yt,#sct{
				width: 150px;
				height: 200px;
			}
			#hb{
				position:absolute;
				top:0px; 
				left:151px;
			}
			#sc{
				border:1px dashed black;
				width: 150px;
				height: 200px;
				position:absolute;
				top:0px; 
				left:302px;
			}
			#save{
				position:absolute;
				top:230px; 
				left:0px;
			}
		</style>
	</head>
	<body>
		<div id="tp">
			<img id="yt" src="img/ht.jpg">
			<div id="bz">原图img标签</div>
		</div>
		<!--截图起点(100,30)绘图范围[150,200]矩形大小的范围-->
		<!--原图片500*588-->
		<div id="hb">
			<canvas id="c2" width="150" height="200"></canvas>
		    <div id="bz1">画布canvas标签</div>
		</div>
	    <div id="sc">
	    	<img id="sct"/>
	    	<div id="bz1">生成的图片</div>
	    </div>
	    <button id="save">保存</button>
	</body>
</html>
<script>
	onload = function() {
	  draw_dx();
	  sctp();  //放在这加载会存在异步问题,获取的图片为空白
	}
	//指定大小绘图
	function draw_dx() {
		//获取Canvas对象(画布)
	    var canvas = document.getElementById("c2");
	    if ( ! canvas || ! canvas.getContext ) { return false; }
		var ctx = canvas.getContext("2d");
	    //创建新的图片对象
	    var img = new Image();
	    img.src = "img/ht.jpg";
	    img.setAttribute('crossOrigin', 'anonymous');
	    img.onload = function(){
	    //以Canvas画布上的坐标(0,0)为起始点,绘制图像
	        ctx.drawImage(img, 0, 0,150,200);
	    }
	}
	//放在onload加载会存在异步问题,获取的图片为空白
	function sctp(){
		var canvas = document.getElementById("c2");
		if ( ! canvas || ! canvas.getContext ) { return false; }
		var base64Str = canvas.toDataURL("image/png");
		console.log(base64Str);
		var sct = document.getElementById("sct");
		sct.src=base64Str;
	}
	
	var canvas = document.getElementById("c2");
	document.getElementById("save").onclick = function (){
		sctp();
	    downLoad(saveAsPNG(canvas));
	}
 
	// 保存成png格式的图片
	function saveAsPNG(canvas) {
		console.log("==="+canvas.toDataURL("image/png"));
	    return canvas.toDataURL("image/png");
	}
	 
	// 保存成jpg格式的图片
	function saveAsJPG(canvas) {
	    return canvas.toDataURL("image/jpeg");
	}
	 
	// 保存成bmp格式的图片  目前浏览器支持性不好
	function saveAsBMP(canvas) {
	    return canvas.toDataURL("image/bmp");
	}
	 
	/**
	 * @author web得胜
	 * @param {String} url 需要下载的文件地址
	 * */
	function downLoad(url){
		console.log(url);
	    var oA = document.createElement("a");
	    oA.download = '';// 设置下载的文件名,默认是'下载'
	    oA.href = url;
	    document.body.appendChild(oA);
	    oA.click();
	    oA.remove(); // 下载之后把创建的元素删除
	}
</script>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xiaoxianer321/article/details/110132484

智能推荐

计算机科学与技术本科人才培养目标,计算机科学与技术本科人才培养探索-程序员宅基地

文章浏览阅读199次。[摘要]信息技术发展日新月异,高校计算机专业教育重知识轻实践的人才培养观念与培养模式亟待改革。积极致力于计算机科学与技术本科专业创新应用型人才培养的探索与实践,在“厚基础、宽口径、重实践、求创新”的教育理念指导下,改革培养模式、优化课程体系、夯实教学团队、强化实践环节,打造一支教学科研能力强、结构合理的高水平师资队伍,构建较为科学的人才培养模式和课程体系,培养一批综合素质和核心竞争力强的创新应用型..._探索建立“厚基础、重实践、能创新、擅实战”的高端应用型人才培养模式

node.js和php对比之下,前端人员学那个更好?_nodejs代替php-程序员宅基地

文章浏览阅读2.8k次,点赞4次,收藏4次。浅谈nodejs和php现在,Web开发公司和开发人员可以选择多种技术栈来构建Web应用程序。早期网络发展,不同的技术被用于前端和后端开发。但是,随着Node.js的发布,布局发生了变化,因为它允许开发人员使用 JavaScript 编写后端代码。这最终催生了MEAN(MongoDB + Express +AngularJS + NodeJS )堆栈 web 开发框架,从前端到后端甚至是数据库(MongoDB -JSON)都使用 JavaScript。在 Node.js 之前,Web 开发通常是在 PHP_nodejs代替php

微信小程序云开发云函数总结_c# wx.cloud.init-程序员宅基地

文章浏览阅读2.6k次,点赞5次,收藏24次。1、小程序创建项目时选择云开2、创建进入小程序后选择云开在设置中创建配置环境在小程序中cloudfunctions文件下选择创建的环境并创建nodejs云函数,在每个云函数下的index.js中进行编译3、login云函数创建项目后自动生成只需要上传部署就行4、新增数据云函数// 云函数入口文件const cloud = require('wx-server-sdk')..._c# wx.cloud.init

将centos7打造成桌面系统centos-程序员宅基地

文章浏览阅读3.5k次。2019独角兽企业重金招聘Python工程师标准>>> ..._centos7 palemoon

理解PHP及Zend Engine的线程安全模型(ZTS)_php zts 哪里定义的-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏6次。在阅读PHP源码和学习PHP扩展开发的过程中,我接触到大量含有“TSRM”字眼的宏。在查找资料过程中发现有2篇文章写的不错,整理如下:深入研究PHP及Zend Engine的线程安全模型:http://blog.codinglabs.org/articles/zend-thread-safety.htmlPHP源码分析之线程安全模型:http://blog.csdn.net/h_php zts 哪里定义的

详解oracle delete和truncate的区别_delete rollba-程序员宅基地

文章浏览阅读185次。语法 delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以。2.delete from记录是一条条删的,所删除的每行记录都会进日志,而truncate一次性删掉整个页,因此日至里面只记录页释放,简言之,delete from更新日志,truncate基本不,所用的事务日志空间较少。3.delete from_delete rollba

随便推点

Captcha must be filled out解决_captcha must be filled out.-程序员宅基地

文章浏览阅读1.4w次,点赞30次,收藏36次。今天注册kaggle时发现没有显示人机验证的选项,而是Captcha must be filled out的红字。然后就去网上搜索,找了一番之后终于解决。保存之后去规则列表查看可以检查是否成功,成功的应该是有上面三条的。就是这样的,因为前面下载过了所以显示覆盖已有,之前没有下载过会显示 添加。然后关闭这个页面,在kaggle注册页面刷新就可以出现人机验证了。不过我搜索第二个没有成功,搜索第一个成功的。_captcha must be filled out.

Python3:《机器学习实战》之支持向量机(4)核函数及其实现_头歌机器学习支持向量机第四关核函数-程序员宅基地

文章浏览阅读1w次,点赞9次,收藏44次。Python3:《机器学习实战》之支持向量机(4)核函数及其实现转载请注明作者和出处:http://blog.csdn.net/u011475210代码地址:https://github.com/WordZzzz/ML/tree/master/Ch06操作系统:WINDOWS 10软件版本:python-3.6.2-amd64编  者:WordZzzz_头歌机器学习支持向量机第四关核函数

live555: The input frame data was too large for our buffer size 解决方法_multiframedrtpsink::aftergettingframe1(): the inpu-程序员宅基地

文章浏览阅读7.1k次。在做live555 直播的时候,输入的图片尺寸是320*240 的时候,live555 输出的RTSP数据流可以正常解码,运行没有出现异常现象,但是把图片尺寸改为640*480的时候,就出现了问题: MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer ..._multiframedrtpsink::aftergettingframe1(): the input frame data was too large

java RMI 技术介绍和实践_rmi请求-程序员宅基地

文章浏览阅读214次。RMI 基本思想是远程方法调用,即客户端调用某个方法,其本质是将这个方法的调用请求,发送给服务器,由服务器代为执行,且,服务器将执行结果回送客户端。对于客户端而言,RMI 只要求客户端针对方法本身,产生一种错觉:方法是在本地被调用的;对于服务器而言,RMI 相当于要处理一个来自客户端的“请求”;这个请求针对某个方法。_rmi请求

JVM对象实例化过程_jvm中对象的实例化过程-程序员宅基地

文章浏览阅读1.6k次。JVM对象的实例化从字节码文件看创建对象的过程判断对象对应的类是否加载、链接、初始化虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化。如果没有,那么在双亲委派模式下,使用当前类加载器已ClassLoader+包名+类名为Key进行查找对应的.class文件。如果没有找到文件,则抛出ClassNotFoundException异常,如果找到,则进行类加载,并生成对应的Class类对象_jvm中对象的实例化过程

XAMPP 安装_xampp fake sendmail-程序员宅基地

文章浏览阅读687次。XAMPP是一个易于安装且包含MySQL、PHP和Perl的建站集成软件包。XAMPP中文版软件操作简单,功能强大,我们只需要在本站下载解压后就可以安装使用。XAMPP软件支持不同的版本以及语言,帮助大家快速简便的建立服务器。华军软件园为您提供xampp中文版官方下载。xampp中文版软件特色  XAMPP此版本由phpStudy作者重新编译,精简掉五分之四,安装包只有35M。..._xampp fake sendmail

推荐文章

热门文章

相关标签