HTML5 新特性总结--1

1.新的语义和结构元素

  <article>  定义独立的内容

  <aside>  定义页面侧边栏内容

  <bdi>  允许设置一段文本,使其脱离其父元素的文本方向设置

  <dialog>  标签定义一个对话框,确认框或窗口

    open  属性控制dialog元素是否有效,

  <figure>  规定独立的流内容 图像,图标,照片,代码等等

  <figcaption>  定义 figure 标签元素的标题

  <footer>  定义 section 或 document 的页脚

  <header>  定义文档的头部区域

  <mark>  定义带有记号的文本

  <meter>  定义度量衡。

    

 

   <nav>  定义导航链接的部分

  <progress>  定义任何类型的任务的进度

    

 

  <ruby>  定义 ruby 注释 中文注音或字符

  <rt>  定义字符(中文注音或字符)的解释或发音

  <rp>  在 ruby 注释中使用,定义不支持 ruby 元素的浏览器所显示的内容

    

  <section>  定义了文档的某个区域,比如章节、头部、底部、或者文档的其他区域

   <time>  定义日期和时间

     

 

   <wbr>  规定在文本中的何处适合添加换行符

  

 2.canvas

   2.1.用于图形的绘制,通过脚本js执行,标签只是图形容器,使用脚本绘制图形

    使用<canvas>标签时,建议成对出现,不要使用闭合的形式

    canvas 元素默认具有高宽 height: 150px; width: 300px;

   2.2.替换内容

    由于某些浏览器较老(尤其IE9之前的浏览器),不支持HTML中的canvas,这个时候要显示一些提示内容,

    例如当不支持canvas的时候就会显示span中的内容,

    支持canvas的时候,就会忽略canvas中包含的内容,正常渲染canvas

    

 

   2.3.canvas 标签的两个属性

    canvas 和 img 很像,不同的就是他没有 src 和 alt 属性,实际上 canvas 标签只有两个属性 width 和 height

    当没有设置宽高的时候就是默认值 300px 和 150px

      html 属性设置 width height 时只影响画布本身,不影响内容

      css 属性设置width height 时不但会影响画布本身的高宽,还会使画布中的内容等比例缩放(基于画布默认尺寸)

  2.4.渲染上下文

    canvas 元素只创造了一个画布,添加内容需要getContext() 的方法,这个方法是用来获得渲染上下文和他的绘画功能,

    getContext()只有一个参数,上下文格式

    2.4.1.绘制矩形

     HTML 中的元素canvas只支持一种原生的图形绘制,矩形,所有其他的图形的绘制都至少需要生成一条路径

     canvas 提供了三种绘制矩形方法:

      绘制一个填充矩形(默认填充色黑色)

 

       fillRect(x, y, width, height);

 

      绘制一个矩形边框(默认边框 1像素实心黑色) 

       strokeRect(x, y, width, height);

      清除指定矩形区域,让清除部分完全透明

       clearRect(x, y, width, height);

      x,y 指定了在 canvas 画布上所绘制的矩形的左上角的坐标,width,height设置矩形的尺寸(存在边框,边框会在width,height上占据一个边框的宽度)

     实例:在画布上绘制 150x75 的红色矩形,从左上角开始(0, 0)

      首先找到 canvas 元素

       var con = document.getElementById('test')

      然后,创建 context 对象

       var ctx = con.getContext('2d');

      绘制矩形

       ctx.fillStyle = '#FF0000';

       ctx.fillRect(0, 0, 150, 75);// 注意不加单位

    2.4.2.strokeRect 边框像素渲染问题

      正常渲染出的边框应该是1px, canvas 在渲染矩形边框时,边框宽度时平均分在偏移位置的两侧,

        context.strokeRect(10, 10, 50, 50)

        边框会渲染在 10.5 和 9.5 之间,浏览器是不会让一个像素只用自己的一半的,相当于边框会渲染在 9 到 11 之间

        context.strokeRect(10.5, 10.5, 50, 50);  边框会渲染在 10 到 11 之间

     2.4.3.添加样式和颜色

      fillStyle  设置图形的填充颜色

      strokeStyle  设置图形轮廓的颜色

        默认情况下,线条和填充颜色都是黑色 #000000

      lineWidth  这个属性设置当前绘线的粗细,属性值必须为正数

        描述线段宽度的数字,0,负数,Infinity 和 NaN 会被忽略,默认值是1.0

    2.4.4.lineWidth  覆盖渲染

    2.4.5.lineJoin

      设定线条与线条间结合处的样式(ctx.lineJoin = 'bevel')

      round  圆角

      bevel  斜角

      miter  直角(默认)

  2.5.绘制案例

    2.5.1.绘制路径  圆形的基本元素是路径,路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合

     步骤

      1.首先需要创建路径起点

      2.然后使用画布命令画出路径

      3.之后把路径封闭

      4.一旦路径生成,你就能通过描边或填充路径区域来渲染图形

    2.5.2.绘制三角形

     beginPath()

      新建一条路径,生成之后,图形绘制命令被指向到路径上准备生成路径

      生成路径的第一步叫做beginPath().本质上,路径是有很多子路径构成,这些字路径都是在一个列表中,

      所有的子路径构成图形,每次使用这个方法,列表清空重置,然后我们就可以重新绘制新的图形

     moveTo(x, y)  将笔触移动到指定的坐标x,y上

      当canvas初始化或者beginPath()调用后,你通常会使用moveTo()函数设置起点

     lineTo(x, y)  绘制一条从当前位置到指定x, y 位置的直线

     closePath()  

      闭合路径之后图形绘制命令又重新指向到上下文中,闭合路径closePath(),不是必需的,这个方法会通过绘制一条

      从当前点到开始点的直线来闭合图形,如果图形是已经闭合的,即当前点为开始点,该函数什么也不做

      当调用fill()函数时,所有没有闭合的形状都会自动闭合,所以不需要调用closePath()函数,但是调用stroke()时不会自动闭合

     stroke()  通过线条绘制图形轮廓,不会自动调用closePath()

     fill()  通过填充路径的内容区域生成实心的图形,自动调用closePath()

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas</title>
</head>
<body>
<div>
  <canvas id='test' width='600px' height='400px'></canvas>
</div>
<script type='text/javascript'>
var test = document.getElementById('test');
var ctx = test.getContext('2d');
ctx.strokeStyle = 'deeppink';// stroke颜色
ctx.lineWidth = 10;// 线宽
ctx.moveTo(50, 50);// 起始点
ctx.lineTo(50, 100);
ctx.lineTo(100, 100);
ctx.closePath();// 自动封闭图形
ctx.stroke();// 需要手动合并
// ctx.fill();// 也会自动合并路径

// ctx.beginPath();// 不清空容器中的路径,下面的ctx.fill() 会应用到上面的路径中
ctx.moveTo(100, 100);
ctx.lineTo(100, 200);
ctx.lineTo(200, 200);
ctx.fill()
</script>
</body>
</html>

      

 

 

     2.5.3.rect(x, y, width, height)

      绘制一个左上角坐标(x, y),宽高为width height 的矩形

      当该方法执行的时候,moveTo()方法自动设置坐标参数(0, 0)

      也就是说,当前笔触自动重置会默认坐标

      绘制矩形(还可以通过划线方式)

        ctx.rect(50, 50, 100, 100);

        ctx.stroke();

    2.5.4.lineCap  是canvas 2D API 指定如何绘制每一条线段末端的属性

      三个可能的值,

        butt  线段末端以方形结束(默认)

        round  圆形结束

        square  以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域

    2.5.5.save()  是canvas 2D API 通过将当前状态放入栈中,保存 canvas 全部状态的方法

      保存到栈中的绘制状态有下面部分组成;

        当前的变换矩阵

        当前的剪切区域

        当前的虚线列表

        以下属性当前的值: strokeStyle,fillStyle,lineWidth,lineCap,lineJoin....

    2.5.6.restore()  是canvas 2D API 通过在绘图状态栈中弹出顶端的状态,将 canvas 恢复到最近的保存状态的方法,

      如果没有保存状态,此方法不做任何改变

      难点:save() 和 restore()

      1.路径容器

        每次调用路径api时,都会往路径容器里做登记

        调用beginPath时,清空整个路径容器

      2.样式容器

        每次调用样式api时,都会往样式容器里做登记

        调用save()时,将样式容器里的状态压入样式栈

        调用restore()时,将样式栈的栈顶状态弹出到样式容器里,进行覆盖

      3.样式栈

        调用save()时,将样式容器里的状态压入样式栈

        调用restore()时,将样式栈的栈顶状态弹出到样式容器里,进行覆盖

  2.6.canvas 绘制圆形

    角度与弧度的js表达式  radians = (Math.PI/180)*degrees

    arc(x, y, radius, startAngle, endAngle, anticlockwise)

      画一个以(x, y)为圆心的以radius为半径的圆弧(圆),以startAngle开始到endAngle结束,

      按照anticlockwise给定的方向(默认顺时针)来生成。true顺时针,false逆时针

      x, y 为绘制圆弧所在圆上的圆心坐标

      radius为半径

      startAngle以及endAngle参数用弧度定义了开始以及结束的弧度,这些都是以x轴为基准

      参数anticlockwise 为一个布尔值,true顺时针,false逆时针

    arcTo(x1, y1, x2, y2, radius)

      根据给定的控制点和半径画一段圆弧

      肯定会从(x1, y1) 但不一定经过(x2, y2);(x2, y2) 只是控制一个方向

       实例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas</title>
  <style type='text/css'>
  * {
    margin: 0;
    padding: 0;
  }

  #test {
    background-color: pink;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
  }
  </style>
</head>
<body>
<div>
  <canvas id='test' width='300px' height='300px'></canvas>
</div>
<script type='text/javascript'>
var test = document.getElementById('test');
var ctx = test.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(300, 0);
ctx.lineTo(200, 200);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(50, 50);
ctx.arcTo(300, 0, 200, 200, 50);
// 解析:50,50  300,0  200,200,三个点组成一个角,有个为50的圆,往角里面靠,
// 靠到最里面就是arcTo画出来的图形
ctx.stroke();
</script>
</body>
</html>

       

 

     二次贝塞尔

      quadraticCurveTo(cp1x, cp1y, x, y)

       绘制二次贝塞尔曲线,cp1x, cp1y 为一个控制点, x,y 为结束点

      起始点为moveTo中指定的点

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas</title>
  <style type='text/css'>
  * {
    margin: 0;
    padding: 0;
  }

  #test {
    background-color: pink;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
  }
  </style>
</head>
<body>
<div>
  <canvas id='test' width='300px' height='300px'></canvas>
</div>
<script type='text/javascript'>
var test = document.getElementById('test');
var ctx = test.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(300, 0);
ctx.lineTo(200, 200);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(50, 50);
ctx.quadraticCurveTo(300, 0, 200, 200);
// 解析:必须经过 起始点moveTo中的点和200,200结束点的圆弧
ctx.stroke();
</script>
</body>
</html>

       

     三次贝塞尔

      bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

      绘制三次贝塞尔曲线,cp1x, cp1y为控制点1,cp2x, cp2y 为控制点2,x, y为结束点

      起始点为moveTo中指定的点

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas</title>
  <style type='text/css'>
  * {
    margin: 0;
    padding: 0;
  }

  #test {
    background-color: pink;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
  }
  </style>
</head>
<body>
<div>
  <canvas id='test' width='300px' height='300px'></canvas>
</div>
<script type='text/javascript'>
var test = document.getElementById('test');
var ctx = test.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(300, 0);
ctx.lineTo(200, 200);
ctx.lineTo(300, 300);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(50, 50);
ctx.bezierCurveTo(300, 0, 200, 200, 300, 300);
// 解析:必须经过 起始点moveTo中的点和300,300结束点的圆弧
ctx.stroke();
</script>
</body>
</html>

       

   2.7.canvas中的变换

    translate(x, y)  它是用来移动canvas的原点到一个不同的位置,x 是左右偏移量,y 是上下偏移量

      在 canvas 中 translate 是累加的

    rotate(angle)  坐标轴旋转一定的角度,接收一个参数角度(angle),它是顺时针方向的,以弧度为单位的值,旋转的中心点始终是canvas的原点,

      如果要改变它我们需要用到 translate 方法,在 canvas 中 rotate 是累加的

    scale(x, y)  x 和 y 分别是横轴和纵轴的缩放因子,他们必须是正值,为1.0什么效果都没有,否则就是缩放比例

      缩放一般我们用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大,在canvas中 scale 是累加的

     放大缩小原理,CSS像素是一个抽象单位

      放大:放大CSS像素的单位,区域内CSS像素的个数变少

      缩小:缩小CSS像素的面积,区域内CSS像素的个数变多

    

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas</title>
  <style type='text/css'>
  * {
    margin: 0;
    padding: 0;
  }

  #test {
    background-color: pink;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
  }
  </style>
</head>
<body>
<div>
  <canvas id='test' width='300px' height='300px'></canvas>
</div>
<script type='text/javascript'>
var test = document.getElementById('test');
var ctx = test.getContext('2d');
ctx.translate(50, 50);
ctx.rotate(45 * Math.PI / 180);
ctx.scale(2, 1);
ctx.beginPath();
ctx.fillRect(0, 0, 100, 100);
ctx.stroke();
</script>
</body>
</html>

      

 

     第一个为原图,第二个图是 原点沿x,y轴偏移50,坐标轴旋转45度,x轴放大2倍的效果

    矩形在canvas中不停的旋转缩放

    

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas</title>
  <style type='text/css'>
  * {
    margin: 0;
    padding: 0;
  }

  #test {
    background-color: pink;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
  }
  </style>
</head>
<body>
<div>
  <canvas id='test' width='300px' height='300px'></canvas>
</div>
<script type='text/javascript'>
var canvas = document.getElementById('test');
var ctx = canvas.getContext('2d');
let flag = 0;
let scale = 0;
let flagScale = -1;
ctx.save();
ctx.translate(150, 150);// 把坐标轴原点设为canvas中心点,要放在save()下面
ctx.fillRect(-50, -50, 100, 100);
ctx.beginPath();
ctx.restore();
setInterval(function() {
  flag++;
  ctx.clearRect(0, 0, canvas.width, canvas.height);// 把原来的图形清空,重新画
  ctx.save();
  ctx.translate(150, 150);// 把坐标轴原点设为canvas中心点,要放在save()下面
  ctx.rotate(flag * Math.PI / 180);// 旋转
  if (scale == 100) flagScale = -1; else if (scale == 0) flagScale = 1;
  scale += flagScale;
  ctx.scale(scale / 100, scale / 100);
  ctx.beginPath();
  ctx.fillRect(-50, -50, 100, 100);// 画矩形
  ctx.restore();
}, 1000 / 60)
</script>
</body>
</html>

     画一个时钟的实例

    

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>canvas</title>
  <style type='text/css'>
  * {
    margin: 0;
    padding: 0;
  }

  html, body {
    height: 100%;
    overflow: hidden;
  }

  #clock {
    background-color: pink;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
  }
  </style>
</head>
<body>
<div>
  <canvas id='clock' width='400px' height='400px'></canvas>
</div>
<script type='text/javascript'>
window.onload = function() {
  let canvas = document.getElementById('clock');
  if (canvas.getContext) {// 判断是否有画笔
    let ctx = canvas.getContext('2d');
    setInterval(function() {// 每一秒执行一次,重新画
      ctx.clearRect(0, 0, canvas.width, canvas.height);// 重画之前清空之前画的
      move();
    }, 1000);

    function move() {
      ctx.save();
      ctx.lineWidth = 8;
      ctx.strokeStyle = 'black';
      ctx.lineCap = 'round';
      ctx.translate(200, 200);
      ctx.rotate(-90 * Math.PI / 180);// 改变x轴方向
      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循环中,否则不会累加
      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();// 不能放在for循环中,否则不会累加
      ctx.lineWidth = 4;// 重设分针线宽
      for (var i = 0; i < 60; i++) {
        if (i % 5 !== 0) {// 判断分针不用画时针,即5的倍数不用画
          ctx.beginPath();
          ctx.moveTo(117, 0);// 长度为3
          ctx.lineTo(120, 0);
          ctx.stroke();
        }
        ctx.rotate(6 * Math.PI / 180);// 从i为1开始画,要放在下面,不然是从i=2开始画的
      }

      ctx.restore();

      // 时针 分针 秒针 表座
      let data = new Date();
      let s = data.getSeconds();
      let m = data.getMinutes() + s / 60;
      let h = data.getHours() + m / 60;
      h = h > 12 ? h - 12 : h;
      // 时针
      ctx.save();
      ctx.lineWidth = 14;//时针宽度
      ctx.rotate(h * 30 * Math.PI / 180);// 每小时转30度
      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);// 一分钟转6度
      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);// 一秒钟6度
      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>
</body>
</html>

   总结:

    1.canvas图像的渲染有区别于html的渲染

      canvas的渲染极快,不会出现代码覆盖后延迟渲染的问题,所以写canvas代码一定要具有同步思想

      获取上下文时,一定要先判断

      画布的高宽问题

        默认高宽 300*150

        切记一定要使用html的attribute的形式来定义画布的宽高

        通过css形式定义会缩放画布内的图像

      绘制矩形问题

        边框宽度的问题,边框宽度是在偏移量上下分别渲染一半,可能会出现小数边框

          一旦出现小数边框都会向上取整

        canvas的api只支持一种图像的直接渲染,矩形

    2.画布api

      oc.getContext('2d');

      oc.width

      oc.height

    3.上下文api

      ctx.fillRect(x, y, w, h)  填充矩形

      ctx.strokeRect(x, y, w, h)  带边框的矩形

      ctx.clearRect(0, 0, w, h)  清楚整个画布,注意原点的位置

      样式:

        ctx.fillStyle  填充的颜色

        ctx.strokeStyle  线的颜色

        ctx.lineWidth  线的宽度

        ctx.lineCap  线的两头

        ctx.lineJoin  线连接处形状

      ctx.moveTo(x, y)  将画笔抬起,点到x, y处,开始画

      ctx.lineTo(x, y)  将画笔移到x, y处

      ctx.rect(x, y, w, h)  画矩形

      ctx.arc(x, y, r, degS, degE, dir)  x,y代表圆心,r半径,degS起始角度,degE结束角度,dir方向

      ctx.arcTo(x1, y1, x2, y2, r)  两个坐标,一个半径,

        结合moveTo(x, y)使用,三个点同时用

        x,y  起始点

        x1, y1  控制点

        x2, y2  结束点

      ctx.quadraticCurveTo(x1, y1, x2, y2)

        结合moveTo(x, y)使用,三个点同时用

        x,y  起始点

        x1, y1  控制点

        x2, y2  结束点

        必须经过起点和结束点

      ctx.bezierCurveTo(x1,y1,x2,y2,x3,y3)

        结合moveTo(x, y)使用,三个点同时用

        x,y  起始点

        x1, y1  控制点

        x2, y2  控制点

        x3, y3  结束点

        必须经过起点和结束点

      ctx.beginPath()  清空路径容器

      ctx.closePath()  闭合路径

        注意fill填充都是自动闭合的,stroke才要手动闭合

      ctx.save()  将画布当前状态(样式相关,变换相关)压入到样式栈中

      ctx.restore()  将样式栈中栈顶的元素弹到样式容器中,图像最终渲染依赖样式容器

      ctx.translate(x, y)  将原点按当前坐标轴位移

      ctx.rotate(弧度)  将坐标轴按顺时针方向进行旋转

      ctx.scale(因子)  放大缩小,

 

posted @ 2020-09-28 10:09  张_Ning  阅读(151)  评论(0编辑  收藏  举报