返回顶部
首页 > 资讯 > 前端开发 > JavaScript >js如何实现一个Canvas统计图插件
  • 110
分享到

js如何实现一个Canvas统计图插件

2024-04-02 19:04:59 110人浏览 泡泡鱼
摘要

小编给大家分享一下js如何实现一个canvas统计图插件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!先说下实现的功能吧:  1

小编给大家分享一下js如何实现一个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;i<data.length;i++){
    newData.push({
     x:data[i].x,
     y:self.options.canvasHeight-data[i].y
    })
   }
   return newData;
  }

  function drawLine(context,point,width){
   context.beginPath();
   context.moveTo(point[0].x,point[0].y);
   if(point.length>2)
   {
    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;
}());

附上<script>调用

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代码

<div class="section">
 <div id="chart1"></div>
 <div id="chart2"></div>
 <div id="chart3"></div>
 </div>

下面是一个实现后的效果图

js如何实现一个Canvas统计图插件

以上是“js如何实现一个Canvas统计图插件”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网JavaScript频道!

--结束END--

本文标题: js如何实现一个Canvas统计图插件

本文链接: https://lsjlt.com/news/77140.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • js如何实现一个Canvas统计图插件
    小编给大家分享一下js如何实现一个Canvas统计图插件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!先说下实现的功能吧:  1...
    99+
    2024-04-02
  • 如何设计一个JavaScript插件系统
    这篇文章给大家介绍如何设计一个JavaScript插件系统,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。WordPress有插件、 jQuery有插件、Gatsby、Eleventy和...
    99+
    2024-04-02
  • JS+canvas如何画一个圆锥
    这篇文章将为大家详细讲解有关JS+canvas如何画一个圆锥,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。实例代码:<html> <head> &...
    99+
    2024-04-02
  • Canvas如何实现一个六边形能力图
    这篇文章将为大家详细讲解有关Canvas如何实现一个六边形能力图,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、前言六边形能力图如下,由 6 个 六边形组成,每一个顶点代表其在某一方面的能力。这篇文章我...
    99+
    2023-06-09
  • 如何使用node实现一个图片拼接插件
    今天小编给大家分享一下如何使用node实现一个图片拼接插件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起...
    99+
    2024-04-02
  • vue如何实现一个弹窗插件
    这篇文章主要讲解了“vue如何实现一个弹窗插件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue如何实现一个弹窗插件”吧!popup.vue<template> &l...
    99+
    2023-07-04
  • JS如何实现一个单文件组件
    目录概述单文件组件基本概念简单的loader解析组件内容注册组件获取脚本内容DataURI和ObjectURI动态导入实现行为层兼容性问题及其他概述 前端开发人员只要了解过vue.j...
    99+
    2024-04-02
  • js如何实现轮播插件
    这篇文章将为大家详细讲解有关js如何实现轮播插件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。轮播效果在网页中用的很多,swiper是其中最有代表性的作品,它支持水平和竖...
    99+
    2024-04-02
  • js插件如何实现图片滑动验证码
    这篇文章将为大家详细讲解有关js插件如何实现图片滑动验证码,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。jquery.lgymove.js  (function...
    99+
    2024-04-02
  • JavaScript中怎么实现一个插件系统
    这篇文章给大家介绍JavaScript中怎么实现一个插件系统,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。构建一个插件系统让我们从一个名为BetaCalc的示例项目开始。BetaCal...
    99+
    2024-04-02
  • node实现封装一个图片拼接插件
    目录前言插件效果1、横向拼接两张图片2、纵向拼接两张图片3、批量拼接3.1 横向拼接长图3.2 纵向拼接长图4、自定义拼接矩阵插件实现1、单张图片拼接2、量拼接3、自定义矩阵拼接插件...
    99+
    2022-11-13
    node封装图片拼接插件 node封装插件
  • 如何实现一个canvas迷宫游戏
    小编给大家分享一下如何实现一个canvas迷宫游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!正文实现这个小游戏也不难,让我们想想,一个迷宫游戏有哪些基本要素。...
    99+
    2023-06-09
  • 原生JS实现图片轮播 JS实现小广告插件
    最近想用原生JS多实现一些小功能,现在写到博客里,大家可以借鉴,有问题欢迎指出。 轮播图 需求: 图片循环轮播,可点击左右切换,切换状态与<li>绑定,鼠标移入图片悬停,...
    99+
    2024-04-02
  • Android开发中怎么使用canvas绘制一个统计图
    Android开发中怎么使用canvas绘制一个统计图?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。效果如下:  特点:使用非常方便,可放在xml布局文...
    99+
    2023-05-31
    android canvas roi
  • canvas 2d 环形统计图手写实现示例
    目录正文先看看效果看看代码绘制图表解决问题结语正文 其实小程序上面也可以使用 echart 等开源图表库得,而且支持代码包得裁切功能,但是可能我不会用吧,效果不太好,而且我这就一个图...
    99+
    2023-05-16
    canvas 2d 环形统计图 canvas 2d
  • PHP中怎么实现一个统计图表类
    这期内容当中小编将会给大家带来有关PHP中怎么实现一个统计图表类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Google Chart API 可以制出各种统计图表,当前支持线形图、柱形图、饼形图、散点图...
    99+
    2023-06-17
  • js如何实现一个isNaN函数
    这篇文章主要介绍了js如何实现一个isNaN函数,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。自己实现一个 isNaN 函数这里利用了 NaN 值的一个特性,即 NaN 是整...
    99+
    2023-06-27
  • 如何实现一个基于canvas的移动端图片编辑器
    这篇文章给大家分享的是有关如何实现一个基于canvas的移动端图片编辑器的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。该插件是一款脱离jq的移动端图片编辑器。可以应用在移动端H5页面或者微信小程序中。插件实现的功...
    99+
    2023-06-09
  • js实现一个简易的计算器
    利用原生js实现一个简易的计算器(附详细注释),供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <...
    99+
    2024-04-02
  • 使用canvas怎么实现一个拼图功能
    使用canvas怎么实现一个拼图功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现的思路其实挺简单的,主要是通过服务端获取图片链接,图片宽度,图片高度,然后...
    99+
    2023-06-09
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作