js怎么封装Canvas成插件

这次给大家带来js怎么封装Canvas成插件,js封装Canvas成插件的注意事项有哪些,下面就是实战案例,一起来看一下。

之前就说过,我想写一个canvas画统计图的插件,现在写好了

先说下实现的功能吧:

  1.可以通过自定义X轴坐标属性和Y轴坐标属性按比例画出统计图

  2.可以选择画折现图还是柱形统计图,或者两者都实现

  3.可以自由定义折现颜色,坐标颜色,柱形图颜色 和canvas边框颜色,当然边框你也可以选择要或者不要

  4.可以选择是否实现柱形图和折现图的动画实现

实现过程

画坐标——画箭头——做X轴和Y轴的标注——画柱形图——画折现图

话不多说,上代码

(function(window,document){ var ChartDraws = function(options){  if(!(this instanceof ChartDraws))return new ChartDraws(options);  this.options = $.extend({   //报表所需的参数   "containerId" : "",  //canvas所在容器id   "canvasWidth" : 400,   "canvasHeight" : 300,   "paddingLeft" : 20,   "paddingTop" : 20,   "columnChartData" :[], //柱形图的数量和对应得名称以及百分比   "yChartData" :[],   //y轴的数量及名称   "axisColor" : "white",  //坐标轴颜色   "columnChartColor" : "#EEE685", //柱形图颜色   "isNeedAnimation" : true, //是否需要动画   "isNeedLineChart" : true, //是否需要折线图   "isNeedColumnChart" : true, //是否需要柱形图   "lineChartColor" : "#90EE90", //折线图颜色,当isNeedLineChart=true时有效   "isNeedBorder" : false,  //canvas是否需要外边框   "borderColor" : "white"  //外边框颜色  },options);  if(this.options.canvasWidth<=500)  {   this.axisBorderWidth = 3;   this.fontSize = 8;  }  else if(this.options.canvasWidth<=800){   this.axisBorderWidth = 4;   this.fontSize = 12;  }  else{   this.axisBorderWidth = 5;   this.fontSize = 16;  }  var self = this;  _init();  function _init(){   var canvasDom = document.createElement("canvas");   canvasDom.id = self.options.containerId+"_"+"canvas";   canvasDom.width = self.options.canvasWidth;   canvasDom.height = self.options.canvasHeight;   if(self.options.isNeedBorder){    canvasDom.style.borderWidth = 1;    canvasDom.style.borderStyle = "solid";    canvasDom.style.borderColor = self.options.borderColor;   }   document.getElementById(self.options.containerId).appendChild(canvasDom);   self.context = document.getElementById(self.options.containerId+"_"+"canvas");   self.ctx = self.context.getContext("2d");   _drawAxis();  }  function _drawAxis(){   var XYData =transformAxis( [{x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},{x:self.options.paddingLeft,y:self.options.paddingTop},{x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop}]);   self.ctx.strokeStyle=self.options.axisColor;   drawLine(self.ctx,XYData,self.axisBorderWidth);   //画三角箭头   //画y轴三角箭头   drawLine(self.ctx,transformAxis([{x:self.options.paddingLeft-self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2},{x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},{x:self.options.paddingLeft+self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2}]),self.axisBorderWidth);   //画x轴三角箭头   drawLine(self.ctx,transformAxis([{x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop+self.axisBorderWidth},{x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop},{x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop-self.axisBorderWidth}]),self.axisBorderWidth);   _drawCoordinatePoints();  }  function _drawCoordinatePoints(){   self.reactAngleWidth = (1-2*0.04)*(self.options.canvasWidth-(2*self.options.paddingLeft))/(self.options.columnChartData.length*2-1);   self.lineDataList = [];   for(var i = 0;i<self.options.columnChartData.length;i++)   {    drawXText(self.ctx,2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))+self.reactAngleWidth/2,self.options.paddingTop/2,self.options.columnChartData[i].Name);    self.lineDataList.push({     x:2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))+self.reactAngleWidth/2,     y:self.options.canvasHeight-(self.options.paddingTop+(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[i].PT)    })   }   //画Y轴title 画y轴虚线   self.reactAngleHeight = (self.options.canvasHeight-2*self.options.paddingTop)/(self.options.yChartData.length+1);   for(var j = 0;j<self.options.yChartData.length;j++)   {    drawYText(self.ctx,3*self.options.paddingLeft/4,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.yChartData[j].Name);    //画虚线    drawDottedLine(self.ctx,self.options.paddingLeft,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.canvasWidth-self.options.paddingLeft,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.canvasWidth-2*self.options.paddingLeft,10,self.axisBorderWidth/2);   }   _drawColumnChart();  }  function _drawColumnChart(){   //柱形图循环   var reactAngleTimer = 1;   function loopColumnChart()   {    var columnChartLooped = window.requestAnimationFrame(loopColumnChart);    if(reactAngleTimer<=100)    {     for(var k=0;k<self.options.columnChartData.length;k++)     {      self.ctx.fillStyle =self.options.columnChartColor;      drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100+self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100);     }     reactAngleTimer++;    }    else    {     window.cancelAnimationFrame(columnChartLooped);     columnChartLooped = null;     reactAngleTimer = 1;     if(self.options.isNeedLineChart)     {      loopLineChart();     }    }   }   //折线图循环   var lineTimer = 0;   function loopLineChart()   {    var lineChartLooped = window.requestAnimationFrame(loopLineChart);    if(lineTimer<self.lineDataList.length-1)    {     self.ctx.lineWidth = 2*self.axisBorderWidth/3;     if(lineTimer == 0)     {      drawCircle(self.ctx,self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);     }     drawCircle(self.ctx,self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);     self.ctx.beginPath();     self.ctx.moveTo(self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);     self.ctx.lineTo(self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);     self.ctx.strokeStyle = self.options.lineChartColor;     self.ctx.lineWidth = 2*self.axisBorderWidth/3;     self.ctx.stroke();     lineTimer++;    }    else    {     window.cancelAnimationFrame(lineChartLooped);     lineChartLooped = null;     lineTimer = 0;    }   }   //画柱形图   function drawRectangle(context,x,y,width,height){    context.beginPath();    context.fillRect(x,y,width,height);   }   //画圆   function drawCircle(context,x,y){    context.beginPath();    context.arc(x,y,self.axisBorderWidth/2,0,2*Math.PI,true);    context.strokeStyle=self.options.lineChartColor;    context.stroke();    context.closePath();   }   if(self.options.isNeedAnimation)   {    if(self.options.isNeedColumnChart)    {     loopColumnChart();    }    else    {     if(self.options.isNeedLineChart) {      loopLineChart();     }    }   }   else   {    if(self.options.isNeedColumnChart)    {     for(var k=0;k<self.options.columnChartData.length;k++)     {      self.ctx.fillStyle =self.options.columnChartColor;      drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT+self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT);     }    }    if(self.options.isNeedLineChart) {     for (var l = 0; l < self.lineDataList.length - 1; l++) {      self.ctx.lineWidth = 4;      if (l == 0) {       drawCircle(self.ctx, self.lineDataList[l].x, self.lineDataList[l].y);      }      drawCircle(self.ctx, self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);      self.ctx.beginPath();      self.ctx.moveTo(self.lineDataList[l].x, self.lineDataList[l].y);      self.ctx.lineTo(self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);      self.ctx.strokeStyle = self.options.lineChartColor;      self.ctx.lineWidth = 2*self.axisBorderWidth/3;      self.ctx.stroke();     }    }   }  }  function transformAxis(data)  {   var newData=[];   for(var i=0;i2)   {    for(var i=1;i<point.length;i++)    {     context.lineTo(point[i].x,point[i].y);    }   }   context.lineWidth = width;   context.lineJoin='round';   context.stroke();   context.closePath();  }  //画y轴title  function drawYText(context,x,y,str) {   context.beginPath();   context.font = '{fontSize} Microsoft Yahei'.replace("{fontSize}",self.fontSize+"px");   context.fillStyle = 'white';   context.textAlign = 'right';   context.fillText(str,x,self.options.canvasHeight-y);   context.closePath();  }  //画x轴title  function drawXText(context,x,y,str) {   context.beginPath();   context.font = '{fontSize} Microsoft Yahei'.replace("{fontSize}",self.fontSize+"px");   context.fillStyle = 'white';   context.textAlign = 'center';   context.fillText(str,x,self.options.canvasHeight-y);   context.closePath();  }  function drawDottedLine(context,x1,y1,x2,y2,totalLength,length,lineWidth){   y1 = self.options.canvasHeight-y1;   y2 = self.options.canvasHeight-y2;   var dashLen = length === undefined ? 5 : length;   //计算有多少个线段   context.beginPath();   var num = Math.floor(totalLength/dashLen);   context.lineWidth = lineWidth;   for(var i = 0 ; i < num; i++)   {    context[i%2==0 ? 'moveTo' : 'lineTo'](x1+(x2-x1)/num*i,y1+(y2-y1)/num*i);   }   context.stroke();  } }; window.ChartDraws = ChartDraws;}(window,document));

登录后复制

下面还有一个是实现requestAnimationFrame浏览器兼容的

(function(){ var lastTime = 0; var prefixes = ['ms','webkit','o','moz']; //各浏览器前缀 var requestAnimationFrame = window.requestAnimationFrame; var cancelAnimationFrame = window.cancelAnimationFrame; var prefix; //通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式 for( var i = 0; i < prefixes.length; i++ ) {  if ( requestAnimationFrame && cancelAnimationFrame ) {   break;  }  prefix = prefixes[i];  requestAnimationFrame = requestAnimationFrame || window[ prefix + 'RequestAnimationFrame' ];  cancelAnimationFrame = cancelAnimationFrame || window[ prefix + 'CancelAnimationFrame' ] || window[ prefix + 'CancelRequestAnimationFrame' ]; } //如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout if ( !requestAnimationFrame || !cancelAnimationFrame ) {  requestAnimationFrame = function( callback, element ) {   var currTime = new Date().getTime();   //为了使setTimteout的尽可能的接近每秒60帧的效果   var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );   var id = window.setTimeout( function() {    callback( currTime + timeToCall );   }, timeToCall );   lastTime = currTime + timeToCall;   return id;  };  cancelAnimationFrame = function( id ) {   window.clearTimeout( id );  }; } window.requestAnimationFrame = requestAnimationFrame; window.cancelAnimationFrame = cancelAnimationFrame;}());

登录后复制

附上调用

ChartDraws({  "containerId" : "chart1",  //canvas所在容器id  "canvasWidth" : 1000,  "canvasHeight" : 250,  "paddingLeft" : 50,  "paddingTop" : 50,  "columnChartData": [   {NO:0,PT:0.2,Name:"Html/Css"},   {NO:1,PT:0.4,Name:"Html5/Css3"},   {NO:2,PT:0.4,Name:"JavaScript"},   {NO:3,PT:0.5,Name:"JQuery"},   {NO:4,PT:0.2,Name:"Angular.js"},   {NO:5,PT:0.8,Name:"BootStrap"},   {NO:6,PT:0.6,Name:"React.js"},   {NO:7,PT:0.5,Name:"Java"}  ],  "yChartData" : [   {NO:0,Name:"熟悉"},   {NO:1,Name:"掌握"},   {NO:2,Name:"精通"}  ],  "isNeedAnimation" : false,  "isNeedBorder" : false,  "isNeedLineChart":true,  "axisColor" : "#8DEEEE" }); ChartDraws({  "containerId" : "chart2",  //canvas所在容器id  "canvasWidth" : 1000,  "canvasHeight" : 250,  "paddingLeft" : 50,  "paddingTop" : 50,  "columnChartData": [   {NO:0,PT:0.4,Name:"Html/Css"},   {NO:1,PT:0.5,Name:"Html5/Css3"},   {NO:2,PT:0.2,Name:"JavaScript"},   {NO:3,PT:0.7,Name:"JQuery"},   {NO:4,PT:0.2,Name:"Angular.js"},   {NO:5,PT:0.3,Name:"BootStrap"},   {NO:6,PT:0.8,Name:"React.js"},   {NO:7,PT:0.2,Name:"Java"}  ],  "yChartData" : [   {NO:0,Name:"熟悉"},   {NO:1,Name:"掌握"},   {NO:2,Name:"精通"}  ],  "isNeedAnimation" : false,  "isNeedBorder" : false,  "isNeedLineChart":false,  "isNeedColumnChart" : true,  "columnChartColor":"#9370DB" }); ChartDraws({  "containerId" : "chart3",  //canvas所在容器id  "canvasWidth" : 1000,  "canvasHeight" : 250,  "paddingLeft" : 50,  "paddingTop" : 50,  "columnChartData": [   {NO:0,PT:0.4,Name:"Html/Css"},   {NO:1,PT:0.5,Name:"Html5/Css3"},   {NO:2,PT:0.2,Name:"JavaScript"},   {NO:3,PT:0.7,Name:"JQuery"},   {NO:4,PT:0.2,Name:"Angular.js"},   {NO:5,PT:0.3,Name:"BootStrap"},   {NO:6,PT:0.8,Name:"React.js"},   {NO:7,PT:0.2,Name:"Java"}  ],  "yChartData" : [   {NO:0,Name:"熟悉"},   {NO:1,Name:"掌握"},   {NO:2,Name:"精通"}  ],  "isNeedAnimation" : false,  "isNeedBorder" : true,  "isNeedLineChart":true,  "isNeedColumnChart" : false,  "lineChartColor" : "#8DB6CD",  "borderColor" : "#87CEFA" })

登录后复制

html代码

登录后复制

相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

推荐阅读:

vue proxyTable怎么实现接口跨域请求调试

Node.js中如何操作mongodb数据库

以上就是js怎么封装Canvas成插件的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2771070.html

(0)
上一篇 2025年3月8日 12:48:01
下一篇 2025年3月8日 12:48:06

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • JS操作浏览器打开关闭

    这次给大家带来JS操作浏览器打开关闭,JS操作浏览器打开关闭的注意事项有哪些,下面就是实战案例,一起来看一下。 JS监控关闭浏览器操作的实例详解 需求如下: 用户关闭浏览器通知后台。 方案如下: 1.采用js监控关闭浏览器操作。 2.用户关…

    编程技术 2025年3月8日
    200
  • js推拉门效果的实现

    这次给大家带来js推拉门效果的实现,js推拉门效果实现的注意事项有哪些,下面就是实战案例,一起来看一下。 // JavaScript Documentfunction startMove(obj,json,endFn){clearInter…

    编程技术 2025年3月8日
    200
  • Vuejs怎么操作页面区域化

    这次给大家带来Vuejs怎么操作页面区域化,Vuejs操作页面区域化的注意事项有哪些,下面就是实战案例,一起来看一下。 组件的好处 当我用vue写页面的时候,大量的数据页面渲染,引入组件简化主页面的代码量,当代码区域块代码差不多相同时,组件…

    2025年3月8日
    200
  • JS封装插件案例

    这次给大家带来JS封装插件案例,JS封装插件的注意事项有哪些,下面就是实战案例,一起来看一下。 由于项目原因,工作一年多还没用js写过插件,项目太成熟,平时基本都是在使用已经封装好的功能插件。感觉自己好low……这两…

    编程技术 2025年3月8日
    200
  • JSONBuddy的安装步奏详解

    这次给大家带来JSONBuddy的安装步奏详解,JSONBuddy安装的注意事项有哪些,下面就是实战案例,一起来看一下。 JSONBuddy在大家生活中使用还是比较广泛的,很多人可能还不知道JSONBuddy怎么安装,怎么使用,下面文章就给…

    编程技术 2025年3月8日
    200
  • vue.js移动端实现上拉加载下拉刷新

    这次给大家带来vue.js移动端实现上拉加载下拉刷新,vue.js移动端实现上拉加载下拉刷新的注意事项有哪些,下面就是实战案例,一起来看一下。 跟横向滚动一样,我们还是采用better-scroll这个库来实现。由于better已经更新了新…

    编程技术 2025年3月8日
    200
  • Chrome+JS实现断点调试

    这次给大家带来Chrome+JS实现断点调试,Chrome+JS实现断点调试的注意事项有哪些,下面就是实战案例,一起来看一下。 技巧二:快速跳转到某个断点的位置 右侧的Breakpoints会汇总你在JS文件所有打过的断点,点击跟check…

    编程技术 2025年3月8日
    200
  • node.js实现读写同步功能

    //10个数 10个字节,每次读4b,写1blet fs=require(“fs”);function pipe(source,target) { //先创建可读流,再创建可写流 //先读一次,rs.on(data) //将读到的类容写入目…

    编程技术 2025年3月8日
    200
  • js面向对象深入理解

    这次给大家带来js面向对象深入理解,js面向对象深入理解的注意事项有哪些,下面就是实战案例,一起来看一下。 类的声明 1. 构造函数 function Animal() { this.name = ‘name’}// 实例化new Anim…

    编程技术 2025年3月8日
    200
  • 使用JS实现点击循环切换图片(附代码)

    单击循环切换图片var i = 1;function nextImg(){i++;//步骤2:获取页面元素var next = document.getElementById(“nImg”);//步骤3:更改元素的src属性next.src…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论