HTML5是HTML最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定。
HTML5的设计目的是为了在移动设备上支持多媒体。HTML5是唯一一个通吃PC、MAC、Iphone、Android等主流平台的跨平台语言。
HTML5 中的一些有趣的新特性:
- 用于绘画的 canvas 元素
- 用于媒介回放的 video 和 audio 元素
- 对本地离线存储的更好的支持
- 新的特殊内容元素,比如 article、footer、header、nav、section
- 新的表单控件,比如 calendar、date、time、email、url、search
目录
9.2 data数据(color/alpha) 像素点 像素点坐标的关系
一、HTML5 基础
1. attribute和property属性
1)html预定义属性和自定义属性 统称为 attribute;property:JS原生对象的直接属性;每个预定义的attribute都会有一个property与之对应
2)property的属性值是布尔值类型的,称为布尔值属性;property的属性值是非布尔值类型的,称为非布尔值属性
3)非布尔值属性:不管什么情况attribute和property都同步;
布尔值属性:①改变property时,不会同步attribute;②在没有动过property时,attribute会同步property;③一旦动过property,attribute不会同步property
4)浏览器只认property,用户操作的是property
5)布尔值属性最好使用prop方法,非布尔值属性attr方法
2. H5的 DOCTYPE和浏览器渲染模式
DOCTYPE即Document Type Declaration(文档类型声明,缩写DTD),通常情况下位于一个HTML文档的最前面位置,位于根元素HTML的其实标签之前,因为浏览器必须在解析HTML正文之前就确定当前文档的类型,以决定其需要采用的渲染模式。不同的渲染模式会影响浏览器对于CSS和JS脚本的解析。
* document.compatMode属性最初由微软在IE中创造出来,是一个只读属性,返回一个字符串,只可能存在两种返回值:
BackCompat:标准兼容模式未开启(怪异模式)
CSS1Compat:标准兼容模式已开启(标准模式)
现在主流浏览器中两种模式差别不大,但IE9之前有区别
二、H5中的小功能
1. classlist
相当于class的property(className) 方法:add() remove() toggle()
2. 自定义属性
dataset:自定义属性(限制data-x-y)的property 注意:名字中有 - 要改为驼峰命名
3. 可编辑属性
contenteditable
三、语义化标签
1. 什么是语义化标签
在HTML5出来之前,我们用div表示页面的头部、章节、页脚等,但div没有实际意义。所谓语义化标签,顾名思义是赋予了标签自己的含义。
2. 常见的语义化标签
1) <header> 头部标签:代表网页或section的页眉,通常包含h1-h6元素或group
hgroup:当元素有多个层级时,该元素可以将h1-h6元素放在其内,譬如文章的主标题和副标题的组合; header使用没有个数限制
如果只需要一个h1-h6标签就不用hgroup,如果有连续多个就用hgroup,如果有连续多个标题和其他文章数据,h1-h6标签就用hgroup包住,和其他文章数据一起放入header标签
2)<nav> 导航标签:代表页面的导航连接区域,用于定义页面的主要导航部分;
注意:用在整个页面主要导航部分上,不合适就不要用nav元素
3)<article> 内容标签:代表一个在文档,页面或网站中自成一体的内容。
注意:独立文章:article 单独的模块:section 没有语义的:div
4)<aside> 侧边栏标签:包含在article之中作为主要内容的附属信息部分,其内容可以是与当前文章有关的相关资料、标签、名词解释等;在article之外使用作为页面或站点全局的附属信息部分,最典型的是侧边栏,如侧栏、文章的一组链接、广告、友情链接、相关产品列表等。
5)<footer> 尾部标签:页脚,只有当父级是body时,才是整个页面的页脚。
四、canvas元素
1. canvas的基本用法
1.1什么是canvas(画布)
<canvas>是HTML5新增的元素,可用于通过使用JavaScript中的脚本来绘制图形,例如它可以用来绘制图形,创建动画。<canvas>最早由Apple引入WebKit。我们可以使用<canvas>标签来定义一个canvas元素。
1.2 canvas标签的两个属性
<canvas>和<img>元素很像,但没有src和alt属性,实际上<canvas>只有两个属性- width和height,当没有设置宽度和高度的时候,canvas会初始化宽度为300像素和高度为150像素。
画布的宽高:
html属性设置的width height 只影响画布本身不影响画布内容
css属性设置width height 不但会影响画布本身的高度,还会使画布中的内容等比例缩放(缩放参照于画布默认的尺寸)
1.3 渲染上下文
<canvas>只是创造了一个固定大小的画布,要想在它上面去绘制内容,我们需要找到它的渲染上下文;<canvas>有一个叫getContext()的方法,是用来获得渲染上下文和它的绘画功能。getContext()只有一个参数,上下文的格式:
var canvas=document.getElementById("#box"); var ctx=canvas.getContext("2d");
2. 绘制矩形
HTML中的元素canvas只支持一种原生的图形绘制:矩形。所有其他的图形绘制都至少需要生成一条路径。 canvas提供了3种绘制矩形的方法:
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
/*canvas 性能极高,同步思维~ 必须先设置样式颜色、边框、宽度等,
读到就画,极快,所见即所得;覆盖渲染*/
// 图形填充颜色
ctx.fillStyle="deeppink";
// 图形边框颜色 默认情况下,线条和填充颜色都是黑色(css颜色值#000000)
ctx.strokeStyle="red";
// 当前绘线的粗细 属性值必须为正数
ctx.lineWidth=50;
// 线条接合处的样式:斜角bevel 圆角round 直角miter(默认)
ctx.lineJoin="bevel";
// 注意不加单位
// 绘制一个填充的矩形(填充色默认为黑色)fillRect(x,y,width,height)
ctx.fillRect(0,0,100,100);
// 绘制一个带边框的矩形(默认边框为一个像素实心黑色)
// 100 : 99.5---100.5(99-101)
// 100.5:100---101
ctx.strokeRect(100,100,100,100);
// 清除指定矩形区域,让清除部分完全透明
ctx.clearRect(100,100,100,100);
}
}
</script>
注意:css没能力介入画布上的任何元素,只能用画布自己的api
3. 绘制路径
图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合
步骤:
① 创建路径起始点 beginpath()新建一条路径
② 使用画图命令画出路径
moveTo(x,y) 将笔触移动到指定的坐标x及y上,当canvas初始化或者beginpath()调用后,你通常会使用moveTo()函数设置起点;
lineTo(x,y)绘制一条从当前位置到指定x及y位置的直线。
③ 把路径封闭 closePath() 闭合路径
这个方法会通过绘制一条从当前点到开始点的直线来闭合图形,如果图形已经是闭合的,则该函数无用;
当调用fill()函数时,所有没有闭合的形状都会自动闭合,则不用closePath,但stroke()不会
④ 一旦路径形成,你就能通过描边或填充路径区域来渲染图形
1)绘制矩形
rect (x,y,width,height) 绘制一个左上角坐标为(x,y),宽高为width和height的矩形,该方法执行时,moveTo()方法自动设置坐标参数(0,0) ,也就是说当前笔触自动重置为默认坐标。
2)lineCap
lineCap是canvas 2D API 指定如何绘制每一条线段末端的属性,有3个值,分别是:
butt:线段末端以方形结束(默认值)
round:线段末端以圆形结束(两端增加一个半圆)
square:线段末端以方形结束(增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域
3)save()
save()是canvas 2D API 通过将当前的状态放入栈中,保存canvas全部状态的方法
4)restore()
restore() 是canvas 2D API 通过在绘图状态栈中弹出顶端的状态,将canvas恢复到最近的保存状态的方法,如果没有保存状态,此方法不作任何改变。
路径容器:每次调用路径api是,都会往路径容器里登记,调用beginPath时,清空整个路径容器。
样式容器:每次调用样式api时,都会往样式容器里做登记,调用save时将容器里的状态压入样式栈,调用restore时,将样式栈的栈顶状态弹出到样式容器里进行覆盖。
样式栈:调用save时将样式容器里的状态压入样式栈,调用restore时,将样式栈的栈顶状态弹出到样式容器里进行覆盖。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background-color: pink;
}
#test{
background-color: gray;
position:absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
</head>
<body>
<canvas id="test" width="300" height="300">
</canvas>
</body>
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
// 绘制三角形
ctx.strokeStyle="deeppink";
ctx.fillStyle="green";
ctx.lineWidth=8;
ctx.moveTo(100,100); // 抬起画笔
ctx.lineTo(100,200);
ctx.lineTo(200,200);
ctx.lineTo(100,100); // 回到初始点闭合
ctx.closePath(); // 或者直接用合并路径
ctx.stroke(); // stroke如果写在closePath上面也不行,要先闭合再加边框
ctx.beginPath();//清空路径容器,不影响下面的路径
ctx.moveTo(200,200);
ctx.lineTo(200,300);
ctx.lineTo(300,300);
ctx.fill();// fill方法会自动调用closePath合并路径,但stroke不会自动调用closePath
// 绘制矩形
ctx.rect(200,0,100,100);
ctx.fill();
ctx.stroke();
// lineCap
ctx.lineCap="round"; // 每条线段末端的属性值:butt:线段末端以方形结束(默认) round:线段末端以圆形结束(两端增加一个半圆) square:线段末端以方形结束(增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域
ctx.moveTo(20,50);
ctx.lineTo(20,100);
ctx.stroke();
}
}
</script>
</html>
4. 绘制曲线
角度与弧度的JS表达式: radians=(Math.PI/180)*degrees
arc (x, y, radius, startAngle, endAngle, anticlockwise) 画一个以(x, y) 为圆心,以radius为半径的圆弧(圆),从startAngle开始 到 endAngle结束(这些都是以X轴为基线),按照 anticlockwise (布尔值)给定的方向(默认顺时针)来生成。 true:逆时针 false:顺时针
arcTo(x1, y1, x2, y2,radius) 根据给定的控制点和半径画一段圆弧,肯定会从(x1,y1)经过,但不一定经过(x2, y2),(x2, y2)只是控制一个方向。
二次贝塞尔 quadraticCurveTo(cp1x, cp1y, x, y) cplx,cply为一个控制点,x,y为结束点,起始点为moveTo时指定的点
三次贝塞尔 bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) cp1x,cp1y为控制点1,cp2x,cp2y为控制点2,x,y为结束点,起始点为moveTo时指定的点
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
// 圆弧(圆)
ctx.beginPath();
ctx.moveTo(100,100);
ctx.arc(100,100,50,0,270*Math.PI/180);
ctx.closePath();
ctx.stroke();
ctx.save();
ctx.beginPath();
ctx.moveTo(50,50)
ctx.lineTo(300,0);
ctx.lineTo(200,200);
ctx.stroke();
// arcTo 根据给定的控制点和半径画圆弧
ctx.save();
ctx.moveTo(50,50);
ctx.arcTo(300,0,200,200,50);
// ctx.closePath();
ctx.stroke();
// 二次贝塞尔
ctx.save();
ctx.beginPath();
ctx.moveTo(50,50)
ctx.lineTo(300,0);
ctx.lineTo(200,200);
ctx.stroke();
// ctx.save();
ctx.beginPath();
ctx.moveTo(50,50);
ctx.quadraticCurveTo(300,0,200,200);
// ctx.closePath();
ctx.stroke();
// 三次贝塞尔
ctx.save();
ctx.beginPath();
ctx.moveTo(50,50)
ctx.lineTo(300,0);
ctx.lineTo(200,200);
ctx.lineTo(300,300);
ctx.stroke();
// ctx.save();
ctx.beginPath();
ctx.moveTo(50,50);
ctx.bezierCurveTo(300,0,200,200,300,300);
// ctx.closePath();
ctx.stroke();
}
}
</script>
5. canvas变换
translate(x,y) 用来移动canvas的原点到一个不同的位置,x是左右偏移量,y是上下偏移量;在canvas中translate是累加的。
rotate(angle) 该方法只接受一个参数:旋转的角度(angle),她是顺时针方向的、以弧度为单位的值,旋转的中心始终是canvas的原点,如果要改变它,需要用translate;在canvas中rotate是累加的。
scale(x,y) x,y分别是横轴和纵轴的缩放因子,必须是正值,值比1.0小表示缩小,比1.0大表示放大,值为1.0时什么效果没有。缩放一般用它来增减图形在canvas中的像素数目,对形状、位图进行缩小或者放大;在canvas中scale是累加的。
6. 变换案例
1)旋转缩放
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background-color: pink;
}
#test{
background-color: gray;
position:absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
</head>
<body>
<canvas id="test" width="300" height="300">
</canvas>
</body>
<script>
window.onload=function(){
var flag=0;
var flagScale=0;
var scale=0;
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=test.getContext("2d");
ctx.save();
ctx.translate(150,150);
ctx.beginPath();
ctx.fillRect(-50,-50,100,100);
ctx.restore();
setInterval(function(){
flag++;
ctx.clearRect(0,0,canvas.width,canvas.height)
ctx.save();
ctx.translate(150,150);
ctx.rotate(flag*Math.PI/180);
if(scale==100){
flagScale=-1;
}else if(scale==0){
flagScale=1;
}
scale+=flagScale;
ctx.scale(scale/50,scale/50);
ctx.beginPath();
ctx.fillRect(-50,-50,100,100);
ctx.restore();
},1000/60);
}
}
</script>
</html>
效果如图:
2)表盘
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
background-color: pink;
}
#clock{
position: absolute;
left: 50%;
top: 50%;
background-color: gray;
transform: translate3d(-50%,-50%,0);
}
</style>
</head>
<body>
<canvas id="clock" width="400" height="400">
</canvas>
</body>
<script>
window.onload=function(){
var clock=document.querySelector('#clock');
if(clock.getContext){
var ctx=clock.getContext("2d");
setInterval(function(){
ctx.clearRect(0,0,clock.width,clock.height);
move();
},1000);
move();
function move(){
ctx.save();
ctx.lineWidth=8;
ctx.strokeStyle="black";
ctx.lineCap="round";
ctx.translate(200,200);
ctx.rotate(-90*Math.PI/180);
ctx.beginPath();
// 外层空气圆盘
ctx.save();
ctx.strokeStyle="#325FA2";
ctx.lineWidth=14;
ctx.beginPath();
ctx.arc(0,0,140,0,360*Math.PI/180);
ctx.stroke();
ctx.restore();
// 时针刻度
ctx.save();
for(var i=0;i<12;i++){
ctx.rotate(30*Math.PI/180);//会自动累加
ctx.beginPath();
ctx.moveTo(100,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.restore();
// 分针刻度
ctx.save();
ctx.lineWidth=4;
for(var i=0;i<60;i++){
ctx.rotate(6*Math.PI/180);//会自动累加
if((i+1)%5!=0){
ctx.beginPath();
ctx.moveTo(117,0);
ctx.lineTo(120,0);
ctx.stroke();
}
}
ctx.restore();
// 时针 分针 秒针 表座
var date=new Date();
var s=date.getSeconds();
var m=date.getMinutes()+s/60;
var h=date.getHours()+m/60;
h=h>12?h-12:h;
// 时针
ctx.save();
ctx.lineWidth=14;
ctx.rotate(h*30*Math.PI/180);
ctx.beginPath();
ctx.moveTo(-20,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// 分针
ctx.save();
ctx.lineWidth=10;
ctx.rotate(m*6*Math.PI/180);
ctx.beginPath();
ctx.moveTo(-28,0);
ctx.lineTo(112,0);
ctx.stroke();
ctx.restore();
// 秒针
ctx.save();
ctx.lineWidth=6;
ctx.strokeStyle="#D40000";
ctx.fillStyle="#D40000";
ctx.rotate(s*6*Math.PI/180);
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(83,0);
ctx.stroke();
// 表座
ctx.beginPath();
ctx.arc(0,0,10,0,360*Math.PI/180);
ctx.fill();
// 秒针头
ctx.beginPath();
ctx.arc(96,0,10,0,360*Math.PI/180);
ctx.stroke();
ctx.restore();
ctx.restore();
}
}
}
</script>
</html>
效果如图:图中指针实时转动,对应当下的时间
7. canvas使用图片
7.1在canvas中插入图片
1)canvas操作图片时要等图片加载完才能操作;
2)drawImage(image, x, y, width, height) image是image或canvas对象,x,y是其在目标canvas里的起始坐标。width和height来控制当向canvas画入时应该缩放的大小。
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
var img=new Image();
img.src="01.jpg";
img.onload=function(){
draw();
}
function draw(){
ctx.drawImage(img,0,0,144,312);
}
}
}
</script>
7.2 在canvas中设置背景
creatPattern(image, repetition) image是图像源,repetition可选值:"repeat" "repeat-x" "repeat-y" "no-repeat" 一般我们会将creatPattern返回的对象作为fillstyle的值
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
var img=new Image();
img.src="02.png";
img.onload=function(){
draw();
}
function draw(){
var pattern= ctx.createPattern(img,"repeat"); //no-repeat 不平铺
ctx.fillStyle=pattern;
ctx.fillRect(0,0,300,300);
}
}
}
</script>
7.3 渐变
1)线性渐变
createLinearGradient (x1, y1, x2, y2) 表示渐变的起点(x1,y1)与终点(x2,y2)
gradient.addColorStop (position, color) gradient:createLinearGradient的返回值; addColorStop有两个参数:position参数必须是0.0-1.0之间的数值,表示渐变中颜色所在的相对位置;color参数必须是一个有效的css颜色值( 如#FFF,rgba(0,0,0,1) 等)
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
var gradient= ctx.createLinearGradient(0,0,300,300);
gradient.addColorStop(0,"red");
gradient.addColorStop(0.3,"yellow");
gradient.addColorStop(0.5,"pink");
gradient.addColorStop(1,"green");
ctx.fillStyle=gradient;
ctx.fillRect(0,0,300,300);
}
}
</script>
2)径向渐变
createRadialGradient (x1, y1, r1, x2, y2, r2) 前三个参数定义另一个以(x1,y1)为原点,半径为r1的圆,后三个参数定义另一个以(x2,y2)为原点,半径为r2的圆。
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
var gradient= ctx.createRadialGradient(150,150,0,150,150,100);
gradient.addColorStop(0,"red");
gradient.addColorStop(0.2,"yellow");
gradient.addColorStop(0.4,"pink");
gradient.addColorStop(1,"green");
ctx.fillStyle=gradient;
ctx.fillRect(0,0,300,300);
}
}
</script>
8. 文本相关
fillText ( text, x, y ) 在指定的(x,y)位置填充指定的文本
strokeText ( text, x, y ) 在指定的(x, y)位置绘制文本边框
font=value 使用和 css font属性相同的语法;默认字体是10px,sans-serif;font属性在指定时,必须要有大小和字体,缺一不可。
textAlign=value 文本对齐 可选值 left right center
textBaseline=value 当前文本基线的属性 可选值 top middle bottom
measureText() 方法返回一个TextMetrics对象,包括文本的尺寸信息
文本阴影:
shadowOffsetX=float shadowOffsetY=float 用来设定阴影在X和Y轴的延伸距离,默认0;
shadowBlur=float 用于设定阴影的模糊程度,其数值不和像素挂钩,也不受变换矩阵的影响;
shadowColor=color(必须项)标准的css颜色值,用于设定阴影颜色效果,默认是全透明的黑色。
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
ctx.fillStyle="pink";
//font 属性指定时必须要有大小和字体,缺一不可
ctx.font="60px impact";
// ctx.textAlign=value value可选值:left right center是将内容的左右中与原点偏移量处对齐,但center比较特殊,文本的居中是基于在fillText的时候给的x的值,也就是文本一半在x的左边,一半在x的右边
// textBaseline 文本基线在文本块的顶部、中间、底部
ctx.textBaseline="middle";
// measureText()方法 返回一个TextMetrics对象,包括文本的尺寸信息,例如文本的宽度
var w=ctx.measureText("candy").width;
console.log(w);
// 文本阴影 要放在fillText前面
ctx.shadowOffsetX=5;
ctx.shadowOffsetY=5;
ctx.shadowBlur=10;
ctx.shadowColor="blue";
// ctx.fillText(text, x, y); 指定(x, y)位置填充指定文本
ctx.fillText("candy",(canvas.width-w)/2,(canvas.height-60)/2);//文本居中
// ctx.strokeText(text, x, y); 指定(x, y)位置绘制文本边框
}
}
</script>
9. 像素操作
9.1 像素数据操作
getImageData( x,y,width,height ) 复制画布上指定矩形的像素数据
x 将要复制的指定矩形区域的左上角 X 坐标(以像素为单位)
y 将要复制的指定矩形区域的左上角 Y 坐标(以像素为单位)
width 将要复制的指定矩形区域的宽度(以像素为单位)
height 将要复制的指定矩形区域的高度(以像素为单位)
该方法返回一个 ImageData 对象,该对象复制画布上指定矩形的像素数据。 ImageData 对象不是图片,它指定画布上的一个部分(矩形),并保存该矩形内每个像素的信息。对于 ImageData 对象中的每个像素,都有四个信息,即 RGBA 值:
R - 红色(0-255)黑色到白色
G - 绿色(0-255)黑色到白色
B - 蓝色(0-255)黑色到白色
A - Alpha 通道(0-255;0 是透明的,255 是透明的)完全可见)
color/alpha 信息保存在一个数组中,并存储在 ImageData 对象的data属性中
以下代码可获得被返回的ImageData对象中第一个像素的color/alpha值
red=imgData.data[0]; green=imgData.data[1]; blue=imgData.data[2]; alpha=imgData.data[3];
putImageData(imgData, dx, dy) 方法将图像数据(来自指定的 ImageData 对象)放回画布上。
imgData 要放回画布的imgData对象;
dx 水平值(x)在画布上放置imgData的X轴位置; dy 水平值(y)在画布上放置imgData的Y轴位置。
createImageData(width, height) width:ImageData新对象的宽度 height:ImageData新对象的高度
新对象的默认像素值是 transparent black 透明黑色
color/alpha 信息保存在一个数组中,并存储在 ImageData 对象的data属性中
例:以下代码把ImageData对象的第一个像素变成红色
imgData=ctx.createImageData(100,100); imgData.data[0]=255; imgData.data[1]=0; imgData.data[2]=0; imgData.data[3]=255;
以下代码把ImageData对象的第二个像素变成红色
imgData=ctx.createImageData(100,100); imgData.data[4]=0; imgData.data[5]=255; imgData.data[6]=0; imgData.data[7]=255;
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=test.getContext("2d");
ctx.fillStyle="rgba(255,192,203,1)";
ctx.fillRect(0,0,100,100);
var imageData=ctx.createImageData(100,100);
var copy=ctx.getImageData(0,0,10,10); //得到像素数据
console.log(copy);
for(var i=0;i<imageData.data.length;i++){
imageData.data[4*i+3]=255;
}
ctx.putImageData(imageData,100,100);
}
}
</script>
9.2 data数据(color/alpha) 像素点 像素点坐标的关系
10. canvas其他
10.1 将画布导出为图像
toDataURL(注意是canvas元素接口上的方法)
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
ctx.fillRect(0,0,199,199);
var result=canvas.toDataURL();
console.log(result);
}
}
</script>
10.2 事件操作
ctx.isPointInPath(x, y) 判断在当前路径中是否包含检测点, x 检测点的X坐标,y 检测点的Y坐标
注意:此方法只作用于最新画出的canvas图像
<script>
window.onload=function(){
var canvas=document.querySelector('#test');
if(canvas.getContext){
var ctx=canvas.getContext("2d");
ctx.arc(100,100,50,0,360*Math.PI/180);
ctx.fill();
canvas.onclick=function(ev){
ev=ev||event;
var x=ev.clientX-canvas.offsetLeft;
var y=ev.clientY-canvas.offsetTop;
if(ctx.isPointInPath(x,y)){
alert(123);
}
}
}
}
</script>
10.3 canvas合成
globalAlpha 属性设置或返回绘图的当前透明值(alpha 或 transparency)
取值0(完全透明)-1(不透明)
globalCompositeOperation 属性设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像上。 默认值是source-over:源在上面,新的图像层级高
源图像 = 打算放置到画布上的绘图(最新的)
目标图像 = 已经放置在画布上的绘图
值 | 描述 |
---|---|
source-over | 默认。在目标图像上显示源图像。 |
source-atop | 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。 |
source-in | 在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。 |
source-out | 在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。 |
destination-over | 在源图像上方显示目标图像。 |
destination-atop | 在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。 |
destination-in | 在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。 |
destination-out | 在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。 |
lighter | 显示源图像 + 目标图像。 |
copy | 显示源图像。忽略目标图像。 |
xor | 使用异或操作对源图像与目标图像进行组合。 |
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(20,20,75,50);
ctx.fillStyle="blue";
ctx.globalCompositeOperation="source-over"; //合成 源在上
ctx.fillRect(50,50,75,50);
ctx.fillStyle="red";
ctx.globalAlpha=0.6; //透明度
ctx.fillRect(150,20,75,50);
ctx.fillStyle="blue";
ctx.globalCompositeOperation="destination-over"; //目标图像在上
ctx.fillRect(180,50,75,50);
</script>
</body>
</html>
五、音视频
<video>:HTML5提供的播放视频的标签
<audio>:HTML5提供的播放音频的标签
src:资源地址 controls:显示或隐藏用户控制界面
1. 音视频attribute属性
标签: <video> <audio> <source>()
video标签的属性:
width(视频显示区域的宽度) height(视频显示区域的高度) poster(预加载的图片)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<video src="猫咪.mp4" controls="controls" autoplay="autoplay" muted="muted" loop="loop" poster="yujiazaitupian.jpg" width="100%">
您的浏览器不支持HTML5 video//标签之间的内容是会在不支持HTML5 video的浏览器显示的
</video>
<audio src="周杰伦 - Mojito.mp3" controls autoplay loop="loop">
</audio>
</body>
</html>
兼容性写法:
3种视频格式:mp4、ogv、webm
3种音频格式:mp3、ogg、wav
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<video>
<source src="">
<source src="猫咪.mp4" type="video/mp4"> </source>
<source src="猫咪.ogg" type="video/ogg"> </source>
您的浏览器不支持video标签
</video>
<audio controls>
<source src="周杰伦 - Mojito.ogg" type="audio/ogg">
<source src="周杰伦 - Mojito.mp3" type="audio/mp3">
您的浏览器不支持audio标签
</audio>
</body>
</html>
2. 音视频property属性
duration 媒体总时间(只读) 例:audio.duration
currentTime 开始播放到现在的时间(可读写) 例:video.currentTime
muted volume 不同步 muted优先级高
muted:静音播放 两个可选值true(静音) false(非静音) 例:video.muted=true;
volume: 0.0-1.0的音量相对值(可读写) 例:video.volume=0;
paused:媒体是否暂停 true/false(只读) 例:video.paused
ended:媒体是否播放完毕 true/false(只读) 例:video.ended
error:null 媒体发生错误时 返回错误代码(只读) 例:video.error
currentSrc: null 以字符串形式返回媒体地址 (只读)例:audio.currentSrc
其它:
poster:视频播放前的预览图片(读写)例: video.poster="yujiazaitupian.jpg";
width height :视频标签宽高(读写) 例:video.width
videoWidth videoHeight :视频实际尺寸(只读) 例:video.videoWidth
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<video src="猫咪.mp4" controls="controls" width="500">
</video>
<audio src="周杰伦 - Mojito.mp3" controls autoplay loop="loop">
</audio>
</body>
<script>
window.onload=function(){
var video=document.querySelector("video");
var audio=document.querySelector("audio");
console.log(video.duration); // duration 媒体总时间(只读)
console.log(audio.duration);
console.log(video.currentTime); // currentTime 开始播放到现在的时间(可读写)
// muted volume 不同步 muted优先级高
video.muted=true;
audio.muted=false;
video.volume=0;
audio.volume=0;
console.log(video.muted); // 媒体是否静音 true和false(可读写)
console.log(audio.muted);
console.log(video.volume);// 0.0-1.0的音量相对值(可读写)
console.log(audio.volume);
console.log(video.paused); //媒体是否暂停 true/false(只读)
console.log(audio.paused);
console.log(video.ended); //媒体是否播放完毕 true/false(只读)
console.log(audio.ended);
console.log(video.error); //null 媒体发生错误时 返回错误代码(只读)
console.log(audio.error);
console.log(video.currentSrc); // null 以字符串形式返回媒体地址 (只读)
console.log(audio.currentSrc);
video.poster="yujiazaitupian.jpg";
console.log(video.poster); // 一视频播放前的预览图片(读写)
console.log(video.width); // 500 视频标签宽高(读写)
console.log(video.height); // 0
console.log(video.videoWidth); // 1280 视频实际尺寸(只读)
console.log(video.videoHeight); //720
}
</script>
</html>
3. 视频与canvas结合
让视频在画布上播放
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background-color: pink;
}
#oc{
position:absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
</head>
<body>
<video autoplay muted src="猫咪.mp4" width="0" height="0" controls ></video>
<canvas id="oc" width="300" height="300"></canvas>
</body>
<script>
window.onload=function(){
var oc=document.querySelector("#oc");
var video=document.querySelector("video");
if(oc.getContext){
var ctx=oc.getContext("2d")
// 给video绑定监听 当浏览器已加载音频/视频的当前帧时
// loadeddata 可以换成play 我在这里用loadeddata谷歌浏览器加载不出来
video.addEventListener("loadeddata",function(){
setInterval(function(){
ctx.drawImage(video,0,0,oc.width,oc.height)
})
})
}
}
</script>
</html>
4. 音视频-函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<video src="猫咪.mp4" controls="controls" muted width="500">
</video>
<audio src="周杰伦 - Mojito.mp3" controls loop="loop">
</audio>
</body>
<script>
window.onload=function(){
var video=document.querySelector("video");
var audio=document.querySelector("audio");
video.play(); // paly() 媒体播放,c现在必须在用户有互动后或静音(muted)时才播放
audio.play();
setTimeout(function(){
video.pause(); //pause()媒体暂停
audio.pause();
},5000)
video.src="xxx";
video.load(); // load() 重新加载媒体
}
</script>
</html>
六、HTML5其他标签
1. 状态标签(不常用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- meter标签 电量-->
<meter value="80" min="20" max="100" low="40" high="60" optimum="50"></meter>
<!-- progress标签 -->
<progress value="50" max="100"></progress>
<progress max="100"></progress>
<!-- meter和progress很少用 -->
</body>
</html>
2. 列表标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin:0;
padding:0;
}
input::-webkit-input-placeholder{
color:pink;
/* 通过伪元素设置颜色*/
}
</style>
</head>
<body>
<!-- 列表标签 -->
<!-- datalist 为输入框构造一个选择列表,list值为datalist标签的id-->
<input type="text" placeholder="你最喜欢的女明星是?" list="ty"></body>
<datalist id="ty">
<option value="1">唐嫣</option>
<option value="2">袁冰妍</option>
<option value="3">郑爽</option>
<option value="4">杨幂</option>
</datalist>
<!-- details -->
<details open>
<summary>ty</summary>
<p>女</p>
<p>39</p>
<p>已婚</p>
</details>
<!-- 注释标签 ruby rt 展示文字注音或字符注释-->
<span><ruby>澧<rt>li</rt></ruby></span>
<!-- 标记标签 -->
<span>最高级的<mark>浪漫</mark>源于生活</span>
</body>
</html>
七、新增表单
1. 新增表单控件
在HTML5中表单仍然使用<form>元素作为容器,可以在其中设置基本的提交特性,form的action指向一个服务器地址(接口);当开发人员或用户提交页面时,表单仍向服务器端发送表单中控件的值 ,注意name属性必须有值,服务器才能获取表单。
之前和新增的表单见如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form > //以往表单
<input type="radio" name=""/> <!--单选按钮 以name分组 确保单选关系,也为了后台成功获取 必须有value属性-->
<input type="radio" name=""/>
<input type="password" /> <!--密码框-->
<input type="text" /> <!--文本框 -->
<input type="checkbox" /> <!--复选框 以name分组 确保单选关系,也为了后台成功获取 必须有value属性-->
<input type="reset" /> <!-- 重置按钮-->
<input type="button"> <!--普通按钮-->
</form>
<form > <!--新增
<input type="email"/> <!--email 地址类型 移动端获焦时会切换英文键盘-->
<input type="tel" /> <!--电话类型 移动端点上去键盘会弹出来-->
<input type="url" /> <!--不符合url格式时提交不会成功 会出提示-->
<input type="search" /> <!--搜索类型 有清空文本的按钮-->
<input type="range" min="10" max="20" step="2" /> <!-- 特定范围内的数值选择器-->
<input type="number" /> <!--只能输入数字的输入框-->
<input type="color" /> <!--颜色选择器-->
<input type="datetime" /> <!--显示完整日期(移动端支持)-->
<input type="datetime-local" /> <!--显示完整日期,不含时区-->
<input type="time" /> <!--显示时间,不含时区-->
<input type="date" /> <!--显示日期-->
<input type="week" /> <!--显示周-->
<input type="month" /> <!--显示月-->
<input type="submit" value="提交" /> <!--提交按钮-->
</form>
</body>
</html>
2. 新增表单属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="http://www.baidu.com">
<input type="text" autofocus> </input> <!--指定表单获取输入焦点-->
<input type="text" required> </input> <!-- 此项必填 不能为空-->
<input type="text" pattern="\d{1,5}"> </input> <!-- 正则验证 比如pattern="\d{1,5}" 必须输入1-5个字符-->
<input type="submit" value="提交">
<input type="submit" value="提交1" formaction="https://www.runoob.com/html/html5-canvas.html">
<!-- formaction 在submit里定义提交地址 -->
</form>
</body>
</html>
3. 表单验证
validity对象,通过下面的valid可以查看验证是否通过,如果8种验证都通过返回true,1种验证失败则返回false。 node.addEventListener( "invalid", fn1, false );
- customError: false 不符合自定义验证返回true
- patternMismatch: false 输入值不满足pattern正则返回true
- rangeOverflow: false 验证的range最大值返回true
- rangeUnderflow: false 验证的range最小值返回true
- stepMismatch: false 验证range当前值是否符合min max step的规则返回true
- tooLong: false 超过maxlength最大限制返回true
- tooShort: false 超过minlength最小限制返回true
- typeMismatch: false 控件值与预期类型不匹配返回true
- valid: false
- valueMissing: true 输入值为空时返回true
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<input type="text" required> </input>
<input type="submit" value="提交" />
</form>
</body>
<script>
window.onload=function(){
var inputEl=document.querySelector("input[type=text]");
inputEl.addEventListener("invalid",function(){
console.log("验证失败了")
console.log(this.validity);
})
}
</script>
</html>
4. 表单验证用户自定义
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<input type="text" > </input>
<input type="submit" value="提交" />
</form>
</body>
<script>
window.onload=function(){
var inputEl=document.querySelector("input");
var submit=document.querySelectorAll("input")[1];
submit.onclick=function(){
var val=inputEl.value;
if(val=="ty"){
// 自定义提示
inputEl.setCustomValidity("该字符无法识别")
}else{
inputEl.setCustomValidity("")
}
}
inputEl.addEventListener("invalid",function(){
console.log(this.validity);
})
}
</script>
</html>