zoukankan      html  css  js  c++  java
  • Canvas 基础二

    一、绘制矩形

      1、rect (x, y, width, height)   : 绘制矩形的路径

        ---用轨迹画的,不是独立路径( 没有beginPath() )

        ---需要stroke()描边才会显示

     

      2、strokeRect (x, y, width, height)   : 描边矩形

        ---自动描边,有独立路径

     

      3、fillRect (x, y, width, height)   : 填充矩形

        ---自动填充(默认黑色),有独立路径

      

      4、clearRect (x, y, width, height)  : 清除矩形

        ---相当于橡皮擦

        

          var myCanvas = document.querySelector("canvas");
          var ctx = myCanvas.getContext("2d");
          ctx.fillRect(100, 100, 300, 200);
          ctx.clearRect(100,100,50,50);  

    如下图:

     

      5、绘制渐变矩形

      ---与css3差不多,渐变三要素 : 方向(有起始坐标, 结束坐标)  初始颜色   结束颜色

      

          var myCanvas = document.querySelector("canvas");
          var ctx = myCanvas.getContext("2d");
          var linearGradient = ctx.createLinearGradient(100, 100, 400, 300);
          linearGradient.addColorStop(0, 'yellow');
          linearGradient.addColorStop(.5, 'pink');
          linearGradient.addColorStop(1, 'red');
          ctx.fillStyle = linearGradient;
          ctx.fillRect(100, 100, 300, 200);
    

      如下图:

      

     

    二、绘制扇形

      1、圆弧

        (1)什么是弧度???

          ---  一种长度的描述单位

          ---  一弧度的长等于圆的半径的长

          ---  一个圆有 2π个弧度

          ---  一个角度等于 π / 180 个弧度

          ---  90度等于 π / 2个弧度

       2、绘制圆弧

        (1)确定圆心(坐标)

        (2)确定半径

        (3)确定 起始绘制 和 结束绘制 的位置 ,弧的位置 --- startAngle , endAngle

        (4)确定绘制的方向,默认是顺时针(false),逆时针(true)

        (5)绘制圆弧的函数  ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)

        例:在中心位置画一个半径为150px的圆弧 ,0度到90度位置的圆弧

        var w = ctx.canvas.width;
        var h = ctx.canvas.height;
        ctx.arc(x / 2, h / 2, 150, 0 , Math.PI / 2);
        ctx.stroke();
    

      3、绘制扇形

            //第一种
            //先移动原点到中心点
            ctx.moveTo(w / 2, h / 2);
            //绘制圆弧时其实绘制了两条轨迹
            ctx.arc(w / 2, h / 2, 150, Math.PI / 2, Math.PI);
            //闭合路径
            ctx.closrPath();
            ctx.stroke();
    
    
            //第二种
            //先绘制圆弧
            ctx.arc(w / 2, h / 2, 150, Math.PI / 2, Math.PI);
            //绘制一条到中心点的轨迹
            ctx.lineTo(w / 2,  h / 2);
            //闭合路径
            ctx.closePath();
            ctx.stroke();
    

      

     三、绘制n等分的随机颜色的圆

             var myCanvas = document.querySelector("canvas");
              var ctx = myCanvas.getContext("2d");
           //确认中心点X
              var x0 = ctx.canvas.width / 2;
           //确认中心点Y
              var h0 = ctx.canvas.height / 2;
           //绘制多少个扇形
              var num = 6;
           //获取扇形的角度
              var angle = 2 * Math.PI / num;
           //随机颜色函数
              var randomColor = 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 stratAngle = i * angle;
            //获取每一次的结束位置
                var endAngle = (i + 1) * angle;
                ctx.beginPath();
                ctx.moveTo(x0, h0);
                ctx.arc(x0, h0, 150, stratAngle, endAngle);
                ctx.fillStyle = randomColor();
                ctx.fill();
              }
    

      

     四、绘制带数据的饼图

            var myCanvas = document.querySelector("canvas");
            var ctx = myCanvas.getContext("2d");
            var x0 = ctx.canvas.width / 2;
            var y0 = ctx.canvas.height / 2;
            // 自定义了四个数组
            var data = [8,30,19,12];
            var angleList = [];
            var total = 0;
            data.forEach(function(item,i){
              total += item;
              if(i == data.length -1){
                angleList.push(2 * Math.PI * (data[0] / total));
              }
            });
            // 计算4个数据分别占弧度的比例,加入angleList中
            data.forEach(function(item,i){
              if(i >= 1){
                angleList.push(2 * Math.PI * (item / total));
              }
            })
    
            var randomColor = 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;
            angleList.forEach(function(item,i){
              // 结束弧度是开始弧度加上新的弧度
              var endAngle = startAngle + item;
              ctx.beginPath();
              ctx.moveTo(x0, y0);
              ctx.arc(x0, y0, 150, startAngle, endAngle);
              ctx.fillStyle = randomColor();
              ctx.fill();
              // 开始弧度是上一次的结束弧度
              startAngle = endAngle;
            })
    

      

    五、画布中绘制文字

      1、 strokeText (str, x, y)      : 绘制描边文本

      2、fillText(str, x, y)  : 绘制填充文本  

        注:起始坐标位于左下角

      3、font = ‘ size, family‘ : 设置文本的大小和字体(第一个参数是大小,第二个参数是字体)

        例:ctx.font = ' 40px, Microsoft YaHei ' ;

      4、textAlign = left, center, right, start(默认), end  : 设置文本水平方向的对齐方式

      5、textBaseline = top , middle, bottom  : 设置文本垂直方向的对齐方式

      6、measureText(str)  :获取文本的宽度

     

    六、绘制饼图加标题和说明

      ---绘制完饼图,别人根本看不懂那一块是那一块,所以需要加上标题和说明

        ---从扇形的弧中间伸出一条线,在画一条横线,在横线上写上文字标题

        ---在画布的左上角,绘制一个和扇形一样颜色的矩形说明,旁边附上文字说明

      如:

      

      1、绘制扇形中间伸出来的线

        1.1---如何确定这条线的位置 :两点确定一条 ——  中心点和线末端的点

        1.2---如何确定末端的点 : 

        

         如上图:可以把它看成一个直角三角形,则 X1 = X0 + a ;   Y1 = Y0 + b ;

        1.3---那么又如何确定 a 和 b 的长度呢?

        这时需要用到三角函数的勾股定理,看下图:

        

           已知 c = 1, 则 a = cos ( 30° ) * c 

                 b = sin ( 30° ) * c

        1.4---现在知道了 a 和 b 怎么求了,那么弧度又如何求呢?

          由前面知道了弧度等于  比例 * 2π

          而这里的弧度等于 : 开始弧度 + 当前弧度 / 2;

                    startAnglr + angle / 2;

          所以 X1 = X0 + cos( startAngle + angle / 2 ) * radius 

             Y1 = X0 + sin(  startAngle + angle / 2 ) * radius

        1.5---代码

        

    // 创建饼图对象
            var PieChart = function(cavs){
            this.ctx = document.querySelector("canvas").getContext("2d");
            this.x0 = this.ctx.canvas.width / 2 + 60;
            this.y0 = this.ctx.canvas.height / 2;
            // 半径
            this.radius = 150;
            // 标题伸出去的线的长度
            this.outLine = 20 + this.radius;
            // 说明矩形的宽
            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;
            // 获取带有数据的数组,其中包含num,title,angle,ratio
            var angleList = this.transfromAngle(data);
            var startAngle = 0;
            angleList.forEach(function(item,i){
              // 结束弧度等于开始弧度加上当前弧度
              var endAngle = startAngle + item.angle;
              //绘制标题
              that.drawTitle(startAngle,item.angle,item.title,item.ratio);
              
              that.ctx.beginPath();
              that.ctx.moveTo(that.x0, that.y0);
              that.ctx.arc(that.x0, that.y0, that.radius, startAngle, endAngle);
              that.ctx.fillStyle = that.getRandomColor();
              that.ctx.fill();
              // 绘制说明
              that.drawDescription(i,item.title);
              // 开始弧度等于上一次的结束弧度
              startAngle = endAngle;
            })
          }
          // 绘制标题函数
          PieChart.prototype.drawTitle = function(startAngle,angle,title,ratio){
              // 获取X方向线的长度,可以理解为a的长度
              var outXLine = Math.cos(startAngle + angle / 2) * this.outLine;
              // 获取Y方向线的长度,可以理解为b的长度
              var outYLine = Math.sin(startAngle + angle / 2) * this.outLine;
              // 获取末端点X坐标
              var outX = this.x0 + outXLine;
              // 获取末端点Y坐标
              var outY = this.y0 + outYLine;
              // 设置标题为 title加上ratio
              var str = title+" : "+ratio;
              this.ctx.beginPath();
              this.ctx.moveTo(this.x0, this.y0);
              this.ctx.lineTo(outX, outY);
              // 设置标题垂直方向底线对齐
              this.ctx.textBaseline = "bottom";
              // 设置标题字体大小和字体
              this.ctx.font = "14px Microsoft YaHei";
              // 设置标题颜色
              this.ctx.fillStyle = "#000";
              // 如果末端点在中心点的右边,则横线向右,否则向左
              if(outX >= this.x0){
                this.ctx.lineTo(outX + this.ctx.measureText(str).width, outY);
                this.ctx.textAlign = 'left';
              }else{
                this.ctx.lineTo(outX - this.ctx.measureText(str).width, outY);
                // 设置文字水平对齐基于起始点的右边
                this.ctx.textAlign = 'right';
              }
              // 设置字体
              this.ctx.fillText(str, outX, outY);
              this.ctx.stroke();
          }
          PieChart.prototype.drawDescription = function(index,title){
            // 1、矩形的大小
            // 2、上边和左边的间距
            // 3、矩形之间的间距
            this.ctx.fillRect(this.space, this.space + index * (10 + this.rectH), 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 * (10 + this.rectH) + this.rectH / 4);
          }
          PieChart.prototype.transfromAngle = function(data){
              var total = 0;
              // 获取数据总数
              data.forEach(function(item,i){
                total += item.num;
              })
              data.forEach(function(item,i){
                // 获取弧度并存如data中
                item.angle = item.num / total * Math.PI * 2;
                // 获取百分比并精确到小数点后两位,存入data中
                item.ratio = Math.round(item.num / total * 10000) / 100 + "%";
              })
              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 = [
            {
              num : 8,
              title : "15-20岁"
            },
            {
              num : 30,
              title : "20-25岁"
            },
            {
              num : 12,
              title : "25-30岁"
            },
            {
              num : 16,
              title : "30-35岁"
            },
            {
              num : 5,
              title : "35-40岁"
            },
          ];
    
          var pie = new PieChart();
          pie.init(data);
    

      

        

       

  • 相关阅读:
    JSP中Session的使用
    深入了解父类引用指向子类
    Gamma校正及其OpenCV实现
    cocos2d-x3.0之请求网络(phpserver)
    Quartz使用-入门使用(java定时任务实现)
    ExtJs--15--Ext.is*各种类型推断的方法,简单看源代码就能够明确了
    小谈边界问题
    VS2010旗舰版安装图解
    LSPCI具体解释分析
    兔子--gradle安装和配置
  • 原文地址:https://www.cnblogs.com/hxblogs/p/13262153.html
Copyright © 2011-2022 走看看