HTML5新特性之一——与表单相关
一、新增的input的type及相关属性

1.已经学过的input type
text、password、radio、checkbox、file、button、submit、reset、image、hidden


2.新的input type
提示:下述验证都必须放在一个表单元素中,表单提交时才会触发。 消息弹出在一个小窗口中,
不是HTML元素,样式无法定制。
(1)email: 提供了邮箱格式的验证,形如:\w{1}@\w{1}
(2)url:提供了URL格式的验证,形如:[a-zA-Z]{1}:
(3)number:提供了数字格式的验证,形如:数字,提供了三个新的属性可用: max(最大) min(最小) step(步长)
(4)tel:在手机中弹出数字键盘,而不是字母键盘
(5)search:可能显示一个X用于清空已有输入
(6)range:范围选择、滑块选择,提供了三个新的属性可用: max(最大) min(最小) step(步长) value(初始值)
(7)color:颜色选择
(8)date:日期选择,弹出一个窗口,FF没有实现
(9)month:月份选择
(10)week:周选择

使用input 新的type range 改变背景颜色:

<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#target{
width:400px;
height:400px;
}
</style>
</head>
<body>
<h3>练习:使用type="range"</h3>

<div id="target"></div><br>
红色:<input type="range" id="red" max="255" value="0">
<span>0</span><br>
绿色:<input type="range" id="green" max="255" value="0">
<span>0</span><br>
蓝色:<input type="range" id="blue" max="255" value="0">
<span>0</span><br>

<script>
var list = document.querySelectorAll('[type="range"]')
for(var i in list){
var range = list[i];
range.onchange = function(){
this.nextElementSibling.innerHTML = this.value;
changeTargetBG(); //修改目标DIV的背景颜色
}
}

function changeTargetBG(){
var r = red.value;
var g = green.value;
var b = blue.value;
target.style.background = 'rgb('+r+','+g+','+b+')';
}
</script>
</body>
二、新增的表单元素
3.已经学过的表单元素
提示:用户可以输入/操作的
input textarea select/option button

4.新的表单元素
提示:下述四个新元素仅用于提示,用户无法操作,也无法随着表单输入进行提交。
(1)datalist:数据列表,本身不可见,用于为其他输入框提供输入建议/提示:
<datalist id="menu">
<option>京酱肉丝</option>
<option>鱼香肉丝</option>
<option>青椒肉丝</option>
</datalist>
我的午餐:<input type="text" list="menu">

(2)progress:进度条
<progress></progress>
<progress value="10" min="0" max="100"></progress>
练习:使用定时器修改progress的进度值,100%时清除定时器

使用定时器模仿进度条的变化:

<body>
<h1>新的表单元素</h1>
<form action="5.php">
加载中:<progress></progress><br>
下载中:<progress min="0" max="100" value="0" id="p2"></progress><br>
</form>

<script>
var timer = setInterval(function(){
var v = p2.value;
v = parseInt(v);
v += 3;
p2.value = v;
if(v>=100){
clearInterval(timer);
}
},100);
</script>
</body>


(3)meter:刻度尺
<meter min="0" max="100" low="能接受的最低值" high="能接受的最高值"
optimum="最优值" value="当前值">
</meter>

(4)output:输出值,语义标签,样式效果与span无异。
商品单价:¥3.5 购买数量:2 小计:¥7.0

三、新增的表单元素的属性

5.已经学过的表单元素的属性
<input id="" class="" title="" style="" name="" value="" type=""
checked selected disabled>

6.表单元素的新属性
(1)autocomplete:on/off,是否启用输入记录功能,下次实现自动完成效果
(2)autofocus:是否自动获得焦点,HTML中只要出现此属性就会自动申请输入焦点,
提示:只有第一个声明此属性的输入域才能获得焦点。(后面再声明了无效)


(3)placeholder:占位符,用于在输入框中显示提示性文本。注意:占位符与value没有任何关系。
(4)multiple:是否允许存在多个输入,使用逗号分隔
(5)form:用于把输入域放到表单外部,指定当前输入域所属的表单
<form action="" id="f1"></form>
<input form="f1">

与表单输入验证相关的新属性
(6)required:必填输入域
(7)maxlength:允许的最大字符长度,限制多余的输入
(8)minlength:允许的最小字符长度——并非H5标准属性,不能代替required属性
(9)max:允许的数字的最大值
(10)min:允许的数字的最小值
(11)step:允许的数字的步长,基于min开始的
(12)pattern:指定必须满足的正则表达式

HTML5新特性之二——视频和音频
HTML5之前播放声音有两种方式:
(1)<body bgsound="x.mp3">
(2)<embed src="x.swf"></embed>

HTML5之后,播放视频和音频使用:
<video></video> 行内块元素
<audio></audio> 行内块元素

VIDEO标签常用的属性:
src:指定视频源URL
width:指定播放区域的宽
height:指定播放区域的高
controls:是否显示播放控件,默认为false
autoplay:是否自动播放,默认为false
loop:是否循环播放,默认为false
poster:在播放之前显示一张海报(播放之后无法再显示),注意取消自动播放
preload:如何预加载视频,有三个可选项:
auto:自动预加载视频元数据,并缓存一定的时长
metadata:仅预加载视频的元数据,不缓存视频内容
none:不预加载视频元数据,不缓存视频内容
paused:JS中使用的只读属性,当前是否处于暂停状态

VIDEO对象的常用事件:
onpause: 当刚一暂停时触发此事件
onplay:当刚一开始播放时触发此事件
onplaying:当视频播放进行中触发此事件

VIDEO对象的方法:
play(): 播放视频
pause():暂停视频


<body>
<h1>视频播放</h1>
<div class="container">
<video id="v3" src="resource/birds.mp4"></video>
<img src="img/haibao.jpg" class="ad">
<img src="img/play.png" class="bt">
</div>
<script>
v3.onpause = function(){ //视频暂停
var img = document.querySelector('.container .ad');
img.style.display = 'block';
}
v3.onplay = function(){ //视频开始播放
var img = document.querySelector('.container .ad');
img.style.display = 'none';
}

var bt = document.querySelector('.bt');
bt.onclick = function(){
if(v3.paused){
v3.play(); //播放视频
this.src="img/pause.png";
}else {
v3.pause();
this.src="img/play.png";
}
}

//鼠标移入/移出事件不能绑定在video上:video和.bt是兄弟关系
var div = document.querySelector('.container');
div.onmouseover = function(){
bt.style.display = 'block';
}
div.onmouseout = function(){
bt.style.display = 'none';
}
</script>
</body>

AUDIO标签常用属性:
(1)src:指定视频源URL
(2)width:指定播放区域的宽
(3)height:指定播放区域的高
(4)controls:是否显示播放控件,默认为false
(5)autoplay:是否自动播放,默认为false
(6)loop:是否循环播放,默认为false
(7)preload:如何预加载视频,有三个可选项:
auto:自动预加载视频元数据,并缓存一定的时长
metadata:仅预加载视频的元数据,不缓存视频内容
none:不预加载视频元数据,不缓存视频内容
(8)paused:JS中使用的只读属性,当前是否处于暂停状态

AUDIO标签的常用事件和方法与VIDEO标签一致。

<audio src="resource/bg.mp3" controls>
您的浏览器不支持AUDIO标签!
</audio>

HTML5新特性之三——canvas

1.补充背景知识:
Chrome中:一个窗口可以有6个线程(工人)向服务器发起请求,可以同时工作;
往浏览器显示区域中绘制内容只有1个线程(工人)。
Canvas绘图应用中,如果需要绘制多个图片,一般必须等待所有图片加载完成
才能开始绘制。图片的加载完成顺序无法预测,必须等待。

给一个全局变量,图像加载完成后就将自己的权重加在这个全局变量上,每一次都判断
全局变量是否满值,直到满值之后才开始绘制图像(例子也是网易云音乐播放器)

2.如何为Canvas上的图像/图形绑定事件监听
只有HTML元素(Canvas)才能进行事件绑定。图形图像无法绑定事件监听。

例子:网易云音乐播放器

<body>
<canvas id="c2" width="400" height="500"></canvas>
<script>
var ctx = c2.getContext('2d');
var progress = 0; //100表全部加载完成

var imgBg = new Image();
imgBg.src = 'img/bg.jpg';
imgBg.onload = function(){
console.log('1 imgBg加载完成');
progress += 25;
if(progress===100){
draw();
}
}
var imgDisc = new Image();
imgDisc.src = 'img/disc.png';
imgDisc.onload = function(){
console.log('2 imgDisc加载完成');
progress += 25;
if(progress===100){
draw();
}
}
var imgPlay = new Image();
imgPlay.src = 'img/play.png';
imgPlay.onload = function(){
console.log('3 imgPlay加载完成');
progress += 25;
if(progress===100){
draw();
}
}
var imgPause = new Image();
imgPause.src = 'img/pause.png';
imgPause.onload = function(){
console.log('4 imgPause加载完成');
progress += 25;
if(progress===100){
draw();
}
}

function draw(){
console.log('开始绘图...');
//绘制背景图
ctx.drawImage(imgBg, 0, 0);

//绘制圆形黑胶片
ctx.beginPath();
ctx.arc(200,250,120,0,2*Math.PI);
ctx.fill();

//绘制胶片封皮图片
ctx.drawImage(imgDisc,200-imgDisc.width/2,250-imgDisc.height/2);

//绘制播放按钮
ctx.drawImage(imgPlay,200-imgPlay.width/2, 500-imgPlay.height);
//为播放按钮绑定事件监听
c2.onmousemove = function(e){ //这里为canvas绑定的事件
var x = e.offsetX;
var y = e.offsetY;
if(x>=150 && x<=250 && y>=400 && y<=500){
c2.style.cursor = 'pointer';
}else {
c2.style.cursor = 'default';
}
}
}
</script>
</body>

验证码的例子:/*******验证码*******/

<style>
canvas {
vertical-align: middle;
}
</style>
</head>

<body>
<canvas id="c1" width="120" height="40"></canvas>
<a href="#" id="change">看不清,换一张</a>
<script>
/**Random Number**/
function rn(min,max){
return Math.floor( Math.random()*(max-min)+min );
}
/**Random Color**/
function rc(min,max){
var r = rn(min,max);
var g = rn(min,max);
var b = rn(min,max);
return `rgb(${r},${g},${b})`;
}
draw();
change.onclick = function(e){
e.preventDefault();
draw();
}

/**绘制验证码图片**/
function draw(){
var ctx = c1.getContext('2d');
ctx.textBaseline = 'bottom';

/**绘制背景色**/
ctx.fillStyle = rc(180,240);
ctx.fillRect(0,0,c1.width,c1.height);
/**绘制文字**/
var str = 'ABCEFGHJKLMNPQRSTWXY3456789';
for(var i=0; i<5; i++){
var txt = str[rn(0,str.length)];
ctx.fillStyle = rc(50,160);
ctx.font = rn(15,40)+'px SimHei';
var x = 15+i*20;
var y = rn(25,45);
var deg = rn(-45, 45);
//修改坐标原点和旋转角度
ctx.translate(x,y);
ctx.rotate(deg*Math.PI/180);
ctx.fillText(txt, 0,0);
//恢复坐标原点和旋转角度
ctx.rotate(-deg*Math.PI/180);
ctx.translate(-x,-y);
}
/**绘制干扰线**/
for(var i=0; i<8; i++){
ctx.strokeStyle = rc(40,180);
ctx.beginPath();
ctx.moveTo( rn(0,c1.width), rn(0,c1.height) );
ctx.lineTo( rn(0,c1.width), rn(0,c1.height) );
ctx.stroke();
}
/**绘制干扰点**/
for(var i=0; i<100; i++){
ctx.fillStyle = rc(0,255);
ctx.beginPath();
ctx.arc(rn(0,c1.width),rn(0,c1.height), 1, 0, 2*Math.PI);
ctx.fill();
}
}
</script>
</body>
结论:非常不方便!

1.Canvas:画布
2.Context:绘图上下文/画笔
3.ctx.strokeStyle = 颜色/渐变色
4.ctx.fillStyle = 颜色/渐变色
5.绘制矩形——定位点在左上角
ctx.fillRect(x,y, w, h)
ctx.strokeRect(x,y,w,h)
ctx.clearRect(x,y,w,h)

6.绘制文本——定位点基线的最左侧
ctx.textBaseline = 'alphabetic/top/bottom/middle'
ctx.font = '30px SimHei'
ctx.measureText(txt).width
ctx.fillText(txt, x, y)
ctx.strokeText(txt, x, y)
7.
绘制路径
ctx.beginPath()
ctx.moveTo(x,y)
ctx.lineTo(x,y)
ctx.closePath()
————————
ctx.stroke()
ctx.fill()
ctx.clip()


8.
绘制圆形路径——圆形定位点在圆心——角度默认从3点钟开始为0度
ctx.beginPath()
ctx.arc(cx,cy, r, sAngle, eAngle, [isCounterClock: false]) //绘制圆拱路径
ctx.stroke()/fill()/clip()
角度转换为弧度制的公式: deg*Math.PI/180


/*******使用canvas绘制统计图*******/

<body>
<h1>作业:使用Canvas绘图统计图</h1>
<canvas id="c1">
您的浏览器不支持Canvas!
</canvas>

<script>
var str = `[
{"label":"HTML", "value":3},
{"label":"CSS", "value":5},
{"label":"JS", "value":7},
{"label":"DOM", "value":6.5},
{"label":"jQuery", "value":6},
{"label":"AJAX", "value":8},
{"label":"HTML5", "value":6.5}
]`;
var arr = JSON.parse(str);
console.log(arr);


c1.width = 500;
c1.height = 400;
//Canvas的宽和高必须用属性,不能用样式
var ctx = c1.getContext('2d');
ctx.font = '14px SimHei';
ctx.textBaseline= 'bottom';
/***绘制X轴***/
ctx.beginPath();
ctx.moveTo(50,350); //左下角原点
ctx.lineTo(450,350); //右下角
ctx.lineTo(440,340); //箭头
ctx.moveTo(450,350); //右下角
ctx.lineTo(440,360); //箭头

/***绘制Y轴***/
ctx.moveTo(50,350); //左下角原点
ctx.lineTo(50,50); //左上角
ctx.lineTo(60,60); //箭头
ctx.moveTo(50,50); //左上角
ctx.lineTo(40,60); //箭头
//画纵轴上的小刻度
for(var i=1; i<10; i++){ //Y轴上的坐标点
var x = 50;
var y = 350-i*30;
ctx.moveTo(x,y); //坐标点左侧点
ctx.lineTo(x+5, y); //坐标点右侧点
//添加刻度上的字
var w = ctx.measureText(i).width;
ctx.fillText(i, x-w-2, y+7);
}

ctx.stroke();

/***绘制柱状图***/
var barWidth = 400/(2*arr.length+1); //柱的宽度和间距
for(var i=0; i<arr.length; i++){
var value = arr[i].value;
var label = arr[i].label;
var w = barWidth;
var h = 30*value;
var x = 50+(2*i+1)*barWidth;
var y = 350-h;
ctx.fillStyle='#000';
ctx.fillText(value,x,y);
ctx.strokeRect(x,y, w, h);//描边一个矩形
var g = ctx.createLinearGradient(x,y,x,350);//设置渐变对象
g.addColorStop(0, rc());
g.addColorStop(1, '#fff');
ctx.fillStyle = g; //将填充颜色赋值给fillStyle
ctx.fillRect(x,y, w,h);//填充矩形

}

function rc(){
var r = Math.floor(Math.random()*256);
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
return 'rgb('+r+','+g+','+b+')';
}
</script>

</body>

绘制圆形进度条的例子:
<body>
<h1>绘制圆形路径</h1>
<canvas id="c3" width="500" height="400">
您的浏览器不支持Canvas!
</canvas>

<script>
var ctx = c3.getContext('2d');

//灰色的圆底
ctx.beginPath();
ctx.arc(250,200, 100, 0, 2*Math.PI);
ctx.lineWidth = 20;
ctx.strokeStyle = '#ddd';
ctx.stroke();
//绿色的进度条
var sAngle = -90; //开始角
var eAngle = -90; //结束角
ctx.strokeStyle = '#0a0';
var timer = setInterval(function(){ //定时器
ctx.beginPath();
ctx.arc(250,200,100,
sAngle*Math.PI/180,eAngle*Math.PI/180);
ctx.stroke();
var txt=parseInt((eAngle-sAngle)/360*100);
ctx.clearRect(230,180,50,50);
ctx.font='20px SimHei';
ctx.fillText(txt+'%',250,200);

eAngle+=15;
if(eAngle>270){
clearInterval(timer);
}
}, 100);
</script>
</body>

食人鱼动画效果代码:

<body>
<h1>绘制圆形路径</h1>
<canvas id="c3" width="500" height="400">
您的浏览器不支持Canvas!
</canvas>

<script>
var ctx = c3.getContext('2d');

function openMouth(){
//绘制外围圆圈
ctx.beginPath();
ctx.arc(250,200, 100,
45*Math.PI/180,315*Math.PI/180);
ctx.lineTo(250,200);
ctx.closePath(); //闭合路径,补全剩余
ctx.stroke();

//绘制眼睛
ctx.beginPath();
ctx.arc(250,150,25,0,2*Math.PI);
ctx.stroke();
ctx.fillStyle = '#6af';
ctx.fill();

//绘制眼神光
ctx.beginPath();
ctx.arc(260,135,5,0,2*Math.PI);
ctx.fillStyle = '#fff';
ctx.fill();
}
function closeMouth(){
//绘制外围圆圈
ctx.beginPath();
ctx.arc(250,200, 100,0,2*Math.PI);
ctx.lineTo(250,200);
ctx.stroke();

//绘制眼睛
ctx.beginPath();
ctx.arc(250,150,25,0,2*Math.PI);
ctx.stroke();
ctx.fillStyle = '#6af';
ctx.fill();

//绘制眼神光
ctx.beginPath();
ctx.arc(260,135,5,0,2*Math.PI);
ctx.fillStyle = '#fff';
ctx.fill();
}
var isOpen = true;
var timer = setInterval(function(){
ctx.clearRect(0,0,500,400);
if(isOpen){
closeMouth();
isOpen = false;
}else {
openMouth();
isOpen = true;
}
},300);
</script>
</body>

9.绘图图像——图像的定位点在左上角
var img = new Image();
img.src = 'x.png';
img.onload = function(){ //必须等待图片加载完成
//img.width img.height
ctx.drawImage( img, x, y );
ctx.drawImage( img, x, y, w, h ); //绘制图像进行拉伸
}

来回弹的小飞机:

<script>
var ctx = c7.getContext('2d');

var img = new Image();
img.src = "img/p1.png";
img.onload = function(){
var x = 0;
var xDirection = 1; //1或-1
var y = 0;
setInterval(function(){
//清除已有的内容
ctx.clearRect(0,0, 500, 400);

ctx.drawImage(img, x, y);

x += 10*xDirection;

if(x>=500-100){ //控制X轴行进方向
xDirection = -1;
}else if(x<=0){
xDirection = 1;
}
},100);
}
</script>

例子:让小飞机随鼠标移动:面向过程版

<script>
var ctx = c7.getContext('2d');

var img = new Image();
img.src = "img/p1.png";
img.onload = function(){
var x = 200-img.width/2;
var y = 600-img.height;

/***定时器:让画面动起来——引擎***/
setInterval(function(){
ctx.clearRect(0,0,400,600);
ctx.drawImage(img, x, y);
},100);
/***用户操作***/
c7.onmousemove = function(e){
x = e.offsetX-img.width/2;//将鼠标移动到图片中央
y = e.offsetY-img.height/2;
}
}
</script>

面向对象版:


<body>
<h1>随鼠标移动的飞机——面向对象版</h1>
<canvas id="c7" width="400" height="600">
您的浏览器不支持Canvas!
</canvas>

<script>
var ctx = c7.getContext('2d');
var hero = null; //new Hero()
var engine = null; //new Engine()

/**我方英雄的构造方法**/
function Hero(img){
this.x = 200-img.width/2;
this.y = 600-img.height;
this.draw = function(){
ctx.drawImage(img, this.x, this.y);
}
}
/***游戏引擎的构造方法***/
function Engine(){
this.start = function(){
setInterval(function(){
ctx.clearRect(0,0,400,600);

hero.draw();
},50);
}
}

//加载图片
var imgHero = new Image();
imgHero.src = 'img/p1.png';
imgHero.onload = function(){
//加载完成:创建英雄、启动引擎
hero = new Hero(imgHero);
engine = new Engine();
engine.start();

//开始使用鼠标操控英雄
c7.onmousemove = function(e){
hero.x = e.offsetX-imgHero.width/2;
hero.y = e.offsetY-imgHero.height/2;
}
}
</script>
</body>


总结:Canvas绘图
绘制矩形
ctx.fillRect(x,y,w,h)
ctx.strokeRect(x,y,w,h)
ctx.clearRect(x,y,w,h)
绘制文本
ctx.fillText(txt,x,y)
ctx.strokeText(txt,x,y)
ctx.measureText(txt).width
绘制路径
ctx.beginPath()
ctx.moveTo(x,y) ctx.lineTo(x,y)
ctx.arc(cx,cy, r, sAngle, eAngle)
ctx.closePath()
----------------------------
ctx.fill() / ctx.stroke() / ctx.clip()
绘制图像
ctx.drawImage(img, x, y)
ctx.drawImage(img, x, y, w, h)

3.补充小难点:如何旋转绘制图像
Canvas(画布)是不能旋转的。
Context(画笔)是可以旋转的。
ctx.rotate( deg * Math.PI / 180 )
//在原有旋转角度基础上继续旋转deg度

——旋转的轴心是画布的坐标原点(默认为左上角)
ctx.translate( x, y ) //把画布的坐标原点平移到新的点,
记得修改图形/图像的定位点

例子:小飞机原地打转

<script>
var ctx = c11.getContext('2d');

var img = new Image();
img.src = 'img/p1.png';
img.onload = function(){

ctx.translate(250,200); //原点平移
//ctx.drawImage(img,-img.width/2,-img.height/2);

setInterval(function(){
//清除已有内容
ctx.clearRect(-250,-200,500,400);

ctx.rotate(10*Math.PI/180);
//注意修改图形图像的定位点
ctx.drawImage(img,-img.width/2, -img.height/2);
},200)
}
</script>

 

4.常用的第三方绘制统计图表的工具
直接使用Canvas绘制统计图表比较麻烦,推荐使用第三方绘图工具库。
免费的:
Chart.js
FreeChart
收费的:
FusionChart
提示:第三方工具的使用不需要记忆,随查随用即可。

3.使用Canvas绘制矩形——矩形的定位点左上角
ctx.strokeStyle = 颜色/渐变对象;
ctx.fillStyle = 颜色/渐变对象;
ctx.strokeRect(x, y, w, h) 描边一个矩形区域
ctx.fillRect(x, y, w, h) 填充一个矩形区域
ctx.clearRect(x,y,w,h) 清除一个矩形区域内所有内容

var g = ctx.createLinearGradient(x1,y1,x2,y2);
g.addColorStop(偏移量, 颜色);

例子:
<body>
<h1>使用渐变色绘制矩形</h1> 
<canvas id="c10" width="500" height="400">
您的浏览器不支持Canvas!
</canvas>
<script>
var ctx = c10.getContext('2d');

//创建线性渐变色
var x1 = 250-100;
var y1 = 200-75;
var x2 = x1+200;
var y2 = y1;
var g = ctx.createLinearGradient(x1,y1,x2,y2);
g.addColorStop(0,'#f00');
g.addColorStop(0.5,'#ff0');
g.addColorStop(1,'#0f0');

//200x150的矩形,画布的正中央
//ctx.fillStyle = g;
//ctx.fillRect(250-100,200-75,200,150);
ctx.strokeStyle = g;
ctx.strokeRect(250-100,200-75,200,150);
</script>

4.使用Canvas绘制文本——文本的定位点在文本基线左侧

middle 第二三根中央
top:第一根线
bottom:第四根线
ctx.textBaseline = 'alphabetic/middle/bottom/top' 文本基线
ctx.font = '20px SimHei'; 设置大小和字体
ctx.measureText(txt).width 测量一段文本的总宽度
ctx.fillText(txt, x, y) 填充文本
ctx.strokeText(txt, x, y) 描边文本


参考PS中的“钢笔工具”:路径本身不可见!创建完路径有三种用途: (1)描边 (2)填充(必须闭合) (3)裁剪图片
ctx.beginPath() //开始一条新路径
/******绘制路径********/
ctx.moveTo(x, y) 移动到指定点
ctx.lineTo(x,y) 从上一个点到指定点画一条直线
ctx.arc(cx,cy, r, sAngle, eAngle) 绘制一条圆拱形路径
ctx.ellipse(cx,cy, rx, ry, sAngle, eAngle) 绘制一条椭圆拱形路径
ctx.bezierCurveTo(.....) 绘制贝塞尔曲线
/***********************/
ctx.closePath() //闭合当前路径
ctx.stroke() //使用当前路径进行描边
ctx.fill() //使用当前路径进行填充
ctx.clip() //使用当前路径进行裁切

HTML5新特性之三——SVG

前端领域可以使用绘图技术:
WebGL
Canvas —— HTML5标准中新特性
SVG —— HTML5标准中新特性

3.SVG绘图
Scalable Vector Graphic,可缩放的矢量图
位图:使用像素点描述图像,善于描述颜色细节变化,放大之后会出现马赛克问题。PS、Canvas
矢量图:使用线条、色块描述图像,不善于描述颜色细节变化,可以无限缩放而不失真。AI、SVG

 


SVG
矢量图,不依赖分辨率
每个图形都是一个标签,支持事件监听
最适合带有大型渲染区域的应用程序(例如百度地图)
不适合游戏
Canvas
位图,依赖分辨率
每个图形不是标签,不支持事件绑定
能够以“.png”或“.jpg”格式保存结果图像
最合适图像密集型的游戏

SVG在2002年就是W3C标准,远早于HTML5标准。纳入HTML5标准,SVG技术进行了一些删减
,如动画、特效。


HTML5之前如何使用SVG图形:
先创建一个.svg文件(是一个XML文档)
再创建一个.html文件,其中使用IMG、IFRAME、EMBED、OBJECT标签引用.svg文件。
HTML5之后如何使用SVG图形:
SVG相关标签都已经纳入H5标签库,可以直接在.html中使用。


4.使用SVG绘制矩形
<svg>
<rect x="200" y="160" width="100"
height="80" fill="rgba(0,0,255,.3)" stroke="#00f" id="r5"
opacity="1" stroke-width="6"></rect>

r5.onmouseover = function(){
console.log('mouse over...');
//r5.fill = 'rgba(0,255,0,.8)';
//console.log(r5);
//debugger;
r5.setAttribute('fill','rgba(0,0,255,.5)');
}
r5.onmouseout = function(){
console.log('mouse out...');
r5.setAttribute('fill','rgba(0,0,255,.3)');
}
</svg>
使用SVG图形图像需要注意:
普通CSS样式对svg图形大多无效,需要自己专用样式,或者声明为属性
SVG图形的属性都不是HTML属性,即不能使用 rect.fill = "#f00"来修改该元素的属性——
SVG标签根本上属于XML标签,而不是HTML标签! 可以使用核心DOM操作方法来控制SVG标签的属性
: setAttribute() .getAttribute()

例子1:
<script>
setInterval(function(){
//r5.x += 5;
var x = r5.getAttribute('x');
console.log(typeof x); //string
x = parseInt(x);
x += 10;
r5.setAttribute('x', x);

var o = r5.getAttribute('opacity');
o = parseFloat(o);
o -= 0.05;
r5.setAttribute('opacity',o)
},200);
</script>

例子2:
<h1>绘制矩形</h1>
<svg width="500" height="400">
<rect x="100" y="55" width="300" height="60" fill="red" opacity="1"></rect>
<rect x="100" y="170" width="300" height="60" fill="yellow" opacity="1"></rect>
<rect x="100" y="285" width="300" height="60" fill="green" opacity="1"></rect>
</svg>


<script>
var list = document.querySelectorAll('rect');
for(var i in list){
var r = list[i];
r.onclick = function(){
var me = this;
var t = setInterval(function(){
var w = me.getAttribute('width');
var h = me.getAttribute('height');
var o = me.getAttribute('opacity');
w = parseFloat(w);
h = parseFloat(h);
o = parseFloat(o);

w += 10;
h += 2;
o -= 0.05;

me.setAttribute('width',w);
me.setAttribute('height',h);
me.setAttribute('opacity',o);

if(o<=0){
clearInterval(t);
//DOM树上删除元素
me.parentNode.removeChild(me);
}
}, 100)
}
}
</script>

document.createElement()创建都是标准的HTML标签,不能用于创建SVG元素!
document.createElementNS('http://www.w3.org/2000/svg', 'SVG标签名'),
使用此方法创建的标签才能被SVG解释器解析。
例子:
<body>
<h1>使用JS动态绘制矩形</h1>
<svg id="svg8" width="500" height="400">
</svg>

<script>
svg8.onclick = function(e){
console.log('开始创建新元素');
var x = e.offsetX;
var y = e.offsetY;

//动态的创建一个矩形
var r = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
r.setAttribute('x', x);
r.setAttribute('y', y);
r.setAttribute('width', 50);
r.setAttribute('height', 50);
r.setAttribute('fill', rc());

//追加到SVG父元素
svg8.appendChild(r);
}

function rc(){
var r = Math.floor(Math.random()*256);
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
return `rgb(${r},${g},${b})`;
}
</script>


<h1>使用JS动态绘制矩形</h1>
<svg id="svg10" width="500" height="400"></svg>

<script>
svg10.onclick = function(e){
var x = e.offsetX;
var y = e.offsetY;

//创建新的SVG元素
var c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
c.setAttribute('cx', x);
c.setAttribute('cy', y);
c.setAttribute('r', 20);
c.setAttribute('fill', rc());
c.setAttribute('opacity', 1);

svg10.appendChild(c);

//启动定时器,变大变淡
var t = setInterval(function(){
var r = c.getAttribute('r');
r = parseFloat(r);
r += 5;
c.setAttribute('r', r);

var o = c.getAttribute('opacity');
o = parseFloat(o);
o -= 0.05;
c.setAttribute('opacity', o);

if(o<=0){
clearInterval(t);
c.parentNode.removeChild(c);
}
},100)
}

function rc(){
var r = Math.floor(Math.random()*256);
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
return `rgb(${r},${g},${b})`;
}
</script>

注意:offsetX offsetY 指的是鼠标相对被点击元素的左上角
pageX pageY 指的是相对文档显示区
screenX screenY 指的是相对于整个屏幕

5.使用SVG绘制圆形
<circle cx="" cy="" r="" fill="" stroke=""></circle>

<circle cx="50" cy="50" r="50"></circle>
6.使用SVG绘制椭圆
<ellipse cx="" cy="" rx="80" ry="40" ....></ellipse>
<ellipse cx="250" cy="200" rx="200" ry="100"
fill="transparent" stroke="#aaa"></ellipse>

7.使用SVG绘制直线
<line x1="" y1="" x2="" y2=""></line>


分组的概念:可以把多个SVG元素相同的属性放在一个公共的父元素中
——称为“元素组”: <g fill="" stroke=""></g>;组员会自动继承小组的属性设置。

<svg id="s12" width="500" height="400">
<g stroke="#a33" stroke-width="30">
<line x1="50" y1="50" x2="100" y2="50"></line>

<line x1="150" y1="50" x2="400" y2="50"></line>

<line x1="50" y1="100" x2="100" y2="100"></line>

<line x1="150" y1="100" x2="400" y2="100"></line>

<line x1="50" y1="150" x2="100" y2="150"></line>

<line x1="150" y1="150" x2="400" y2="150"></line>

</g>
</svg>

8.使用SVG绘制折线
<polyline points="x1,y1 x2,y2 x3,y3 .... " ></polyline>
一个点的X和Y用逗号分隔;两个点之间用空格分隔
<polyline points="250,50 50,200 250,350 450,200 250,50" stroke="#a33"
stroke-width="30" fill="transparent"></polyline>

9. 使用SVG绘制多边形
<polygon points="x1,y1 x2,y2 x3,y3 .... "></polygon>
注意:多边形与折线的区别:多边形会自动闭合起始点,折线不会。
<polygon points="250,50 50,200 250,350 450,200" stroke="#3f3"
stroke-width="10" fill="transparent"></polygon>


10.使用SVG绘制文本
<text x="" y="" font-size="" font-family="">文本内容</text>
提示:SVG中的文字是可以选中的——标签的innerHTML,Canvas中的fillText()
做不到这一点。SVG中的文字内容够容易搜索引擎查询到,排名会靠前。

<text x="0" y="100" font-size="50" font-family="SimHei">达内科技123jky</text>


11.使用SVG绘制图像
<image xlink:href="img/disc.png" x="250" y="200" width="200"
height="200"></image>
注意:SVG图形中一旦使用位图,就不能无限缩放了。

<image xlink:href="img/disc.png" x="250" y="200" width="200"
height="200"></image>

12.对SVG图形/图像使用定义特效 —— 了解
定义和使用特效:


<svg>
<defs> <!--定义/声明特效元素-->
<特性元素 id="特效ID"></特效元素>
</defs>
<rect 使用某个特效> <!--使用特效元素-->
</svg>

 

(1)渐变色特效: 线性渐变、径向渐变
<defs>
<linearGradient id="g1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="red"></stop>
<stop offset="50%" stop-color="yellow"></stop>
<stop offset="100%" stop-color="green"></stop>
</linearGradient>
</defs>
<rect x="50" y="150" width="400" height="100" fill="url(#g1)"></rect>

(2)滤镜特效: 模糊滤镜-高斯模糊
<svg id="s13" width="500" height="400">
<defs>
<filter id="mh">
<feGaussianBlur stdDeviation="3"></feGaussianBlur>
</filter>
</defs>

<text x="100" y="100" filter="url(#mh)">达内科技</text>
</svg>

例子:

<svg id="s13" width="500" height="400">
<defs>
<filter id="mh">
<feGaussianBlur stdDeviation="3"></feGaussianBlur>
</filter>
</defs>

<text x="100" y="100" font-size="50" filter="url(#mh)">达内科技</text>

<image xlink:href="img/disc.png" x="100" y="150" width="150" height="150" filter="url(#mh)"></image>
</svg>

HTML新特性之——拖放API

1.拖放API

源对象可以触发的事件(3个):
src.ondragstart:刚开始被拖动
src.ondrag:被拖动中
src.ondragend:拖动结束
目标对象可以触发的事件(4个):
target.ondragenter:源对象被拖动着进入目标对象
target.ondragover:源对象被拖动在目标对象上方
target.ondragleave:源对象被拖动着离开目标对象
target.ondrop:源对象在目标对象上方释放
提示:dragover事件的默认后续行为就是触发dragleave,即使用户松手也触发该事件。
必须阻止其默认行为,才可能触发drop事件!

拖放源对象和目标对象间如何传递数据:
(1)使用全局变量——污染全局对象
src.ondragstart:为全局变量赋值
target.ondrop:读取全局变量的值

<script>
var srcObj = null; //被拖拽的源对象

var list = document.querySelectorAll('.src');
for(var i in list){
var img = list[i];
//源对象可以触发的事件
img.ondragstart = function(){
console.log('src: drag start...');
srcObj = this;//记录拖拽的源对象
}
}

//目标对象可以触发的事件
target.ondragover = function(e){
e.preventDefault(); //使得drop可以触发
}
target.ondrop = function(){
console.log('target: drop...');
this.innerHTML = '';
var copy = srcObj.cloneNode(); //克隆一个元素
this.appendChild( copy );
srcObj.style.display = 'none';
srcObj.nextElementSibling.style.display = 'inline-block';
}
</script>

(2)拖放事件的新属性 event.dataTransfer(数据传递对象——拖拉机)
src.ondragstart:
e.dataTransfer.setData(k, v)
target.ondrop:
e.dataTransfer.getData(k)
注意:此方法只能传递string数据。
HTML5标准中:k只能是三种可能之一:text/uri-list、text/html、Files
但不同的浏览器有不同的扩展。

<script>

var list = document.querySelectorAll('.src');
for(var i in list){
var img = list[i];
//源对象可以触发的事件
img.ondragstart = function(e){
console.log('src: drag start...');
//保存被拖动的源对象的id
e.dataTransfer.setData('text/html',this.id);
}
}

//目标对象可以触发的事件
target.ondragover = function(e){
e.preventDefault(); //使得drop可以触发
console.log('target: drag over...');
}
target.ondrop = function(e){
console.log('target: drop...');
var id = e.dataTransfer.getData('text/html');
var img = document.getElementById(id);
console.log(img);
target.innerHTML = '';
target.appendChild(img.cloneNode());
}
</script>

2.扩展知识点:如何在网页中拖放显示一张客户端的图片——了解
(1)必须阻止拖放本地图片到浏览器,默认在新窗口中打开的行为
document.ondragover = function(e){
e.preventDefault();
}
document.ondrop = function(e){
e.preventDefault();
}
(3)为目标div元素绑定ondrop事件
target.ondrop = function(e){
//通过e.dataTransfer对象获取源对象拖动时传递的数据
var f0 = e.dataTransfer.files[0]; //File:文件对象
var fr = new FileReader(); //文件读取器对象
fr.readAsDataURL(f0); //读取文件内容
fr.onload = function(){ //读取完成事件
console.log('客户端文件读取完成');
var img = new Image();
img.src = fr.result;
target.appendChild(img);
}
}
<script>
//允许触发ondrop事件
document.ondragover = function(e){
e.preventDefault();
}
//阻止document.ondrop事件的默认行为——新窗口中打开图片
document.ondrop = function(e){
e.preventDefault();
}
target.ondragover = function(e){
e.preventDefault();
}
target.ondrop = function(e){
console.log('图片在div上方释放了');
var f0 = e.dataTransfer.files[0];//File
var fr = new FileReader(); //文件读取器对象
fr.readAsDataURL(f0);
fr.onload = function(){
var img = new Image();
img.src = fr.result;
target.appendChild(img);
}
}
</script>

HTML新特性之——文件操作相关对象

HTML5新增加的几个文件操作相关对象:
File:表示一个文件
FileList:表示一个文件集合
FileReader:文件读取对象,用于读取文件中的内容
FileWriter:文件写出对象,用于向文件中写出内容

2.Web Worker:

(1)操作系统:用于管理磁盘和内存,分配CPU时间片,实现程序的并发执行
(宏观上是“同时执行”,微观上是“一个一个执行”)。
(2)进程Process:可执行文件被操作系统从硬盘中调入到内存,获得执行,
称为进程/任务;进程是操作系统分配内存的基本单位。

(3)线程Thread:线程负责执行代码语句,线程是进程内部的执行代码的基本单位

(4)面试题1:进程和线程的关系?
进程是分配内存的基本单位;线程是执行代码的基本单位。线程必须处于某个进
程中,一个进程内可以同时存在1到多个线程。
(5)面试题2:Chrome中的线程模型是怎么的?
每个Chrome窗口都是一个进程,最多可以使用6个线程发起HTTP请求并接收响应消息。
但解析HTML、执行JS、CSS、绘图操作、事件监听由唯一的UI主线程执行。
(6)js文件最好放在body的最后

(7)如何执行很耗时的JS任务
方式一:(1)在页面中创建
<script src=''耗时.js"></script>
推荐放在body的最后——UI主线程只有一个!!!!!!
方式2:HTML5 中,可以创建一个新的线程,来执行耗时的JS任务
new Worker(‘耗时.js’);
由主UI线程创建一个新的“工作线程”,为其分配耗时的JS任务,
UI主线程可以继续渲染界面
(8)可以使用Worker线程加载任意的JS文件吗??

界面渲染任务只能由UI主线程执行,所以任何Worker线程都不能操作DOM树,
即window/document/dom 对象不能再Worker执行的JS中使用。
UI主线程给Worker线程传递数据:
var w1= new Worker('耗时.js');
w1.postMessage(‘字符串消息’); //传递消息
Worker接收消息:(在JS中写的)
onmessage=function(event){
//event.data //主线程发过来的消息event.data 里存的就是
主线程UI发送过来的消息,可以进行处理
}
Worker线程给UI主线程传递消息数据:
Worker 线程发送消息:
postMessage(“字符串消息”);(也是在JS中写的)
UI主线程接收消息:
// var w1=new Worker ('耗时.js');
w1. onmessage=function(event){
//event.data //对方发过来的数据
}

<script>
//用户点击按钮后,创建Worker线程
btn.onclick=function(){
//p.innerHTML="运算中";
//创建一个工作线程
var w1=new Worker('js/7.js');
//UI主线程给Worker线程传递数据
w1.postMessage(v.value);
//UI线程等待接收Worker线程的消息
w1.onmessage=function(e){
p.innerHTML=e.data;
}
}
</script>
js中:
onmessage=function(e){
var num=e.data;//获取消息
num=parseInt(num);
console.time('质数判定计时');
var result = isPrime(num);
console.timeEnd('质数判定计时');
console.log(num+'是质数吗'+result);
postMessage(num+'是质数吗'+result);

HTML新特性之——存储

3.Web Storage

服务器端存储:
服务器端文件、内存、数据库。可以存储新闻、留言、
商品、订单、评论、进入库记录、。。。

客户端存储:
应用:浏览器历史记录、内容定制、样式定制、多久之内不再登录...
客户端存储的实现方法:

(1)Cookie :服务器保存在客户端的键值对 浏览器兼容性最好,最长可保存
只能保存4kb数据(400多个汉字)
(2)Flash:依赖于Flash播放器
(3)HTML5 sessionStorage/localStorage 会话存储/本地存储
HTML5 Wbe Storage 存储 :HTML新特性 ,最长不能超过8MB
(4)IndexedDB :保存在客户端的“索引数据库”

 

HTML5 Web Storage 分为两个对象:
(1)window.sessionStorage:会话级存储
键值对形式的字符串,存储在浏览器进程的内存空间中,一个页面中保存的
数据可以供后续的所有页面使用;一旦浏览器窗口关闭、操作系统
重启,sessionStorage中的数据都会消失,其他浏览器进程不能访问
当前浏览器进程中的sessionStorage数据

总结:sessionStorage的用途:在某个浏览器窗口先后打开的多个页面间共享数据。

(2)window.localStorage:本地存储,跨会话级存储
键值对形式的字符串,存储在本地的文件系统(磁盘的文件)中,
这些数据在浏览器关闭后,甚至操作系统重启后,仍然可以使用。没有过期时间,
是永久存储

localStorage:
把数据保存在磁盘文件中,可以永久存储
localStorage.setItem(k,v)
localStorage.getItem(k)
localStorage.removeItem(k)
localStorage.clear()
localStorage.length
localStorage.key(index)

例子:单词录入系统

如何监视localStorage中存储的数据发生了改变:
window.onstorage=function(){
//localStorage对象中存储的数据发生改变了
}

如改变页面风格后,下一页面可以及时更着改变

//监视localStorage中数据的修改
window.onstorage=function(){
var s=localStorage.getItem('风格');
document.body.style.background=s;
}

HTML新特性之——WebSocket
4.WebSocket

HTTP协议:基于“请求-响应模型”的协议,没有请求,就没有响应;一个请求,
只会对应一个响应。用于呈现网页,没有问题;但是有些应用中,显得力不从心:
实时应用、聊天室....
“心跳请求”——使用 “定时器+XHR”——解决效果并不好。

WebSocket协议:基于“广播模型”的协议,只要客户端连接到服务器,就一直保持连接
/永久连接,一方不需要发消息,对方可以主动的给出消息;一方发一个消息,对方可以
给出多个应答消息。


浏览器作为客户端使用WebSocket协议进行通信步骤:
var ws = new WebSocket('ws://127.0.0.1:9999'); //创建连接
ws.onopen = function(){ //连接成功
ws.onmessage = function(e){ //接收消息
//e.data
}
ws.send(); //发送消息
}


注意:WebSocket服务器端编写比较麻烦!可以使用PHP、Java、C#、NodeJS等编写。

总结:HTML5 WebSocket用于创建使用WS协议的客户端应用,连接WS协议的服务器端应用。

1.Two.js
是一个第三方二维绘图函数库,可以在WebGL、Canvas、SVG上绘制图形,
从而屏蔽三者在使用上的不同。

2.地理定位

HTML5新特性:geolocation,用于返回当前浏览器所在的地理坐标。


window.navigator.geolocation {
getCurrentPosition(succCB, errCB) 获得当前浏览器所在定位数据
watchPosition() 使用定时器不停的获得定位数据
clearWatch() 清除监视定时器
}

 

posted on 2017-02-13 17:06  艾薇儿802388  阅读(1240)  评论(0编辑  收藏  举报