1.1 面试题:flash被HTML5取代在哪些方面?
音频和视频 -----<video>和<audio>
绘图 -----<canvas>
动画 -----<canvas>+定时器
统计图表 ------<canvas><svg>
客户端数据存储----webstorage
2.2 HTML5新特性---视频播放
HTML5提供了一个新的标签<video>标签,用于播放视频.该标签默认是一个300*150的inline-block.使用方法:
<video src="x.mp4"><video>
<video>
<source src="x.mp4">
<source src="x.ogg">
<source src="x.webm">
</video>
video元素/对象的属性:
(1)src:指定要播放的资源的路径
(2)autoplay:false,是否自动播放
(3)controls:false,是否显示播放控件.提示:不同浏览器的播放控件外观不同
(4)currentTime:0,当前播放的时间点(s)
(5)duration:60,影片总时长(s)
(6)ended:false,是否播放到结尾
(7)loop:false,是否循环播放
(8)muted:false,是否静音
(9)volumn:音量设置(0-1),对象属性,不用于标签
(10)paused:false,当前是否处于暂停
(11)poster:'',指定视频第一帧播放前的电影海报
(12)preload:指定视频预加载方案,可取值
auto:默认值,自动预加载视频的宽高,时长,第一帧内容,并缓冲了一定的时长
metadata:元数据,只预加载视频的宽高,时长,第一帧内容
none:不预加载任何内容
video对象的方法;
play():开始播放
pause():暂停播放
video对象的事件:
onplay:视频开始播放(可能多种原因引起)
onpause:视频开始暂停(可能多种原因引起)
浏览器中内置的视频解码器:
练习:
(1)不使用video默认的播放控件,使用自定义的按钮,控制视频的播放和暂停
(2)不论何种原因,影片一暂停即显示出广告图片;一播放广告图片就隐藏;提示:不能使用poster属性(影片海报只能在第一次播放之前显示一次)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.container{
position: relative;
text-align: center;
}
#btn{
position: absolute;
left:50%;
top:50%;
margin-left:-32px;
margin-top:-32px;
opacity:0.9;
cursor: pointer;
}
#ad{
position: absolute;
left:50%;
top:50%;
margin-left:-100px;
margin-top:-75px;
opacity:0.9;
cursor: pointer;
}
</style>
</head>
<body>
//不适用video默认的播放控件,使用自定义的按钮,控制视频的播放和暂停//
//不论何种原因,影片一暂停就显示出广告图片;一播放广告图片就隐藏;不能使用poster属性
<h3>视频播放</h3>
<div class="container">
<video src="./res/birds.mp4" id="v4"></video>
<img src="./img/2.jpg" alt="" id="ad">
<img src="./img/play.png" alt="" id="btn">
</div>
<script>
// 为播放按钮绑定时间监听
btn.onclick=function () {
if(v4.paused){
v4.play();
btn.src="./img/pause.png";
}else{
v4.pause();
btn.src="./img/play.png";
}
}
// 为父容器绑定鼠标移出事件
var container=document.querySelector('.container');
container.onmouseenter=function () {
btn.style.display='block';
}
container.onmouseleave=function () {
btn.style.display='none';
}
//监视视频的播放和暂停,修改广告图片的图片
v4.onplay=function () {
ad.style.display='none';
}
v4.onpause=function () {
ad.style.display='block';
}
</script>
</body>
</html>
1.3 HTML5新特性---音频播放
HTML5提供了一个新的标签<audio>标签,用于播放音频.该标签若没有controls属性,则默认默认display:none,反之则是一个是一个300*30的inline-block.使用方法:
<audio src="x.mp3"><audio>
<audio>
<source src="x.mp3">
<source src="x.ogg">
<source src="x.wav">
</audio>
audio元素/对象的属性:
(1)src:指定要播放的资源的路径
(2)autoplay:false,是否自动播放
(3)controls:false,是否显示播放控件.提示:不同浏览器的播放控件外观不同
(4)currentTime:0,当前播放的时间点(s)
(5)duration:60,影片总时长(s)
(6)ended:false,是否播放到结尾
(7)loop:false,是否循环播放
(8)muted:false,是否静音
(9)volumn:音量设置(0-1),对象属性,不用于标签
(10)paused:false,当前是否处于暂停
(11)poster:'',指定视频第一帧播放前的电影海报
(12)preload:指定视频预加载方案,可取值
auto:默认值,自动预加载视频的宽高,时长,第一帧内容,并缓冲了一定的时长
metadata:元数据,只预加载视频的宽高,时长,第一帧内容
none:不预加载任何内容
video对象的方法;
play():开始播放
pause():暂停播放
video对象的事件:
onplay:视频开始播放(可能多种原因引起)
onpause:视频开始暂停(可能多种原因引起)
浏览器中内置的音频解码器:
练习:为网页添加自动播放的背景音乐,用户可以选择播放或者暂停
<body>
<h3>音频播放</h3>
<audio src="./res/bg.mp3" id="bgAudio" autoplay></audio>
<input type="checkbox" id="cb" checked>
<span id="msg">播放/暂停背景音乐</span>
<script>
cb.onchange=function () {
var c=this.checked;//当前是否选中
if(c){
bgAudio.play();
}else {
bgAudio.pause();
}
}
</script>
</body>
提示:
(1)<body bgsound="x.mp3">属性是老IE的专有属性,也可以用于播放背景音乐,但音量,静音,暂停和停止都无法精确控制.其他浏览器不支持此属性
(2)当前iOS的Safari浏览器默认不支持audio标签,只能使用video标签代替
1.4 web前端中可用的绘图技术
在网页中绘图可以使用的功能:
(1)实时走势图
(2)统计图表
(3)随机内容的图片
(4)在线画图板
(5)HTML5游戏-2D/3D
可用的绘图技术:
(1)canvas---专用于绘制2D图形/图像
(2)SVG技术---专用于绘制矢量图
(3)WebGLobal技术---目前不是HTML5标准技术,功能最强大,3D图形/图像
1.5 canvas绘图技术---最重要&难点
难点:(1)小学/中学数学知识 (2)单词记忆
HTML5引入了<canvas>标签用于绘图,默认是一个300*150的inline-block.使用width.height属性执行尺寸,但不能使用css样式指定宽和高.
<canvas width="600" height="500">
您的浏览器不支持canvas标签!
</canvas>
往"画布"上绘图需要使用其对应的"画笔"对象:
var ctx=c.getContext('2d'); //绘图上下文---"画笔"
接下来所用的绘图任务都由画笔实现.
绘图上下文对象的常用属性---console.log(ctx):
fileStyle:"#000",填充样式
strokeStyle:"#000",描边/轮廓样式
linewidth:1,描边/轮廓的宽度
font:' 10px sans-serif',绘制文本所用的字号/字体
textBaseline:'alphabetical',文本对齐的基线
shadowOffsetX:0,阴影水平偏移量
shadowOffsetY:0,阴影竖直偏移量
shadowColor:'rgba(0,0,0,0)',阴影颜色
shadowBlur:0,阴影模糊半径
1.6 使用canvas绘制矩形
提示:矩形的定位点在自己左上角
ctx.fillStyle="#000" 填充颜色
ctx.strokeStyle="#000" 描边颜色
ctx.fillRect(x,y,w,h) 填充一个矩形
ctx.strokeRect(x,y,w,h) 描边一个矩形
ctx.clearRectangle(x,y,w,h) 清除一个矩形范围内容的所有内容
练习:在600*400的画布上绘图
(1)左上角填充一个矩形100*80,默认颜色
(2)右上角描边一个矩形100*80,默认颜色
(3)左下角填充一个矩形100*80,红色
(4)右下角描边一个矩形100*80,青色
(5)正中央描边一个矩形100*80,注意是什么颜色
<body>
<h3>canvas 绘图</h3>
<canvas id="c8" width="600" height="400">
您的浏览器不支持canvas标签!
</canvas>
<script>
//获得画布对应的画笔
var ctx=c8.getContext('2d');
//左上角填充矩形
ctx.fillRect(0,0,100,80);
//右上角描边矩形
ctx.lineWidth=10;
ctx.strokeRect(500-5,0+5,100,80);
//左下角填充矩形
ctx.fillStyle="#f00";
ctx.fillRect(0,320,100,80);
//右下角描边矩形
ctx.strokeStyle="#0f0";
ctx.strokeRect(500,320,100,80);
//正中央填充+描边一个矩形
ctx.fillRect(250,160,100,80);
ctx.strokeRect(250,160,100,80);
</script>
</body>
(6)重新创建一个画布,在左上角绘制一个矩形,使用定时器,绘制一个可以不断向右移动的矩形
<body>
<h3>canvas 绘图</h3>
<canvas id="c8" width="600" height="400">
您的浏览器不支持canvas标签!
</canvas>
<script>
//获得画布对应的画笔
var ctx=c8.getContext('2d');
//可以慢慢边长的矩形
var x=0;
setInterval(function () {
//清除画布上的已有内容
ctx.clearRect(0,0,600,400);
x+=5;
ctx.strokeRect(x,0,100,80);
},41);
</script>
</body>
(7)绘制一个斜向30移动的矩形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>canvas 绘图</h3>
<canvas id="c8" width="600" height="400">
您的浏览器不支持canvas标签!
</canvas>
<script>
//获得画布对应的画笔
var ctx=c8.getContext('2d');
//想右下30度角移动的矩形
var x=0;
var y=0;
setInterval(function () {
//清画布
ctx.clearRect(0,0,600,400);
x+=5;
y+=5*Math.tan(30*Math.PI/180);
ctx.strokeRect(x,y,100,80);
},41);
</script>
</body>
</html>
(8)绘制一个绕圆形路径移动的矩形
1.7 使用canvas绘制文本
提示:文字的定位点默认在文本基线的起点(左侧)
ctx.textBaseline='alphabatic',文本基线,可取为top/bottom/middle/alphabetical
ctx.fillText(txt,x,y) 填充文本
ctx.stroke(txt,x,y) 描边文本
ctx.measureText(txt).width 测量,根据当前指定的字号和字体计算指定文本的宽度
练习:绘制文本
(1)在左下角绘制一行文本
(2)在右下角描边一行文本
(3在画布 中央绘制一个可以向右移动的文本,向户外LED招牌一样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>canvas 绘图</h3>
<canvas id="c8" width="600" height="400">
您的浏览器不支持canvas标签!
</canvas>
<script>
//获得画布对应的画笔
var ctx=c8.getContext('2d');
//文本基线设为top
ctx.font='80px SimHei';
ctx.textBaseline='top';
//左下角填充文本
var txt="达内科技";
ctx.fillText(txt,0,320);
ctx.fillStyle='#f00';
//右下角描边文本
var txt="达内科技";
var w=ctx.measureText(txt).width;
ctx.strokeText(txt,600-w,320);
ctx.shadowColor="#888";
ctx.shadowOffsetX=8;
ctx.shadowOffsetY=8;
ctx.shadowBlur=10;
//从左到右移动的文字
var x=-w;
var y=200-10;
setInterval(function () {
//清画布
ctx.clearRect(0,0,600,400);
ctx.fillText(txt,x,y);
x+=10;
if(x>=600){//即将移出屏幕,则再次回到左侧
x=-w;
}
},100);
//渐变
//创建渐变对象
var g=ctx.createLinearGradient(100,400,500,400);
g.addColorStop(0,'#f00'); //添加颜色点
g.addColorStop(0.5,'#ff0'); //添加颜色点
g.addColorStop(1,'#0f0'); //添加颜色点
//使用渐变对象
ctx.fillStyle=g;
ctx.fillRect(100,400,500,400);
</script>
</body>
</html>
1.8 使用canvas绘制路径(path)
提示:canvas中的路径概念与PhotoShop中的钢笔工具类似的.路径本身是不可见的,有三个用途:描边,填充(闭合),裁剪(闭合)
canvas中与路径绘制相关的绘制方法:
ctx.beginPath() //开始一条新路径
ctx.closePath() //闭合路径,让最后一个锚点自动连接到第一个锚点
ctx.moveTo(x,y) //移动到指定点
ctx.lineTo(x,y) //从当前点到指定点绘制直线路径
ctx.arc() //绘制拱形路径
ctx.ellipse() //绘制椭圆路径
ctx.bezierCurveTo() //绘制贝塞尔曲线
ctx.stroke();
ctx.fill();
ctx.clip();
练习:
(1)使用直线路径绘制一个坐标轴
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---坐标轴</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
//绘制x轴
ctx.beginPath();
ctx.moveTo(50,350); //坐标轴原点
ctx.lineTo(550,350); //最右侧点
ctx.lineTo(550-20,350-20);
ctx.moveTo(550,350);
ctx.lineTo(550-20,350+20);
ctx.lineWidth=5;
ctx.strokeStyle='#f00';
// ctx.lineJoin='bevel';//斜面,修改折线拐点处的样式
ctx.lineJoin='round';//圆角,修改折线拐点处的样式
// ctx.lineJoin='miter';//尖角,修改折线拐点处的样式
ctx.stroke();
//绘制Y轴 最顶点(50,50)
ctx.beginPath(); //注意此处!
ctx.moveTo(50-20,50+20);
ctx.lineTo(50,50);
ctx.lineTo(50+20,50+20);
ctx.moveTo(50,50);
ctx.lineTo(50,350);
ctx.strokeStyle='#0f0';
ctx.stroke();
</script>
</body>
</html>
(2)使用圆拱+定时器绘制可以前进的进度条
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#f0f0f0;
}
</style>
</head>
<body>
<h3>绘制路径---圆拱进度条</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
//绘制变色的进度环
var start=-Math.PI/2;
var deg=-5; //进度环前进的角度
// var end=-Math.PI/2;
var timer;
timer = setInterval(function () {
//清除画布
ctx.clearRect(0,0,600,400);
//绘制灰色的圆环
ctx.beginPath();
ctx.arc(300,200,100,0,2*Math.PI);
ctx.strokeStyle="#aaa";
ctx.lineWidth=15;
ctx.stroke();
ctx.beginPath(); //注意此处!
deg += 5;
// end+=5*Math.PI/180; //每次前进5度
ctx.arc(300, 200, 100, start, start + deg * Math.PI / 180);
//绘制进度文本
ctx.textBaseline = "top";
ctx.font='40px SimHei';
ctx.fillText(deg + "%", 300 - ctx.measureText(deg).width / 2, 180);
if (deg >= 0 && deg <= 90) {
ctx.strokeStyle = "#f00";
} else if (deg >= 90 && deg <= 180) {
ctx.strokeStyle = "#d60";
} else if (deg >= 180 && deg <= 270) {
ctx.strokeStyle = "#064";
} else if(deg>=270&°<=360){
ctx.strokeStyle = "#00f";
deg=355;
}else{
clearInterval(timer);
}
ctx.stroke();
}, 100);
</script>
</body>
</html>
(3)创建一个函数:openMouth(),在画布上绘制如下的图形:
(4)创建一个函数:closeMouth(),在画布上绘制如下的图形:
(5)使用定时器,不停的调用openMouth()和closeMouth();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---张嘴闭嘴</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
// openMouth();
// closeMouth();
//吃豆人张嘴
function openMouth() {
//外围轮廓:半圆环+斜线到圆心+闭合
ctx.beginPath();
ctx.arc(300,200,100,Math.PI/4,7*Math.PI/4);
ctx.lineTo(300,200);
ctx.closePath();
ctx.stroke();
ctx.fillStyle='#fea';
ctx.fill();
//眼睛的外框
ctx.beginPath();
ctx.arc(300,150,25,0,2*Math.PI);
ctx.stroke();
ctx.fillStyle='#38f';
ctx.fill();
//两个眼神光
ctx.beginPath();
ctx.arc(315,140,5,0,2*Math.PI);
ctx.arc(308,133,3,0,2*Math.PI);
ctx.fillStyle='#fff';
ctx.fill();
}
//吃豆人闭嘴
function closeMouth() {
//外围轮廓:圆环+直线到圆心
ctx.beginPath();
ctx.arc(300,200,100,0,2*Math.PI);
ctx.lineTo(300,200);
ctx.closePath();
ctx.fillStyle='#fea';
ctx.fill();
ctx.stroke();
//眼睛的外框
ctx.beginPath();
ctx.arc(300,150,25,0,2*Math.PI);
ctx.stroke();
ctx.fillStyle='#38f';
ctx.fill();
//两个眼神光
ctx.beginPath();
ctx.arc(315,140,5,0,2*Math.PI);
ctx.arc(308,133,3,0,2*Math.PI);
ctx.fillStyle='#fff';
ctx.fill();
}
var isOpen=true; //是否处于张嘴状态
setInterval(function () {
//清除画布
ctx.clearRect(0,0,600,400);
if(isOpen){
closeMouth();
isOpen=false;
}else {
openMouth();
isOpen=true;
}
},500);
</script>
</body>
</html>
1.9 使用canvas绘制图像
提示:图片的定位点在图片的左上角.客户端js必须等待图片加载完成才能开始绘制.
ctx.drawImage(img,x,y);
var img=new Image();
img.src='x.jpg';
img.onload=function(){
//图片已经加载完成了
ctx.drawImage(img,x,y); //使用默认的宽高
ctx.drawImage(img,x,y,w,h);
}
练习:
(1)在画布的四个角各绘制一个小飞机
(2)在画布的中央绘制一个2倍标准大小的飞机
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---图像</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
var p3=new Image();
p3.src="./img/p3.png";
p3.onload=function () {
console.log(p3.width,p3.height);
//画布左上角的小飞机
ctx.drawImage(p3,0,0);
//画布左下角的小飞机
ctx.drawImage(p3,0,400-p3.height);
//画布右下角的小飞机
ctx.drawImage(p3,600-p3.width,400-p3.height);
//画布右上角的小飞机
ctx.drawImage(p3,600-p3.width,0);
//画布正中央的小飞机
ctx.drawImage(p3,300-p3.width,200-p3.height,400,200);
}
</script>
</body>
</html>
(3)绘制一个可以随鼠标而移动的小飞机,提示需要使用mousemove
注意:canvas绘图中,只有一个HTML元素---canvas!!其他图形图像都不是元素,不能绑定时间函数!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---图像</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
var p3=new Image();
p3.src="./img/p3.png";
p3.onload=function () {
//为canvas元素绑定事件监听
c3.onmousemove=function (e) {
ctx.clearRect(0,0,600,400);
var x=e.offsetX; //事件相对于事件源的坐标
var y=e.offsetY;
ctx.drawImage(p3,x-p3.width/2,y-p3.height/2);
}
}
</script>
</body>
</html>
(4)绘制一个可以左右移动的小飞机
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---左右晃动的飞机</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
var p3=new Image();
p3.src="./img/p3.png";
p3.onload=function () {
var x=0;
var xDirection=1; //横向的移动方向,1或者-1;
var y=0;
setInterval(function () {
ctx.clearRect(0,0,600,400);
x+=5*xDirection;
if(x>=600-p3.width){ //已到最右侧
xDirection=-1; //-1相当于左移
}else if(x<=0){ //已到最左侧
xDirection=1; //1代表右移
}
ctx.drawImage(p3,x,y);
},41);
}
</script>
</body>
</html>
(5)绘制一个可以在画布范围内走斜线移动的小飞机---碰到画布的任何一个边缘,立即反弹.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---上下移动的飞机</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
var p3=new Image();
p3.src="./img/p3.png";
p3.onload=function () {
//碰撞弹回算法
var x=0;
var xDirection=1; //1(右) 或-1(左)
var y=0;
var yDirection=1; //1(下)或-1(上)
setInterval(function () {
ctx.clearRect(0,0,600,400);
x+=5*xDirection;
y+=5*yDirection;
if(x>=600-p3.width){ //已到最右侧
xDirection=-1; //-1相当于左移
}else if(x<=0){ //已到最左侧
xDirection=1; //1代表右移
}
if(y>=400-p3.height){ //已到最下侧
yDirection=-1; //-1相当于上移
}else if(y<=0){ //已到最上侧
yDirection=1; //1代表下移
}
ctx.drawImage(p3,x,y);
},41);
}
</script>
</body>
</html>
小结:canvas绘图可以绘制的内容:
(1)矩形 ctx.fillRect() ctx.strokeRect() ctc.clearRect()
(2)文本 ctx.fillText() ctx.strokeText() ctx.clearRect()
(3)路径---描边/填充/裁剪
ctx.beginPath() ctx.closePath();
ctx.moveTo() ctx.linTo() ctx.arc()
ctx.stroke() ctx.fill() ctx.clip()
(4)图像 ctx.drawImage()
(5)恢复
绘图上下文的状态改变和修改---难点&晦涩
var ctx=canvas.getContext('2d');
//可以将绘图上下文对象进行变形(transform)---与对canvas施加css transform样式不同,绘图上下文的变形只影响当前绘制的图形图像内容
ctx.translate(x,y); //坐标轴原点平移到指定点,所有点的左边都发生改变
ctx.rotate(deg); //画笔旋转,则内容旋转,轴点在坐标轴原点
ctx.scale(); //画笔缩放
练习:绘制一个绕自己中心轴旋转的小飞机
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---旋转的飞机</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
var p3=new Image();
p3.src="./img/p3.png";
p3.onload=function () {
ctx.translate(300,200);
setInterval(function () {
//只有当坐标轴原点(即旋转的轴点)在飞机的中央,才能保证飞机绕中央旋转
ctx.clearRect(-300,-200,600,400);
ctx.rotate(10*Math.PI/180);
ctx.drawImage(p3,-100,-50);
},41);
}
</script>
</body>
</html>
练习:有点坑---绘制四个小飞机,各在画布的一个角绕着自己的中心在旋转
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---四个旋转的飞机</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
var p3=new Image();
p3.src="./img/p3.png";
p3.onload=function () {
var deg=0; //飞机旋转的角度
setInterval(function () {
ctx.clearRect(0,0,600,400);
deg+=5;
//绘制左上角的小飞机
ctx.translate(200/2,100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.rotate(-deg*Math.PI/180);
ctx.translate(-200/2,-100/2);
//此飞机对画笔的修改最终全部恢复原样
//绘制右上角的小飞机
ctx.translate(600-200/2,100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.rotate(-deg*Math.PI/180);
ctx.translate(-(600-200/2),-100/2);
//此飞机对画笔的修改最终全部恢复原样
//绘制左下角的小飞机
ctx.translate(200/2,400-100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.rotate(-deg*Math.PI/180);
ctx.translate(-200/2,-(400-100/2));
//此飞机对画笔的修改最终全部恢复原样
//绘制右下角的小飞机
ctx.translate(600-200/2,400-100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.rotate(-deg*Math.PI/180);
ctx.translate(-(600-200/2),-(400-100/2));
//此飞机对画笔的修改最终全部恢复原样
},41);
}
</script>
</body>
</html>
利用save简化代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
canvas{
background:#aaa;
}
</style>
</head>
<body>
<h3>绘制路径---四个旋转的飞机</h3>
<canvas id="c3" width="600" height="400"></canvas>
<script>
var ctx=c3.getContext('2d');
var p3=new Image();
p3.src="./img/p3.png";
p3.onload=function () {
var deg=0; //飞机旋转的角度
setInterval(function () {
ctx.clearRect(0,0,600,400);
deg+=5;
//绘制左上角的小飞机
ctx.save(); //保存画笔当前的变形状态
ctx.translate(200/2,100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.restore(); //恢复到上一次的保存的变形状态
//此飞机对画笔的修改最终全部恢复原样
//绘制右上角的小飞机
ctx.save();
ctx.translate(600-200/2,100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.restore();
//此飞机对画笔的修改最终全部恢复原样
//绘制左下角的小飞机
ctx.save();
ctx.translate(200/2,400-100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.restore();
//此飞机对画笔的修改最终全部恢复原样
//绘制右下角的小飞机
ctx.save();
ctx.translate(600-200/2,400-100/2); //原点平移
ctx.rotate(deg*Math.PI/180);
ctx.drawImage(p3,-200/2,-100/2);
ctx.restore();
//此飞机对画笔的修改最终全部恢复原样
},41);
}
</script>
</body>
</html>
1.10 为图形文字添加阴影
ctx.shadowColor="#888"; //阴影颜色
ctx.shadowOffsetX=8; //阴影偏移量
ctx.shadowOffsetY=8;
ctx.shadowBlur=10; //阴影模糊半径
1.11 在绘图时使用渐变色
//创建渐变对象
var g=ctx.createLinearGradient(100,400,500,400);
g.addColorStop(0,'#f00'); //添加颜色点
g.addColorStop(0.5,'#ff0'); //添加颜色点
g.addColorStop(1,'#0f0'); //添加颜色点
//使用渐变对象
ctx.fillStyle=g;
ctx.fillRect(100,400,500,400);
课后练习:
(1)使用视频做DIV元素的背景
提示:Video自动播放、循环播放、静音,绝对定位到目标元素下面,z-index为负值即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
margin:0;
}
.main{
border:1px solid #ddd;
width:100%;
position: relative;
overflow: hidden;
}
.main:before{
content:'';
display:table;
}
.main:after{
content:'';
display:table;
clear: both;
}
.container{
width:500px;
margin:80px auto;
background:rgba(255,255,255,.6);
border:1px solid #ddd;
border-radius:4px;
}
.bg-video{
position: absolute;
left:0;
top:-200px;
z-index: -1;
}
</style>
</head>
<body>
<h1>使用视频做背景的div</h1>
<div class="main">
<div class="container">
<h4>注册新用户</h4>
<h4>注册新用户</h4>
<h4>注册新用户</h4>
<h4>注册新用户</h4>
<h4>注册新用户</h4>
<h4>注册新用户</h4>
</div>
<video class="bg-video" src="./res/birds.mp4" width="100%" autoplay loop muted></video>
</div>
</body>
</html>
(2)使用AJAX从服务器端的PHP页面获取如下的JSON数据:
[
{"label": "部门1", "value":300},
{"label": "部门2", "value":500},
{"label": "部门3", "value":150},
{"label": "部门4", "value":400},
{"label": "部门5", "value":550},
{"label": "部门6", "value":250}
]
根据这些数据,绘制出如下图所示的统计图:
提示:为简化起见,可以把value值看做每个柱的高度。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
text-align: center;
}
#c2{
background: #f0f0f0;
//不用css指定canvas的宽和高
/*width:800px;*/
/*height:600px;*/
}
</style>
</head>
<body>
<canvas id="c2"></canvas>
<h3>canvas绘制统计图</h3>
<script src="./js/jquery-1.11.3.js"></script>
<script>
setInterval(function () {
},1000);
var w=800; //画布的宽
var h=600; //画布的高
c2.width=w;
c2.height=h;
var ctx=c2.getContext("2d");
//绘制边框轮廓
ctx.strokeRect(50,50,w-100,h-100);
//异步请求服务器端数据
$.ajax({
type:'GET',
url:'./data/2.json',
success:function (list) {
//数据/柱子的数量
var count=list.length;
//每个柱子的宽度
var colWidth=(w-100)/(2*count+1);
//遍历list数据,绘制每个柱子
for(var i=0;i<list.length;i++){
var data=list[i]; //每个数据
var rw=colWidth; //矩形的宽
var rh=data.value; //矩形的高
var x=(2*i+1)*colWidth+50;
var y=h-rh-50;
ctx.strokeRect(x,y,rw,rh);
//使用渐变色进行填充
var g=ctx.createLinearGradient(x,y,x,y+rh);
g.addColorStop(0,rc()); //随机色
g.addColorStop(1,'#fff'); //白色
ctx.fillStyle=g;
ctx.fillRect(x,y,rw,rh);
}
}
});
//randow color
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>
</html>