Canvas绘制曲线&圆弧&扇形&饼状图&绘制图片&帧动画&canvas的转换

绘制曲线

    /*
    * 1、体验曲线的绘制
    * 2、线是由点构成的
    * 3、曲线可以由数学公式得来
    *
    * 公式:y=x/2
    * 公式:y=(x+2)^2
    * 公式:y=sin(x)
    * */

    for(var i=0;i<600;i++){
    
    
        var x=i;
        // var y=x/2;
        // var y=Math.pow(x-100+2,2)/20;
        var y=50*Math.sin(x/10)+150;
        ctx.lineTo(x,y);
    }
    ctx.strokeStyle="blueviolet";
    ctx.stroke();

在这里插入图片描述

绘制四分之一的圆弧

    /*
    * 绘制圆弧
    * 确定圆心 坐标 x y
    * 确定圆半径 r
    * 确定起始绘制的位置和结束绘制的位置 确定弧的长度和位置 startAngle endAngle
    * 取得绘制的方向 direction 默认是顺时针方向-->false   逆时针--->true
    * */

    //在中心位置画一个半径150px的圆弧左下角
    var w=ctx.canvas.width;
    var h=ctx.canvas.height;
    ctx.arc(w/2,h/2,150,Math.PI/2,Math.PI,false);
    ctx.strokeStyle="blueviolet";
    ctx.stroke();

在这里插入图片描述

绘制四分之一扇形

    //在中心位置画一个半径150px的圆弧右上角 扇形 边 填充
    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,true);
    ctx.fillStyle="lightskyblue";
    ctx.fill();

在这里插入图片描述

绘制一个圆等分成num份

<script>
    var myCanvas=document.querySelector("canvas");
    var ctx=myCanvas.getContext("2d");

    var canvasWidth=ctx.canvas.width;
    var canvasHeight=ctx.canvas.height;

    //分成多少等份
    var num=360;

    //半径
    var radius=150;

    //一份多少弧度
    var angle=Math.PI*2/num;

    //坐标原点
    var x0=canvasWidth/2;
    var y0=canvasHeight/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,radius,startAngle,endAngle);
        //随机颜色
        ctx.fillStyle=getRandomColor();
        ctx.fill();
    }
</script>

在这里插入图片描述

根据数据的饼图

根据占比设置每个扇形起止angle

    //转换弧度+绘制图形
    var startAngle=0;
    var endAngle=0;
    data.forEach(function (item,i) {
    
    
        endAngle=startAngle+Math.PI*2*(item/total);
        ctx.beginPath();
        ctx.moveTo(x0,y0);
        ctx.arc(x0,y0,radius,startAngle,endAngle);
        ctx.fillStyle=getRandomColor();
        ctx.fill();
        startAngle=endAngle;
    });

绘制在画布中心的一段文字(下划线)

    var str="乐程_NB";
    ctx.beginPath();
    ctx.font="40px 华文行楷";
    ctx.textAlign="center";//水平-->center left right start end
    ctx.textBaseline="middle";//垂直-->top bottom middle
    ctx.strokeText(str,x0,y0);
    var width=ctx.measureText(str).width;//文本宽度
    ctx.moveTo(x0-width/2,y0+20);
    ctx.lineTo(x0+width/2,y0+20);
    ctx.stroke();

在这里插入图片描述

绘制饼状图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas{
    
    
            border:1px solid lightskyblue;
        }
    </style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
    /*
    * 绘制饼状图
    * 根据数据绘制一个饼状图
    * 绘制标题 从扇形的弧中心伸出一条横线 在横线的上面写上标题
    * 在画布的左上角 绘制说明 一个扇形一样的颜色的矩形 旁边是文字说明
    * */

    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;
        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 (data) {
    
    
        var that=this;
        //转化弧度
        var angleList=this.transformAngle(data);

        //绘制饼图
        var startAngle=0;
        angleList.forEach(function (item,i) {
    
    
            //当前弧度结束要等于下一次的起始弧度
            var endAngle=startAngle+item.angle;

            that.ctx.beginPath();
            that.ctx.moveTo(that.x0,that.y0);
            that.ctx.arc(that.x0,that.y0,that.radius,startAngle,endAngle);
            var color=that.ctx.fillStyle=that.getRandomColor();
            that.ctx.fill();
            that.drawTitle(startAngle,item.angle,color,item.title)
            startAngle=endAngle;

            that.drawDesc(i,item.title);
        });
    };

    //转换弧度
    PieChart.prototype.transformAngle=function (data) {
    
    
        //返回的数据内容包含弧度的
        var total=0;
        data.forEach(function (item,i) {
    
    
            total+=item.num;
        });

        //计算弧度,并且追加到当前的对象内容
        data.forEach(function (item,i) {
    
    
            var angle=Math.PI*2*(item.num/total);
            item.angle=angle;
        });
        return data;
    };

    //绘制标题
    PieChart.prototype.drawTitle=function(startAngle,angle,color,title){
    
    
        /*
        * 确定伸出去的线,通过圆心点,通过伸出去的点 确定这条线
        * 确定伸出去的点,需要确定伸出去的线的长度
        * 固定伸出去的线的长度
        * 计算这个点的坐标
        * 根据角度和斜边的长度
        * 使用弧度,当前扇形的起始弧度+对应的弧度的一半
        * 半径+伸出去的长度
        *
        * outX=this.x0+edge*cos(startAngle+angle/2);
        * outY=this.y0+edge*sin(startAngle+angle/2);
        * */

        //斜边
        var edge=this.radius+this.outLine;
        //出去点的x坐标
        var outX=this.x0+edge*Math.cos(startAngle+angle/2);
        //出去点的y坐标
        var outY=this.y0+edge*Math.sin(startAngle+angle/2);

        this.ctx.beginPath();
        this.ctx.moveTo(this.x0,this.y0);
        this.ctx.lineTo(outX,outY);
        this.ctx.strokeStyle=color;
        this.ctx.stroke();

        //绘制文字和下划线
        //线的方向怎么判断-->伸出去的点在x0的哪边,线的方向就是哪边
        //结束的点坐标和文字大小
        this.ctx.font="14px Microsoft YaHei";
        var textWidth=this.ctx.measureText(title).width;
        if(outX>=this.x0){
    
    
            //右
            this.ctx.moveTo(outX,outY);
            this.ctx.lineTo(outX+textWidth,outY);
            this.ctx.textAlign="left";
        }
        else{
    
    
            //左
            this.ctx.moveTo(outX,outY);
            this.ctx.lineTo(outX-textWidth,outY);
            this.ctx.textAlign="right";
        }
        this.ctx.strokeStyle=color;
        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.fill();

        //绘制文字
        this.ctx.font="12px Microsoft YaHei";
        this.ctx.beginPath();//重新开一条路径
        this.ctx.textAlign="left";
        this.ctx.textBaseline="top";
        this.ctx.fillText(title,this.space+this.rectW+10,this.space+index*(this.rectH+10));
    }

    //产生随机颜色
    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: '15-20岁',
            num: 6
        },
        {
    
    
            title: '20-25岁',
            num: 30
        },
        {
    
    
            title: '25-30岁',
            num: 10
        },
        {
    
    
            title: '30以上',
            num: 8
        }
    ];

    var pieChart=new PieChart();
    pieChart.init(data);

</script>
</body>
</html>

在这里插入图片描述

绘制图片

    //创建对象
    var img=new Image();

    //绑定加载完成事件
    img.onload=function () {
    
    
        //实现图片绘制
        console.log(img);

        //绘制图片的三种方式

        //三个参数
        //图片对象
        //绘制在画布上的坐标x y
        // ctx.drawImage(img,100,100);

        //五个参数
        //图片对象
        //绘制在画布上的坐标x y
        //图片的大小 不是裁剪 是缩放
        // ctx.drawImage(img,100,100,200,200);

        /*
        * 九个参数
        * 图片对象
        * 图片上定位的坐标 x y
        * 在图片上截取多大的区域 w h
        * 绘制在画布上的坐标 x y
        * 图片的大小 不是裁剪 是缩放
        * */
        ctx.drawImage(img,20,20,50,50,100,100,400,400);
    };

    //设置图片路径
    img.src="01.jpg";

帧动画

    var img=new Image();
    img.onload=function () {
    
    
        //图片加载完成
        //动态地去获取当前图片的尺寸
        var imgWidth=img.width;
        var imgHeight=img.height;

        //计算出每一个小人的尺寸
        var personWidth=imgWidth/4;
        var personHeight=imgHeight/4;

        //位截取图片
        //帧动画,在规定的时间间隔更换显示的图片 根据图片的索引
        var index=0;

        //绘制在画布的中心
        //图片绘制的起始点
        var x0=canvasWidth/2-personWidth/2;
        var y0=canvasHeight/2-personHeight/2;

        ctx.drawImage(img,0,0,personWidth,personHeight,x0,y0,personWidth,personHeight);
        setInterval(function () {
    
    
            index++;
            ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
            ctx.drawImage(img,index*personWidth,0,personWidth,personHeight,x0,y0,personWidth,personHeight);
            if(index>=3){
    
    
                index=0;
            }
        },100);

    };

    //图片路径
    img.src="04.png";

在这里插入图片描述


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas {
    
    
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
    var Person=function (ctx) {
    
    
        //绘制工具
        this.ctx=ctx||document.querySelector("canvas").getContext("2d");

        //图片路径
        this.src="04.png";

        //行走相关参数
        this.stepSize=10;

        //0-前  1-左 2-右 3-后 和图片的行数包含的图片对应上
        this.direction=0;

        //x轴方向偏移步数
        this.stepX=0;

        //y轴方向偏移步数
        this.stepY=0;

        //初始化方法
        this.init();
    }

    Person.prototype.init=function () {
    
    
        var that=this;

        //加载图片
        this.loadImage(function (image) {
    
    
            //图片的大小
            that.imageWidth=image.width;
            that.imageHeight=image.height;

            //人物的大小
            that.personWidth=that.imageWidth/4;
            that.personHeight=that.imageHeight/4;

            //绘制图片的起点
            that.x0=that.imageWidth/2-that.personWidth/2;
            that.y0=that.imageHeight/2-that.personHeight/2;

            //默认绘制在中心位置正面朝外
            that.ctx.drawImage(image,0,0,that.personWidth,that.personHeight,that.x0,that.y0,that.personWidth,that.personHeight);

            //3、能通过方向键去控制人物行走----document.onkeyDown--->keyCode
            that.index=0;
            var add=3;
            setInterval(function () {
    
    
                var code=parseInt(Math.random()*4+37);
                if(code==40){
    
    
                    //前
                    that.direction=0;
                    that.stepY+=add;
                    that.drawImage(image);
                }else if(code==37){
    
    
                    //左
                    that.direction=1;
                    that.stepX-=add;
                    that.drawImage(image);
                }else if(code==39){
    
    
                    //右
                    that.direction=2;
                    that.stepX+=add;
                    that.drawImage(image);
                }else if(code==38){
    
    
                    //后
                    that.direction=3;
                    that.stepY-=add;
                    that.drawImage(image);
                }
            },200);
        });
    };

    //加载图片
    Person.prototype.loadImage=function (callback) {
    
    
        var image=new Image();
        image.onload=function () {
    
    
            callback&&callback(image);
        };
        image.src=this.src;
    };

    //绘制图片
    Person.prototype.drawImage=function (image) {
    
    
        this.index++;
        this.ctx.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);

        //绘图
        //在精灵图上的定位x  索引
        //在精灵图上的定位y  方向
        this.ctx.drawImage(image,this.index*this.personWidth,
                            this.direction*this.personHeight,
                            this.personWidth,this.personHeight,
                            this.x0+this.stepX*this.stepSize,
                            this.y0+this.stepY*this.stepSize,
                            this.personWidth,this.personHeight);

        //超出索引
        if(this.index>=3){
    
    
            this.index=0;
        }
    };

    new Person();
</script>
</body>
</html>

canvas的转换

    var startAngle=0;
    ctx.translate(200,200);
    setInterval(function () {
    
    
        startAngle+=Math.PI/180;
        ctx.rotate(startAngle);
        ctx.strokeStyle=getRandomColor();
        ctx.strokeRect(-50,-50,150,150);
    },500);

    function getRandomColor() {
    
    
        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+")";
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Amethystlry/article/details/109755182