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>

  • 相关阅读:
    复杂系统架构设计<1>
    DevExpress Applications<3>
    DevExpress Skins<2>
    DevExpress MVVM<1>
    Unity容器<1>
    spring cloud微服务快速教程之(九) Spring Cloud Alibaba--sentinel-限流、熔断降级
    spring cloud微服务快速教程之(八) Spring Cloud Alibaba--nacos(二)、配置中心
    spring cloud微服务快速教程之(七) Spring Cloud Alibaba--nacos(一)、服务注册发现
    小白的springboot之路(十五)、mybatis的PageHelper分页插件使用
    spring cloud微服务快速教程之(六) 应用监控 spring boot admin
  • 原文地址:https://www.cnblogs.com/EricZLin/p/9269404.html
Copyright © 2011-2022 走看看