zoukankan      html  css  js  c++  java
  • canvas的基本使用

    一、定义

    • canvas最早是由Apple引入Webkit的,<canvas>元素包含于HTML5中
    • HTML5的canvas元素使用JavaScript在网页上绘制图像,画布是一个矩形区域,可以控制其每一像素,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法

    二、基本使用(步骤)

    ①创建canvas元素,向HTML5页面添加canvas元素(准备画布)

    ②设置画布宽度和高度(默认是白色的,大小默认300*150)

    ③通过JavaScript来绘制(在什么地方画)

    ④准备绘制工具(获取上下文,指一种环境getContext('2d')

    ⑤利用工具绘图:移动画笔(moveTo),规定轨迹(lineTo),描边(stroke)或者填充(fill)....

    三、体验

    ①画一条直线

    • 关于画布大小的书写位置:设置画布大小在canvas的行内设置,不建议内嵌式或者外链式
    • 关于轨迹的理解:轨迹是看不见的,只有通过描边或者填充才能看见形态
    • 关于2d的说明:目前只有2d,未来可能出现3d,目前的网页的3d效果通常是使用Web GL制作的
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            ctx.moveTo(100,100);
            ctx.lineTo(200,100);
            ctx.stroke();
        </script>
    </body>
    </html>

    ②画两条平行线

    • 线条的默认大小和颜色:默认宽度是1px,默认颜色是黑色
    • 线条模糊的原因:线条的大小是1像素,是画在画布像素刻度中间的位置,所以会出现不饱和的情况,颜色偏灰,并且因为屏幕的最小单位是1px,所以画布显示的大小会略大

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            ctx.moveTo(100,100-0.5);
            ctx.lineTo(300,100-0.5);
    
            ctx.moveTo(100,200);
            ctx.lineTo(300,200);
    
            ctx.stroke();
        </script>
    </body>
    </html>

    ③画三条不同颜色和宽度的平行线

    • 颜色:strokeStyle=‘ 颜色’ 
    • 宽度:lineWidth=‘ num ’ (没有单位)
    • 解决样式覆盖问题:开启新的路径 beginPath()
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            // 红色 10px
            ctx.beginPath();
            ctx.moveTo(100,100);
            ctx.lineTo(300,100);
            ctx.strokeStyle='red';
            ctx.lineWidth='10';
            ctx.stroke();
            // 蓝色 20px
            ctx.beginPath();
            ctx.moveTo(100,200);
            ctx.lineTo(300,200);
            ctx.strokeStyle='blue';
            ctx.lineWidth='20';
            ctx.stroke();
            // 黄色 30px
            ctx.beginPath();
            ctx.moveTo(100,300);
            ctx.lineTo(300,300);
            ctx.strokeStyle='yellow';
            ctx.lineWidth='30';
            ctx.stroke();
        </script>
    </body>
    </html>

    ④绘制一个填充颜色的三角形

    • 填充 :fill( )
    • 填充颜色: fillStyle=‘颜色’
    • 描边情况下起始点和lineto的结束点无法完全闭合(缺角)的解决办法:closePath( ) 自动闭合
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            ctx.moveTo(100,100);
            ctx.lineTo(200,100);
            ctx.lineTo(200,200);
            //ctx.lineTo(100,100);无法完全闭合
            ctx.closePath();
            //ctx.strokeStyle='red';
            ctx.fillStyle='red';
            //ctx.lineWidth='10';
            //ctx.stroke();
            ctx.fill();
        </script>
    </body>
    </html>

    ⑤绘制一个镂空的正方形

    • 画法:大正方形顺时针,小正方形逆时针
    • 原理:非零环绕填充规则

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            // 大正方形(顺时针)
            ctx.moveTo(100,100);
            ctx.lineTo(300,100);
            ctx.lineTo(300,300);
            ctx.lineTo(100,300);
            ctx.closePath();
            // 小正方形(逆时针)
            ctx.moveTo(150,150);
            ctx.lineTo(150,250);
            ctx.lineTo(250,250);
            ctx.lineTo(250,150);
            ctx.closePath();
            // 填充
            ctx.fillStyle='red';
            ctx.fill();
        </script>
    </body>
    </html>

    ⑥两端样式和拐点样式

    • 两端样式:lineCap=“ ”  可以填butt(默认) 、square(方)、round(圆)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            // 两端默认 30px
            ctx.beginPath();
            ctx.moveTo(100,100);
            ctx.lineTo(300,100);
            ctx.lineWidth='30';
            ctx.lineCap='butt';
            ctx.stroke();
            // 两端方形 30px
            ctx.beginPath();
            ctx.moveTo(100,200);
            ctx.lineTo(300,200);
            ctx.lineWidth='30';
            ctx.lineCap='square'
            ctx.stroke();
            // 两端圆形 30px
            ctx.beginPath();
            ctx.moveTo(100,300);
            ctx.lineTo(300,300);
            ctx.lineWidth='30';
            ctx.lineCap='round';
            ctx.stroke();
        </script>
    </body>
    </html>

    • 拐点样式:lineJoin=‘  ’ 可以填miter(默认)、bevel(方)、round(圆)
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            // 拐点默认 30px
            ctx.beginPath();
            ctx.moveTo(100,100);
            ctx.lineTo(200,150);
            ctx.lineTo(300,100);
            ctx.lineWidth='30';
            ctx.lineJoin='miter';
            ctx.stroke();
            // 拐点方形 30px
            ctx.beginPath();
            ctx.moveTo(100,200);
            ctx.lineTo(200,250);
            ctx.lineTo(300,200);
            ctx.lineWidth='30';
            ctx.lineJoin='bevel'
            ctx.stroke();
            // 拐点圆形 30px
            ctx.beginPath();
            ctx.moveTo(100,300);
            ctx.lineTo(200,350);
            ctx.lineTo(300,300);
            ctx.lineWidth='30';
            ctx.lineJoin='round';
            ctx.stroke();
        </script>
    </body>
    </html>

    ⑦绘制虚线

    • 设置虚线的排列方式:setlineDash([  ])数组用来描述排列方式的
    • 获取虚线的排列方式:getlineDash()获取的是不重复的那一段排列方式
    • 虚线偏移量:lineDashoffset=' num '  如果是正的,往后偏移;如果是负的往前偏移
    <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            ctx.moveTo(100,100.5);
            ctx.lineTo(300,100.5);
            //虚线是由一段虚线加一段实线组成的,数组描述的就是虚线和实线的大小
            ctx.setLineDash([5,10,30,20]);
            console.log(ctx.getLineDash());//(4) [5, 10, 30, 20]
            ctx.lineDashOffset=-20;
            ctx.lineWidth=10;
            ctx.stroke();
        </script>
    </body>
    </html>

    ⑧绘制一个颜色渐变的矩形

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            ctx.lineWidth=100;
            for(var i=0;i<255;i++){
                ctx.beginPath();
                ctx.moveTo(100+i-1,100);
                ctx.lineTo(100+i,100);
                ctx.strokeStyle='rgba('+i+',0,0)';
                ctx.stroke();
            }
        </script>
    </body>
    </html>

    ⑨绘制折线图(面向对象)

    • 绘制网格
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            //网格的大小,画布的宽度和高度
            var gridSize=10;
            var canvasHeight=ctx.canvas.height;
            var canvasWidth=ctx.canvas.width;
            //x轴方向的线
            var xLineTotal=Math.floor(canvasHeight/gridSize);
            for(var i=0;i<xLineTotal;i++){
                ctx.beginPath();
                ctx.moveTo(0,i*gridSize-0.5);
                ctx.lineTo(canvasWidth,i*gridSize-0.5);
                ctx.strokeStyle='#eee';
                ctx.stroke();
            }
            //y轴方向的线
            var yLineTotal=Math.floor(canvasWidth/gridSize);
            for(var i=0;i<yLineTotal;i++){
                ctx.beginPath();
                ctx.moveTo(i*gridSize-0.5,0);
                ctx.lineTo(i*gridSize-0.5,canvasHeight);
                ctx.strokeStyle='#eee';
                ctx.stroke();
            }
        </script>
    </body>
    </html>

    • 绘制坐标系
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            // 确定原点的坐标(x0,y0)
            var space=20;
            var canvasWidth=ctx.canvas.width;
            var canvasHeight=ctx.canvas.height;
            var x0=space;
            var y0=canvasHeight-space;
            // 绘制x轴
            ctx.beginPath();
            ctx.moveTo(x0,y0);
            ctx.lineTo(canvasWidth-space,y0);
            // 绘制x轴的箭头
            var arrowSize=10;
            ctx.lineTo(canvasWidth-space-arrowSize,y0+arrowSize/2);
            ctx.lineTo(canvasWidth-space-arrowSize,y0-arrowSize/2);
            ctx.lineTo(canvasWidth-space,y0);
            ctx.fill();
            ctx.stroke();
            // 绘制y轴
            ctx.beginPath();
            ctx.moveTo(x0,y0);
            ctx.lineTo(space,space);
            // 绘制y轴的箭头
            ctx.lineTo(space+arrowSize/2,space+arrowSize);
            ctx.lineTo(space-arrowSize/2,space+arrowSize);
            ctx.lineTo(space,space);
            ctx.fill();
            ctx.stroke();
        </script>
    </body>
    </html

    • 绘制点
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            // 点坐标
            var coordinate={
                x:100,
                y:100
            }
            // 点的尺寸大小
            var dottedSize=10;
            // 在画布上绘制点
            ctx.moveTo(coordinate.x-dottedSize/2,coordinate.y-dottedSize/2);
            ctx.lineTo(coordinate.x+dottedSize/2,coordinate.y-dottedSize/2);
            ctx.lineTo(coordinate.x+dottedSize/2,coordinate.y+dottedSize/2);
            ctx.lineTo(coordinate.x-dottedSize/2,coordinate.y+dottedSize/2);
            ctx.closePath();
            ctx.fill();
        </script>
    </body>
    </html>

    • 面向对象的方式绘制折线图
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas的基本使用</title>
        <style>
            canvas{
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
        <canvas width="600" height="400"></canvas>
        <script>
            var myCanvas=document.querySelector("canvas");
            var ctx=myCanvas.getContext('2d');
            /*  1.构造折线图的函数 */
            var LineChart=function(ctx){
                // 获取绘图工具
                this.ctx=ctx||document.querySelector('canvas').getContext('2d');
                // 获取画布的大小
                this.canvasWidth=this.ctx.canvas.width;
                this.canvasHeight=this.ctx.canvas.height;
                // 网格的大小
                this.gridSize=10;
                // 坐标系的间距
                this.space=20;
                // 坐标原点
                this.x0=this.space;
                this.y0=this.canvasHeight-this.space;
                // 箭头的大小
                this.arrowSize=10;
                // 绘制点的大小
                this.dottedSize=6;
            }
            /*  2.添加原型方法 */
            // 初始化
            LineChart.prototype.init=function(data){
                this.drawGrid();
                this.drawAxis();
                this.drawDotted(data);
            };
            // 绘制网格
            LineChart.prototype.drawGrid=function(){
                // x轴方向的线
                var xLineTotal=Math.floor(this.canvasHeight/this.gridSize);
                this.ctx.strokeStyle='#eee';
                for(var i=0;i<xLineTotal;i++){
                    this.ctx.beginPath();
                    this.ctx.moveTo(0,i*this.gridSize-0.5);
                    this.ctx.lineTo(this.canvasWidth,i*this.gridSize-0.5);
                    this.ctx.stroke();
                }
                // y轴方向的线
                var yLineTotal=Math.floor(this.canvasWidth/this.gridSize);
                for(var i=0;i<yLineTotal;i++){
                    this.ctx.beginPath();
                    this.ctx.moveTo(i*this.gridSize-0.5,0);
                    this.ctx.lineTo(i*this.gridSize-0.5,this.canvasHeight);
                    this.ctx.stroke();
                }
            };
            //绘制坐标系
            LineChart.prototype.drawAxis=function(){
                // x轴和x轴的箭头
                this.ctx.beginPath();
                this.ctx.strokeStyle='#000';
                this.ctx.moveTo(this.x0,this.y0);
                this.ctx.lineTo(this.canvasWidth-this.space,this.y0);
                this.ctx.lineTo(this.canvasWidth-this.space-this.arrowSize,this.y0+this.arrowSize/2);
                this.ctx.lineTo(this.canvasWidth-this.space-this.arrowSize,this.y0-this.arrowSize/2);
                this.ctx.lineTo(this.canvasWidth-this.space,this.y0);
                this.ctx.stroke();
                this.ctx.fill();
                // y轴和y轴的箭头
                this.ctx.beginPath();
                this.ctx.strokeStyle='#000';
                this.ctx.moveTo(this.x0,this.y0);
                this.ctx.lineTo(this.space,this.space);
                this.ctx.lineTo(this.space+this.arrowSize/2,this.space+this.arrowSize);
                this.ctx.lineTo(this.space-this.arrowSize/2,this.space+this.arrowSize);
                this.ctx.lineTo(this.space,this.space);
                this.ctx.stroke();
                this.ctx.fill();
            };
            //绘制所有点
            LineChart.prototype.drawDotted=function(data){
                //转化当前对象为that,因为后面循环内的this已经不是当前对象
                var that=this;
                data.forEach(function(item,i){
                    // 数据的坐标需要转换为canvas坐标
                    var canvasX=that.x0+item.x;//x=原点的x坐标+数据的x坐标
                    var canvasY=that.y0-item.y;//y=原点的y坐标+数据的y坐标
                    // 进行点的绘制
                    that.ctx.beginPath();
                    that.ctx.moveTo(canvasX-that.dottedSize/2,canvasY-that.dottedSize/2);
                    that.ctx.moveTo(canvasX+that.dottedSize/2,canvasY-that.dottedSize/2);
                    that.ctx.moveTo(canvasX+that.dottedSize/2,canvasY+that.dottedSize/2);
                    that.ctx.moveTo(canvasX-that.dottedSize/2,canvasY+that.dottedSize/2);
                    that.ctx.closePath();
                    that.ctx.fill();
                    // 连线
                    if(i==0){//第一个点,起点是x0,y0
                        that.ctx.beginPath();
                        that.ctx.moveTo(that.x0,that.y0);
                        that.ctx.lineTo(canvasX,canvasY);
                        that.ctx.stroke();
                    }else{//后面的点,起点是上一个点
                        that.ctx.beginPath();
                        that.ctx.moveTo(prevCanvasX,prevCanvasY);
                        that.ctx.lineTo(canvasX,canvasY);
                        that.ctx.stroke();
                    }
                    // 记录当前的坐标,下一次要用
                    prevCanvasX=canvasX;
                    prevCanvasY=canvasY;
                });
            };
           /* 3.数据和实例化对象 */
           var data=[
               {x:100,y:120},
               {x:200,y:160},
               {x:300,y:240},
               {x:400,y:320},
               {x:500,y:80}
           ]
           var lineChart=new LineChart();
           lineChart.init(data);
        </script>
    </body>
    </html>

  • 相关阅读:
    【转载】SAP_ECC6.0_EHP4或SAP_ECC6.0_EHP5_基于Windows_Server_2008R2_和SQL_server_2008下的安装
    使用delphi 开发多层应用(二十四)KbmMW 的消息方式和创建WIB节点
    使用delphi 开发多层应用(二十三)KbmMW 的WIB
    实现KbmMw web server 支持https
    KbmMW 服务器架构简介
    Devexpress VCL Build v2014 vol 14.1.1 beta发布
    使用delphi 开发多层应用(二十二)使用kbmMW 的认证管理器
    KbmMW 4.50.00 测试版发布
    Basic4android v3.80 beta 发布
    KbmMW 认证管理器说明(转载)
  • 原文地址:https://www.cnblogs.com/EricZLin/p/9269404.html
Copyright © 2011-2022 走看看