zoukankan      html  css  js  c++  java
  • HTML5 Canvas学习

    一.SVG(Scalable Vector Graphics,可伸缩矢量图形)Canvas对比

    1.Canvas本质上是一个位图画布,其上绘制的图形是不可缩放的,不能像SVG那样可以被放大缩小。

    2.用Canvas绘制出的对象不属于页面DOM结构或者任何命名空间——这点被认为是一个缺陷。SVG图像却可以在不同的分辨率下流畅的缩放,并且支持单击检测(能检测到鼠标点击了图像上的哪个点)。

    虽然Canvas有这些不足,但是Canvas API有两方面的优势可以弥补:首先,不需要将所绘制图像中的每个图元当做对象存储,因此执行性能非常好。

    其次,在其他编程语言现有的优秀二维绘制API的基础上实现Canvas API相对来说比较简单。毕竟,二鸟在林不如一鸟在手。

    二.Canvas概述

    1.canvas是什么

    <canvas></canvas>

    默认创建一块矩形区域,宽300,高150像素,可设置border style使其可见。

    使用canvas编程,首先要获取其上下文(context.然后在上下文中执行动作,最后将这些动作应用到上下文中。

    2.Canvas坐标

    Canvas坐标从左上角开始,x轴水平右延伸,y轴垂直下延伸。左上角坐标为x=0,y=0,称作原点。

    3.浏览器支持

    检测浏览器支持代码:

    try{
    
    document.createElement(“canvas”).getContext(“2d”);
    
    document.getElementById(“support”).innerHTML=
    
    “HTML5 Canvas is supported in your browser.”;
    
    }catch(e){
    
    document.getElementById(“support”).innerHTML=
    
    “HTML5 Canvas is not supported in your browser.”;
    
    }

    不支持时替代内容写法:

    <canvas>
    
    Update your browser to enjoy canvas!
    
    </canvas>

    4.在页面中加入canvas

    1.画直线

    html
    
    <!DOCTYPE html>
    
    <html>
    
    <head lang="en">
    
        <meta charset="UTF-8">
    
        <title>canvas</title>
    
        <script  type="text/javascript" src="../js/canvas/canvas1.js"></script>
    
    </head>
    
    <body>
    
    <canvas id="diagonal" width="200" height="200" style="border:1px solid;">
    
        update your browser to support canvas
    
    </canvas>
    
    </body>
    
    </html>

    Js:

    window.addEventListener("load",drawcans,true);
    
     
    
    function drawcans() {
    
        var canvs = document.getElementById("diagonal");
    
        var context = canvs.getContext("2d");
    
        context.beginPath();
    
        context.moveTo(70, 140);
    
        context.lineTo(140, 70);
    
        context.stroke();
    
    }

    2.变换

    平移,缩放,旋转等

    下面的js代码使用translate函数实现上面同样的对角线

    function drawDiagonal(){
    
      var canvas = document.getElementById("diagonal");
    
        var context = canvas.getContext("2d");
    
        context.save() ;
    
        context.translate(70,140);
    
        context.beginPath();
    
        context.moveTo(0,0) ;
    
        context.lineTo(70,-70);
    
        context.stroke() ;
    
        context.restore();
    
    } 

    3.路径

    •  moveTo(x,y):不绘制,只是将当前位置移动到新的目标坐标(x,y)
    • lineTo(x,y):不仅将当前位置移动到新坐标(x,y,而且在两个坐标之间画一条直线。

    简而言之,上面两个函数的区别在于,moveTo就像是提起画笔,移动到新位置,而lineTo告诉canvas用画笔从纸上的旧坐标画条直线到新坐标。不过,提醒大家,不管调用那个,都不会真正画出图形,因为还没有调用stroke或者fill函数。目前只是在定义路径的位置,以便后面绘制时使用。

    closePath会将起始坐标自动作为目标坐标,和lineTo很像。还会通知canvas当前的图形已经闭合或者形成了完全封闭的区域,这对将来填充和描边非常有用。

       

    context.beginPath();
    
        context.moveTo(-25,-50);
    
        context.lineTo(-10,-80);
    
        context.lineTo(-20,-80);
    
        context.lineTo(-5,-110);
    
        context.lineTo(-15,-110);
    
     
    
        context.lineTo(0,-140);
    
     
    
        context.lineTo(15,-110);
    
        context.lineTo(5,-110);
    
        context.lineTo(20,-80);
    
        context.lineTo(10,-80);
    
        context.lineTo(25,-50);
    
        context.closePath() ;

    以上js代码可以绘制出一个松树的树冠。

    4.描边样式

    //设置使用描边样式
    
    //加宽线条
    
    context.lineWidth=4;
    
    //平滑路径接合点
    
    context.lineJoin = 'round';
    
    //将颜色改成棕色
    
    context.strokeStyle='#663300';
    
    //最后绘制树冠
    
     context.stroke();

    5.填充样式

      

     //填充树颜色为绿色
    
        context.fillStyle="#339900";
    
       context.fill();

    6.填充矩形区域

    //将填充色设为棕色
    
      context.fillStyle=’#663300’;
    
    //填充用作树干的矩形区域
    
       context.fillRect(-5,-50,10,50);

    7.绘制曲线

       context.save();
    
        context.translate(-10,350);
    
        context.beginPath();
    
        //第一条曲线向右上方弯曲
    
        context.moveTo(0,0);
    
        context.quadraticCurveTo(170,-50,260,-190);
    
     
    
        //第二条曲线向右下方弯曲
    
        context.quadraticCurveTo(310,-250,410,-250);
    
     
    
        //使用棕色的粗线条来挥之路径
    
        context.strokeStyle="#663300";
    
        context.lineWidth=20;
    
        context.stroke();
    
        context.restore();

    8.在canvas中插入图片

    //保证图片加载完才调用
    
    var Bark = new Image();
    
    Bark.src=”bark.jpg”;
    
    Bark.onload = function(){
    
    drawTrails();
    
    }

    canvas中显示图像

    context.drawImage(Bark,-5,-50,10,50);

    9.渐变

    步骤:

    ① 创建渐变对象

    ② 为渐变对象设置颜色,指明过度方式

    ③ 在context上为填充样式或者描边样式设置渐变

      

     var trunkGradient = context.createLinearGradient(-5,-50,5,-50);
    
        trunkGradient.addColorStop(0,'#663300');
    
        trunkGradient.addColorStop(0.4,'#996600');
    
        trunkGradient.addColorStop(1,'#552200');
    
        context.fillStyle=trunkGradient;
    
        context.fillRect(-5,-50,10,50);
    
        //接下来,创建垂直渐变,以用作树冠在树干上的投影
    
        var canopyShadow = context.createLinearGradient(0,-50,0,0);
    
        canopyShadow.addColorStop(0,'rgba(0,0,0,0.5)');
    
        //方向垂直向下,渐变色在很短的距离内迅速渐变为完全透明,这段长度之外的树干上没有投影
    
        canopyShadow.addColorStop(0.2,'rgba(0,0,0,0.0)');
    
     
    
        //在树干上填充投影渐变
    
        context.fillStyle=canopyShadow;
    
        context.fillRect(-5,-50,10,50);

    10.背景图

    使用createPattern函数替代之前的drawImage函数

    var Bark = new Image();
    
    Bark.src=”bark.jpg”;
    
    Bark.onload = function(){
    
    drawTrails();
    
    }
    
    //用背景图替代棕色的粗线条
    
    context.strokeStyle = context.createPattern(Bark,’repeat’);
    
    context.lineWidth=20;
    
    Context.stroke();

    11.缩放canvas对象

     //在(130,250)的位置绘制第一棵树
    
        context.save();
    
        context.translate(130,250);
    
        drawTree(context);
    
        context.restore();
    
     
    
        //在(260,500)的位置绘制第二棵树
    
        context.save();
    
        context.translate(260,500);
    
     
    
        //将第二棵树的宽高分别放大至原来的2倍
    
        context.scale(2,2);
    
        drawTree(context);
    
        context.restore();

    12.Canvas变换

       

        context.save();
    
        //X值随着Y值的增加而增加,借助拉伸变换,可以创建一颗用作阴影的倾斜的数,应用了变换以后,所有坐标都与矩阵相乘
    
        context.transform(1,0,-0.5,1,0,0);
    
        //在Y轴方向,将阴影的高度压缩为原来的60%
    
        context.scale(1,0.6);
    
        //使用透明度为20%的黑色填充树干
    
        context.fillStyle='rgba(0,0,0,0.2)';
    
        context.fillRect(-5,-50,10,50);
    
        //使用已有的阴影效果重新绘制树
    
        createCanopyPath(context);
    
        context.fill();
    
        context.restore();

    运用上面的所有变换后的图形:

     

    13.canvas文本

    Context对象的文本绘制功能由两个函数组成:

    •  fillText(text,x,y,maxwidth);
    • strokeText(text,x,y,maxwidth);

    Maxwidth是可选的,用于限制字体的大小,它将文字强制收缩到指定尺寸。

    //在canvas上绘制标题文本
    
        context.save();
    
        context.font='60px impact';
    
        //将文本填充为棕色
    
        context.fillStyle='#996600';
    
        //将文本设为居中对齐
    
        context.textAlign='center';
    
        //在canvas顶部中央的位置以大字体的样式显示文本
    
        context.fillText('Merry  Christmas!',200,60,400);
    
        context.restore();

    最后显示如下,是不是很欢快的感觉,绘制的还是很不错的。

    14.应用阴影

      //设置文字阴影的颜色为黑色,透明度为20%
    
        context.shadowColor ='rgba(0,0,0,0.2)';
    
        //将阴影向右移动15px,向上移动10px
    
        context.shadowOffsetX=15;
    
        context.shadowOffsetY = -10;
    
        //轻微模糊阴影
    
        context.shadowBlur=2;
    
     

    最终效果图:

     

    三.完整代码

    JS:

     window.addEventListener("load",drawTrails,true);
    //绘制松树树冠
    function createCanopyPath(context){
        context.beginPath();
        context.moveTo(-25,-50);
        context.lineTo(-10,-80);
        context.lineTo(-20,-80);
        context.lineTo(-5,-110);
        context.lineTo(-15,-110);
    
        context.lineTo(0,-140);
    
        context.lineTo(15,-110);
        context.lineTo(5,-110);
        context.lineTo(20,-80);
        context.lineTo(10,-80);
        context.lineTo(25,-50);
        context.closePath() ;
    
    }
    function drawTrails(){
        var canvas = document.getElementById("diagonal");
        var context = canvas.getContext("2d");
        //在(130,250)的位置绘制第一棵树
        context.save();
        context.translate(130,250);
        drawTree(context);
        context.restore();
    
        context.save();
        context.translate(-10,350);
        context.beginPath();
        //第一条曲线向右上方弯曲
        context.moveTo(0,0);
        context.quadraticCurveTo(170,-50,260,-190);
    
        //第二条曲线向右下方弯曲
        context.quadraticCurveTo(310,-250,410,-250);
    
        //使用棕色的粗线条来挥之路径
        context.strokeStyle="#663300";
        context.lineWidth=20;
        context.stroke();
        context.restore();
        //在(260,500)的位置绘制第二棵树
        context.save();
        context.translate(260,500);
    
        //将第二棵树的宽高分别放大至原来的2倍
        context.scale(2,2);
        drawTree(context);
        context.restore();
    
        //在canvas上绘制标题文本
        context.save();
        context.font='60px impact';
        //将文本填充为棕色
        context.fillStyle='#996600';
        //将文本设为居中对齐
        context.textAlign='center';
        //在canvas顶部中央的位置以大字体的样式显示文本
    
        //设置文字阴影的颜色为黑色,透明度为20%
        context.shadowColor ='rgba(0,0,0,0.2)';
        //将阴影向右移动15px,向上移动10px
        context.shadowOffsetX=15;
        context.shadowOffsetY = -10;
        //轻微模糊阴影
        context.shadowBlur=2;
        context.fillText('Merry  Christmas!',200,60,400);
        context.restore();
    
    
    
    }
    
    
    function drawTree(context){
        context.save();
        var trunkGradient = context.createLinearGradient(-5,-50,5,-50);
        trunkGradient.addColorStop(0,'#663300');
        trunkGradient.addColorStop(0.4,'#996600');
        trunkGradient.addColorStop(1,'#552200');
        context.fillStyle=trunkGradient;
        context.fillRect(-5,-50,10,50);
        //接下来,创建垂直渐变,以用作树冠在树干上的投影
        var canopyShadow = context.createLinearGradient(0,-50,0,0);
        canopyShadow.addColorStop(0,'rgba(0,0,0,0.5)');
        //方向垂直向下,渐变色在很短的距离内迅速渐变为完全透明,这段长度之外的树干上没有投影
        canopyShadow.addColorStop(0.2,'rgba(0,0,0,0.0)');
    
        //在树干上填充投影渐变
        context.fillStyle=canopyShadow;
        context.fillRect(-5,-50,10,50);
    
        createCanopyPath(context);
        context.restore() ;
    
    
        context.save();
        //设置使用描边样式
        context.lineWidth=4;
        context.lineJoin = 'round';
        context.strokeStyle='#663300';
        context.stroke();
        //填充数颜色
        context.fillStyle="#339900";
        context.fill();
        context.restore();
    
        context.save();
        //X值随着Y值的增加而增加,借助拉伸变换,可以创建一颗用作阴影的倾斜的数,应用了变换以后,所有坐标都与矩阵相乘
        context.transform(1,0,-0.5,1,0,0);
        //在Y轴方向,将阴影的高度压缩为原来的60%
        context.scale(1,0.6);
        //使用透明度为20%的黑色填充树干
        context.fillStyle='rgba(0,0,0,0.2)';
        context.fillRect(-5,-50,10,50);
        //使用已有的阴影效果重新绘制树
        createCanopyPath(context);
        context.fill();
        context.restore();
    
    }

    HTML:

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>canvas</title>
        <script  type="text/javascript" src="../js/canvas/canvas1.js"></script>
    </head>
    <body>
    <canvas id="diagonal" width="410" height="510" style="border:1px solid;">
        update your browser to support canvas
    </canvas>
    </body>
    </html>
  • 相关阅读:
    SaltStack(六) 案例练习
    SaltStack(五) SaltStack与ZeroMQ
    SaltStack(四) 配置管理
    SaltStack(三) 远程执行
    js 阳历、阴历互转
    把一个服务器的数据库导入到另一台服务器中
    vue项目 px自动转vw
    oracle创建自增序列和触发器
    svn 无法clean up的解决方案
    vue 后台获取路由表,addRouters动态路由
  • 原文地址:https://www.cnblogs.com/jsStudyjj/p/5022485.html
Copyright © 2011-2022 走看看