重温---HTML5高级---视频和音频

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,是否自动播放

扫描二维码关注公众号,回复: 3571387 查看本文章

(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&&deg<=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>

猜你喜欢

转载自blog.csdn.net/qq_32054169/article/details/82973734