深入学习JavaScript中的canvas绘图(下)!!!

34 篇文章 0 订阅
2 篇文章 0 订阅

圆弧绘制

  • 弧度概念

1.什么是弧度 是一种长度的描述单位
2.一个弧度怎么去描述 一个圆有多少个弧度 2 * π
3.一弧度有多长 一个弧度一个半径的长度

角度:一个圆是360度
半径:已一个点为中心多长为放射半径
周长:2 * π * r
最终的结论:一个角度等于多少弧度  π/180
- arc()
    + x 圆心横坐标
    + y 圆心纵坐标
    + r 半径
    + startAngle 开始角度
    + endAngle 结束角度
    + anticlockwise 是否逆时针方向绘制(默认false表示顺时针;true表示逆时针)

绘制文本

- ctx.font = '微软雅黑'  设置字体
- strokeText()
- fillText(text,x,y,maxWidth)
    + text 要绘制的文本
    + x,y 文本绘制的坐标(文本左下角)
    + maxWidth 设置文本最大宽度,可选参数
- ctx.textAlign文本水平对齐方式,相对绘制坐标来说的
    + left
    + center
    + right
    + start 默认
    + end
- ctx.direction属性css(rtl ltr) start和end于此相关
    + 如果是ltr,start和left表现一致
    + 如果是rtl,start和right表现一致
- ctx.textBaseline 设置基线(垂直对齐方式  )
    + top 文本的基线处于文本的正上方,并且有一段距离
    + middle 文本的基线处于文本的正中间
    + bottom 文本的基线处于文本的证下方,并且有一段距离
    + hanging 文本的基线处于文本的正上方,并且和文本粘合
    + alphabetic 默认值,基线处于文本的下方,并且穿过文字
    + ideographic 和bottom相似,但是不一样
- measureText() 	获取文本宽度obj.width

实例练习

  • 绘制四分之一圆弧
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');

    /*绘制圆弧*/
    /*确定圆心  坐标 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,true);
    ctx.stroke();
</script>
  • 绘制一个右上角的四分之一的扇形
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');

    /*在中心位置画一个半径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.closePath();

    ctx.fill();
</script>
  • 绘制圆
<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 = 360;
    /*一份多少弧度*/
    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 + ')';
    }

    /*上一次绘制的结束弧度等于当前次的起始弧度*/
    //var startAngle = 0;
    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>
  • 绘制饼图
<canvas width="600" height="400"></canvas>
<script>
    /*var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');*/

    /*1.绘制饼状态图*/
    /*1.1 根据数据绘制一个饼图*/
    /*1.2 绘制标题 从扇形的弧中心伸出一条线在画一条横线在横线的上面写上文字标题*/
    /*1.3 在画布的左上角 绘制说明 一个和扇形一样颜色的矩形 旁边就是文字说明*/

    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) {
        /*1.准备数据*/
        this.drawPie(data);
    };
    PieChart.prototype.drawPie = function (data) {
        var that = this;
        /*1.转化弧度*/
        var angleList = this.transformAngle(data);
        /*2.绘制饼图*/
        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);
            /*绘制说明*/
            that.drawDesc(i,item.title);
            startAngle = endAngle;
        });
    };
    PieChart.prototype.drawTitle = function (startAngle, angle ,color , title) {
        /*1.确定伸出去的线 通过圆心点 通过伸出去的点  确定这个线*/
        /*2.确定伸出去的点 需要确定伸出去的线的长度*/
        /*3.固定伸出去的线的长度*/
        /*4.计算这个点的坐标*/
        /*5.需要根据角度和斜边的长度*/
        /*5.1 使用弧度  当前扇形的起始弧度 + 对应的弧度的一半 */
        /*5.2 半径+伸出去的长度 */
        /*5.3 outX = x0 + cos(angle) * ( r + outLine)*/
        /*5.3 outY = y0 + sin(angle) * ( r + outLine)*/
        /*斜边*/
        var edge = this.radius + this.outLine;
        /*x轴方向的直角边*/
        var edgeX = Math.cos(startAngle + angle / 2) * edge;
        /*y轴方向的直角边*/
        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;
        /*画文字和下划线*/
        /*线的方向怎么判断 伸出去的点在X0的左边 线的方向就是左边*/
        /*线的方向怎么判断 伸出去的点在X0的右边 线的方向就是右边*/
        /*结束的点坐标  和文字大小*/
        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.ctx.textBaseline = 'top';
        this.ctx.font = '12px Microsoft YaHei';
        this.ctx.fillText(title,this.space + this.rectW + 10 , this.space + index * (this.rectH + 10));
    };
    PieChart.prototype.transformAngle = function (data) {
        /*返回的数据内容包含弧度的*/
        var total = 0;
        data.forEach(function (item, i) {
            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: '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>

做动画啦!!!

绘制图片

- drawImage()
    + 三个参数drawImage(img,x,y)
        - img 图片对象、canvas对象、video对象
        - x,y 图片绘制的左上角
    + 五个参数drawImage(img,x,y,w,h)
        - img 图片对象、canvas对象、video对象
        - x,y 图片绘制的左上角
        - w,h 图片绘制尺寸设置(图片缩放,不是截取)
    + 九个参数drawImage(img,x,y,w,h,x1,y1,w1,h1)
        - img 图片对象、canvas对象、video对象
        - x,y,w,h 图片中的一个矩形区域
        - x1,y1,w1,h1 画布中的一个矩形区域

序列帧动画

  • 绘制精灵图
  • 动起来
  • 控制边界
  • 键盘控制

坐标变换

  • 平移 移动画布的原点
    • translate(x,y) 参数表示移动目标点的坐标
  • 缩放
    • scale(x,y) 参数表示宽高的缩放比例
  • 旋转
    • rotate(angle) 参数表示旋转角度

Demo

  • 绘制图片
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');

    /*1.加载图片到内存即可*/
    /*var img = document.createElement('img');
    img.src = 'image/01.jpg';*/
    /*创建对象*/
    var image = new Image();
    /*绑定加载完成事件*/
    image.onload = function () {
        /*实现图片绘制*/
        console.log(image);
        /*绘制图片的三种方式*/

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


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


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

    };
    /*设置图片路径*/
    image.src = 'image/02.jpg';    
</script>
  • 帧动画
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');

    var image = new Image();
    image.onload = function () {
        /*图片加载完成*/
        /*动态的去获取当前图片的尺寸*/
        var imageWidth = image.width;
        var imageHeight = image.height;
        /*计算出每一个小人物的尺寸*/
        var personWidth = imageWidth/4;
        var personHeight = imageHeight/4;
        /*位截取图片*/
        /*帧动画  在固定的时间间隔更换显示的图片  根据图片的索引*/
        var index = 0;

        /*绘制在画布的中心*/
        /*图片绘制的起始点*/
        var x0 = ctx.canvas.width /2 - personWidth / 2;
        var y0 = ctx.canvas.height /2 - personHeight / 2;

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

    };
    image.src = 'image/04.png';
</script>
  • 方向键控制的行走的小人
var Person = function (ctx) {
     /*绘制工具*/
     this.ctx = ctx || document.querySelector('canvas').getContext('2d');
     /*图片路径*/
     this.src = 'image/04.png';
     /*画布的大小*/
     this.canvasWidth = this.ctx.canvas.width;
     this.canvasHeight = this.ctx.canvas.height;

     /*行走相关参数*/
     this.stepSzie = 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;
        /*1.加载图片*/
        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.canvasWidth / 2 - that.personWidth / 2;
            that.y0 = that.canvasHeight / 2 - that.personHeight / 2;
            /*2.默认绘制在中心位置正面朝外*/
            that.ctx.drawImage(image,
                0,0,
                that.personWidth,that.personHeight,
                that.x0,that.y0,
                that.personWidth,that.personHeight);

            /*3.能通过方向键去控制人物行走*/
            that.index = 0;
            document.onkeydown = function (e) {
                if(e.keyCode == 40){
                    that.direction = 0;
                    that.stepY ++;
                    that.drawImage(image);
                    /*前*/
                }else if(e.keyCode == 37){
                    that.direction = 1;
                    that.stepX --;
                    that.drawImage(image);
                    /*左*/
                }else if(e.keyCode == 39){
                    that.direction = 2;
                    that.stepX ++;
                    that.drawImage(image);
                    /*右*/
                }else if(e.keyCode == 38){
                    that.direction = 3;
                    that.stepY --;
                    that.drawImage(image);
                    /*后*/
                }
            }
        });
    }
    /*加载图片*/
    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.canvasWidth,this.canvasHeight);
        /*绘图*/
        /*在精灵图上的定位 x  索引*/
        /*在精灵图上的定位 y  方向*/
        this.ctx.drawImage(image,
            this.index * this.personWidth,this.direction * this.personHeight,
            this.personWidth,this.personHeight,
            this.x0 + this.stepX * this.stepSzie ,this.y0 + this.stepY * this.stepSzie,
            this.personWidth,this.personHeight);
        /*如果索引超出了 变成0*/
        if(this.index >= 3){
            this.index = 0;
        }
    };

    new Person();
</script>
  • 认识 canvas 的转换
<canvas width="600" height="400"></canvas>
<script>
    var myCanvas = document.querySelector('canvas');
    var ctx = myCanvas.getContext('2d');
    //ctx.translate(100,100);
    //ctx.scale(0.5,1);
    //ctx.rotate(Math.PI/6);
    var startAngle = 0;
    ctx.translate(150,150);
    setInterval(function () {
        startAngle += Math.PI/180;
        ctx.rotate(startAngle);
        ctx.strokeRect(-50,-50,100,100);
    },500);
    
</script>

如有不足,欢迎大家批评指正,希望这篇文章能给大家带来帮助 !!!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值