canvas图形绘制

一、矩形绘制

①rect(x,y,w,h)绘制矩形路径,不是独立路径,起点是x,y,宽是w,高是h

<!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');
        // 在(100,50)处画一个宽200,高100的矩形,描边
        ctx.beginPath();
        ctx.rect(100,50,200,100);
        ctx.stroke();
        // 在(100,200)处画一个宽200,高100的矩形,填充
        ctx.beginPath();
        ctx.rect(100,200,200,100);
        ctx.fill();
    </script>
</body>
</html>

②strokeRect(x,y,w,h)绘制描边矩形,有独立路径

③fillRect(x,y,w,h)绘制填充矩形,有独立路径

<!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.strokeRect(100,100,200,100);
        // 绘制一个填充矩形
        ctx.fillRect(100,250,200,100);
    </script>
</body>
</html>

④clear(x,y,w,h)擦除矩形区域

<!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.fillRect(100,100,200,200);
        // 擦除区域
        ctx.clearRect(100,100,100,100);
    </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 linearGradient=ctx.createLinearGradient(100,50,400,100);
        linearGradient.addColorStop(0,'red');
        linearGradient.addColorStop(0.5,'green');
        linearGradient.addColorStop(1,'blue');
        ctx.beginPath();
        ctx.fillStyle=linearGradient;
        ctx.fillRect(100,50,400,100);
        // 绘制一个径向渐变的矩形
        var radialGradient=ctx.createRadialGradient(350,250,150,100,150,150);
        radialGradient.addColorStop(0,'red');
        radialGradient.addColorStop(0.5,'green');
        radialGradient.addColorStop(1,'blue');
        ctx.beginPath();
        ctx.fillStyle=radialGradient;
        ctx.fillRect(100,200,400,100);
    </script>
</body>
</html>

二、圆弧绘制

①弧度的概念:一个角度等于π/180弧度

②曲线的绘制:曲线也是由点构成的

<!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
        ctx.beginPath();
        for(var i=1;i<1000;i++){
            var x=i;
            var y=Math.pow(x-50,2);
            ctx.lineTo(x,y);
        }
        ctx.stroke();
        // 曲线2
        ctx.beginPath();
        for(var i=1;i<1000;i++){
            var x=i;
            var y=50*Math.sin(x/10)+100;
            ctx.lineTo(x,y);
        }
        ctx.stroke();
    </script>
</body>
</html>

③绘制圆弧:arc(x,y,r,startAngle,endAngle,bool

  • x表示圆心横坐标,y表示圆心纵坐标,r表示圆半径
  • startAngle表示开始的角度,endAngle表示结束的角度
  • bool 默认是false,表示顺时针,设置成true,表示逆时针
<!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 w=ctx.canvas.width;
        var h=ctx.canvas.height;
        // 四分之一圆
        ctx.beginPath();
        ctx.arc(w/4,h/4,150,Math.PI/2,Math.PI,false);
        ctx.stroke();
        // 四分之三圆
        ctx.beginPath();
        ctx.arc(w/2,h/2,150,Math.PI/2,Math.PI,true);
        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 w=ctx.canvas.width;
        var h=ctx.canvas.height;
        ctx.moveTo(w/2,h/2);
        ctx.arc(w/2,h/2,150,0,Math.PI/2);
        ctx.fill();
    </script>
</body>
</html> 

⑤绘制一个分成n等分颜色随机的圆

<!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 w=ctx.canvas.width;
        var h=ctx.canvas.height;
        // 分成几等分
        var num=10;
        // 一份多少弧度
        var angle=Math.PI*2/num;
        // 坐标原点
        var x0=w/2;
        var y0=h/2;
        // 获取随机颜色
        var getRandomColor=function(){
            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+')';
        }
        // 绘制(上一次的结束弧度等于当前的起始弧度)
        for(var i=0;i<num;i++){
            var startAngle=i*angle;
            var endAngle=(i+1)*angle;
            ctx.beginPath();
            ctx.moveTo(x0,y0);
            ctx.arc(x0,y0,150,startAngle,endAngle);
            ctx.fillStyle=getRandomColor();
            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');
        // 获取宽高
        var w=ctx.canvas.width;
        var h=ctx.canvas.height;
        // 分成几等分
        var num=10;
        // 一份多少弧度
        var angle=Math.PI*2/num;
        // 坐标原点
        var x0=w/2;
        var y0=h/2;
        // 获取随机颜色
        var getRandomColor=function(){
            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+')';
        }
        // 绘制(上一次的结束弧度等于当前的起始弧度)
        for(var i=0;i<num;i++){
            var startAngle=i*angle;
            var endAngle=(i+1)*angle;
            ctx.beginPath();
            ctx.moveTo(x0,y0);
            ctx.arc(x0,y0,150,startAngle,endAngle);
            ctx.fillStyle=getRandomColor();
            ctx.fill();
        }
    </script>
</body>
</html>

三、文本绘制

①strokeText(txt,x,y) 文本描边,txt表示文本,x和y是起始坐标(文本的左下角)

②font=‘ ’  可以设置字体样式,字体大小(没有单位)

③fillText(txt,x,y)文本填充,txt表示文本,x和y是起始坐标(文本的左下角)

④textAlign=“ ”  可以设置left,center,right,end,start等

⑤direction 属性css(rtl ltr)start和end于此相关

⑥textBaseline=“ ” 垂直对齐方式,常用的有top,bottom,middle

⑦measureText() 获取文本宽度,obj.width

<!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 str='亚历山大';
        var w=ctx.canvas.width;
        var h=ctx.canvas.height;
        ctx.beginPath();
        ctx.moveTo(0,h/2);
        ctx.lineTo(w,h/2);
        ctx.moveTo(w/2,0);
        ctx.lineTo(w/2,h);
        ctx.strokeStyle='#eee';
        ctx.stroke();
        // 绘制文本
        ctx.beginPath();
        var x0=w/2;
        var y0=h/2;
        ctx.font='40px Microsoft YaHei';
        ctx.textAlign='center';
        ctx.textBaseline='middle';
        ctx.fillStyle='red';
        ctx.fillText(str,x0,y0);
        // 绘制文本的下划线
        ctx.beginPath();
        console.log(ctx.measureText(str));//TextMetrics {width: 160}
        var width=ctx.measureText(str).width;
        ctx.moveTo(x0-width/2,y0+20);
        ctx.lineTo(x0+width/2,y0+20);
        ctx.strokeStyle='#000';
        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 PieChart=function(ctx){
            // 绘制工具
            this.ctx=ctx||document.querySelector('canvas').getContext('2d');
            // 绘制饼图的原点和半径
            this.w=this.ctx.canvas.width;
            this.h=this.ctx.canvas.height;
            this.x0=this.w/2+60;//+60为了空出左边的一些距离
            this.y0=this.h/2;
            this.radius=150;
            // 伸出去线的长度
            this.outLine=20;
            // 说明矩形的大小
            this.rectW=30;
            this.rectH=16;
            this.space=20;
        }
        /* 初始化 */
        PieChart.prototype.init=function(data){
            // 画饼图
            this.drawPie(data);
        };
        /* 根据数据绘制一个饼图 */
        PieChart.prototype.drawPie=function(){
            var that=this;
            var angleList=this.transformAngle(data);
            var startAngle=0;
            angleList.forEach(function(item,i){
                var endAngle=startAngle+item.angle;
                ctx.beginPath();
                ctx.moveTo(that.x0,that.y0);
                ctx.arc(that.x0,that.y0,that.radius,startAngle,endAngle);
                var color=ctx.fillStyle=that.getRandomColor();
                ctx.fill();

                // 标题
                that.drawTitle(startAngle,item.angle,color,item.title);
                // 说明
                that.drawDesc(i,item.title);

                startAngle=endAngle;
            });
        };
        /* 绘制标题,从扇形的弧中心伸出一条线,再画一条横线,在横线上写上文字标题 */
        PieChart.prototype.drawTitle=function(startAngle,angle,color,title){
            // 计算伸出去的点的坐标
            var edge=this.radius+this.outLine;
            var edgeX=Math.cos(startAngle+angle/2)*edge;
            var edgeY=Math.sin(startAngle+angle/2)*edge;
            var outX=this.x0+edgeX;
            var outY=this.y0+edgeY;
            // 绘制伸出去的线
            this.ctx.beginPath();
            this.ctx.moveTo(this.x0,this.y0);
            this.ctx.lineTo(outX,outY);
            this.ctx.strokeStyle=color;
            this.ctx.stroke();
            // 绘制文字和下划线
            this.ctx.font='14px Microsoft YaHei';
            var textWidth=this.ctx.measureText(title).width;
            if(outX>this.x0){
                this.ctx.lineTo(outX+textWidth,outY);
                this.ctx.textAlign='left';
            }else{
                this.ctx.lineTo(outX-textWidth,outY);
                this.ctx.textAlign='right';
            }
            this.ctx.stroke();
            this.ctx.textBaseline='bottom';
            this.ctx.fillText(title,outX,outY);
        };
        /* 在画布的左上角,绘制说明一个和扇形一样颜色的矩形,旁边是文字说明 */
        PieChart.prototype.drawDesc=function(index,title){
            this.ctx.fillRect(this.space,this.space+index*(this.rectH+10),this.rectW,this.rectH);
            this.ctx.beginPath();
            this.ctx.textAlign='left';
            this.textBaseline='top';
            this.ctx.font='12px microsoft YaHei'
            this.ctx.fillText(title,this.space+this.rectW+10,this.space+index*(this.rectH+10)+15,this.rectW,this.rectH)
        };
        /* 把数据转化弧度,并且把弧度追加到数据里 */
        PieChart.prototype.transformAngle=function(data){
            var total=0;
            data.forEach(function(item,i){
                total=total+item.num;
            });
            data.forEach(function(item,i){
                var angle=item.num/total*Math.PI*2;
                item.angle=angle;
            });
            return data;
        }
        PieChart.prototype.getRandomColor=function(){
            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+')';
        }
        /* 数据 和 实例化对象 */
        var data=[
            {title:'10-20岁',num:5},
            {title:'20-30岁',num:20},
            {title:'30-40岁',num:15},
            {title:'15-20岁',num:10}
        ]
        var pieChart=new PieChart();
        pieChart.init(data);
    </script>
</body>
</html>

猜你喜欢

转载自www.cnblogs.com/EricZLin/p/9271606.html