原生JS使用Canvas实现拖拽式绘图功能


Posted in Javascript onJune 05, 2019

一、实现的功能

1、基于oop思想构建,支持坐标点、线条(由坐标点组成,包含方向)、多边形(由多个坐标点组成)、圆形(包含圆心坐标点和半径)等实体

2、原生JavaScript实现,不依赖任何第三方js库和插件

3、多图形绘制(支持画笔、线条、箭头、三角形、矩形、平行四边形、梯形以及多边形和圆形绘制)

4、拖拽式绘制(鼠标移动过程中不断进行canvas重绘)

5、图片绘制(作为背景图片时重绘会发生闪烁现象,暂时有点问题,后面继续完善)

5、清空绘制功能

6、新版本优化绘制性能(使用共享坐标变量数组,减少了大量的对象创建操作)

7、新版本支持箭头绘制功能

二、完整实现代码

DrawingTools =(function(){
//公共方法
      var getDom=function(id){return document.getElementById(id)};
      var isNull=function(s){return s==undefined||typeof(s)=='undefined'||s==null||s=='null'||s==''||s.length<1};
      var hideDefRM=function(){document.oncontextmenu=function(){return false}};//屏蔽浏览器默认鼠标事件
      /**绘图容器*/
      var cbtCanvas;
      /**绘图对象*/
      var cxt;
      /**绘制的图形列表*/
      var shapes=new Array();
      var graphkind={'cursor':0,'pen':1,'line':2,'trian':3,'rect':4,'poly':5,'circle':6,'arrow':21,'parallel':41,'trapezoid':42};
      //背景图片绘制配置
      var bgPictureConfig={
        pic:null,//背景图片地址或路径
        repaint:true,//是否作为永久背景图,每次清除时会进行重绘
      };
      //加载并绘制图片(src:图片路径或地址),默认重绘背景图
      var loadPicture=function(src){
        if(isNull(bgPictureConfig.repaint)||bgPictureConfig.repaint){bgPictureConfig.pic=src}
        var img = new Image();
        img.onload = function(){cxt.drawImage(img,0,0)}
        img.src =src;
      }
      //绘图基础配置
      var paintConfig={lineWidth:1,//线条宽度,默认1
        strokeStyle:'red',//画笔颜色,默认红色
        fillStyle:'red',//填充色
        lineJoin:"round",//线条交角样式,默认圆角
        lineCap:"round",//线条结束样式,默认圆角
      };
      //重新载入绘制样式
      var resetStyle=function(){
        cxt.strokeStyle=paintConfig.strokeStyle;
        cxt.lineWidth=paintConfig.lineWidth;
        cxt.lineJoin=paintConfig.lineJoin;
        cxt.lineCap=paintConfig.lineCap;
        cxt.fillStyle=paintConfig.fillStyle;
      }
      //鼠标图形
      var cursors=['crosshair','pointer'];
      /** 切换鼠标样式*/
      var switchCorser=function(b){
        cbtCanvas.style.cursor=((isNull(b)?isDrawing():b)?cursors[0]:cursors[1]);
      }
      //操作控制变量组
      var ctrlConfig={
        kind:0,//当前绘画分类
        isPainting:false,//是否开始绘制
        startPoint:null,//起始点
        cuGraph:null,//当前绘制的图像
        cuPoint:null,//当前临时坐标点,确定一个坐标点后重新构建
        cuAngle:null,//当前箭头角度
        vertex:[],//坐标点
      }
      /**获取当前坐标点*/
      var getCuPoint=function(i){
        return ctrlConfig.cuPoint[i];
      }
      /**设置当前坐标点*/
      var setCuPoint=function(p,i){
        return ctrlConfig.cuPoint[i]=p;
      }
      /**设置当前临时坐标点值*/
      var setCuPointXY=function(x,y,i){
        if(isNull(ctrlConfig.cuPoint)){
          var arr=new Array();
          arr[i]=new Point(x,y);
          ctrlConfig.cuPoint=arr;
        }else if(isNull(ctrlConfig.cuPoint[i])){
          setCuPoint(new Point(x,y),i);
        }else{
          ctrlConfig.cuPoint[i].setXY(x,y);
        }
        return getCuPoint(i);
      }
      /**是否正在绘制*/
      var isDrawing=function (){
        return ctrlConfig.isPainting;
      }
      /**开始绘制状态*/
      var beginDrawing=function(){
        ctrlConfig.isPainting=true;
      }
      /**结束绘制状态*/
      var stopDrawing=function(){
        ctrlConfig.isPainting=false;
      }
      /**是否有开始坐标点*/
      var hasStartPoint=function(){
        return !isNull(ctrlConfig.startPoint);
      }
      /**设置当前绘制的图形*/
      var setCuGraph=function(g){
        ctrlConfig.cuGraph=g;
      }
      /**获取当前绘制的图形*/
      var getCuGraph=function(){
        return ctrlConfig.cuGraph;
      }
      /**设置开始坐标点(线条的起始点,三角形的顶点,圆形的圆心,四边形的左上角或右下角,多边形的起始点)*/
      var setStartPoint=function(p){
        ctrlConfig.startPoint=p;
      }
      /**获取开始坐标点*/
      var getStartPoint=function(){
        return ctrlConfig.startPoint;
      }
      /**清空全部*/
      var clearAll=function(){
        cxt.clearRect(0,0,cbtCanvas.width,cbtCanvas.height);
      }
      /**重绘*/
      var repaint=function(){
        clearAll();
        /*
        if(bgPictureConfig.repaint){
          loadPicture(bgPictureConfig.pic);
        }*/
      }
      /**点(坐标,绘图的基本要素,包含x,y坐标)*/
      var Point=(function(x1,y1){
        var x=x1,y=y1;
        return{
          set:function(p){
            x=p.x,y=p.y;
          },
          setXY:function(x2,y2){
            x=x2;y=y2;
          },
          setX:function(x3){
            x=x3;
          },
          setY:function(y3){
            y=y3;
          },
          getX:function(){
            return x;
          },
          getY:function(){
            return y;
          }
        }
      });
      /**多角形(三角形、矩形、多边形),由多个点组成*/
      var Poly=(function(ps1){
        var ps=isNull(ps1)?new Array():ps1;
        var size=ps.length;
        return{
          set:function(ps2){
            ps=ps2;
          },
          getSize:function(){
            return size;
          },
          setPoint:function(p,i){
            if(isNull(p)&&isNaN(i)){
              return;
            }
            ps[i]=p;
          },
          setStart:function(p1){
            if(isNull(ps)){
              ps=new Array();
              return ps.push(p1);
            }else{
              ps[0]=p1;
            }
          },
          add:function(p){
            if(isNull(ps)){
              ps=new Array();
            }
            return ps.push(p);
          },
          pop:function(){
            if(isNull(ps)){
              return;
            }
            return ps.pop();
          },
          shift:function(){
            if(isNull(ps)){
              return;
            }
            return ps.shift;
          },
          get:function(){
            if(isNull(ps)){
              return null;
            }
            return ps;
          },
          draw:function(){
            cxt.beginPath();
            for(i in ps){
              if(i==0){
                cxt.moveTo(ps[i].getX(),ps[i].getY());
              }else{
                cxt.lineTo(ps[i].getX(),ps[i].getY());
              }
            }
            cxt.closePath();
            cxt.stroke();
          }
        }
      });
      /*线条(由两个点组成,包含方向)*/
      var Line=(function(p1,p2,al){
        var start=p1,end=p2,angle=al;
        var drawLine=function(){
          cxt.beginPath();
          cxt.moveTo(p1.getX(),p1.getY());
          cxt.lineTo(p2.getX(),p2.getY());
          cxt.stroke();
        }
        //画箭头
        var drawArrow=function() {
          var vertex =ctrlConfig.vertex;
          var x1=p1.getX(),y1=p1.getY(),x2=p2.getX(),y2=p2.getY();
          var el=50,al=15;
          //计算箭头底边两个点(开始点,结束点,两边角度,箭头角度)
          vertex[0] = x1,vertex[1] = y1, vertex[6] = x2,vertex[7] = y2;
          //计算起点坐标与X轴之间的夹角角度值
          var angle = Math.atan2(y2 - y1, x2 - x1) / Math.PI * 180;
          var x = x2 - x1,y = y2 - y1,length = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
          if (length < 250) {
            el/=2,al/2;
          }else if(length<500){
            el*=length/500,al*=length/500;
          }
          vertex[8] = x2 - el * Math.cos(Math.PI / 180 * (angle + al));
          vertex[9] = y2- el * Math.sin(Math.PI / 180 * (angle + al));
          vertex[4] = x2- el* Math.cos(Math.PI / 180 * (angle - al));
          vertex[5] = y2 - el * Math.sin(Math.PI / 180 * (angle - al));
          //获取另外两个顶点坐标
          x=(vertex[4]+vertex[8])/2,y=(vertex[5]+vertex[9])/2;
          vertex[2] = (vertex[4] + x) / 2;
          vertex[3] = (vertex[5] + y) / 2;
          vertex[10] = (vertex[8] +x) / 2;
          vertex[11] = (vertex[9] +y) / 2;
          //计算完成,开始绘制
          cxt.beginPath();
          cxt.moveTo(vertex[0], vertex[1]);
          cxt.lineTo(vertex[2], vertex[3]);
          cxt.lineTo(vertex[4], vertex[5]);
          cxt.lineTo(vertex[6], vertex[7]);
          cxt.lineTo(vertex[8], vertex[9]);
          cxt.lineTo(vertex[10], vertex[11]);
          cxt.closePath();
          cxt.fill();
          cxt.stroke();
        }
        return{
          setStart:function(s){
            start=s;
          },
          setEnd:function(e){
            end=e;
          },
          getStart:function(){
            return start;
          },
          getEnd:function(){
            return end;
          },
          draw:function(){
            if(angle){
              drawArrow();
            }else{
              drawLine();
            }
          }
        }
      });
      /**圆形(包含圆心点和半径)*/
      var Circle=(function(arr){
        //包含起始点(圆心)和结束点,以及圆半径
        var startPoint=arr.start,endPoint=arr.end,radius=arr.radius;
        /*绘制圆*/
        var drawCircle=function(){
          cxt.beginPath();
          var x=startPoint.getX();
          var y=startPoint.getY();
          if(isNull(radius)){
            radius=calculateRadius(startPoint,endPoint);
          }
          //x,y,半径,开始点,结束点,顺时针/逆时针
          cxt.arc(x,y,radius,0,Math.PI*2,false); // 绘制圆
          cxt.stroke();
        }
        //计算圆半径
        var calculateRadius=function(p1,p2){
          var width=p2.getX()-p1.getX();
          var height=p2.getY()-p1.getY();
          //如果是负数
          if(width<0||height<0){
            width=Math.abs(width);
          }
          //计算两点距离=平方根(width^2+height^2)
          c=Math.sqrt(Math.pow(width,2)+Math.pow(height,2));
          return c;
        }
        return{
          set:function(params){
            startPoint=params.start;
            endPoint=params.end;
            radius=params.radius;
          },
          setPoint:function(p1){
            p=p1;
          },
          getPoint:function(){
            return p;
          },
          setRadius:function(r1){
            radius=r1;
          },
          getRadius:function(){
            return radius;
          },
          calcRadius:calculateRadius,
          //绘制
          draw:drawCircle,
        }
      });
      /**绘制线条工具方法*/
      var drawLine=function(p){
        cxt.beginPath();
        cxt.moveTo(startPosition.getX(),startPosition.getY());
        cxt.lineTo(p.getX(),p.getY());
        cxt.stroke();
      }
      /**绘制三角形工具方法*/
      var drawTrian=function(ps){
        cxt.beginPath();
        var a=ps.get();
        cxt.moveTo(a[0].getX(),a[0].getY());
        cxt.lineTo(a[1].getX(),a[1].getY());
        cxt.lineTo(a[2].getX(),a[2].getY());
        cxt.closePath();
        cxt.stroke();
      }
      /**绘制矩形工具方法*/
      var drawRect=function(p2){
        var p=getStartPoint();
        var width=p.getX()-p2.getX();
        var height=p.getY()-p2.getY();
        cxt.beginPath();
        cxt.strokeRect(x,y,width,height);//绘制矩形
      }
      /*绘制多边形工具方法*/
      var drawpolygon=function(ps){
        if(ps.length>1){//保证只有两个坐标点才是矩形
          cxt.beginPath();
          var p=ctrlConfig.startPoint;
          var x=p.getX();
          var y=p.getY();
          cxt.moveTo(x,y);
          for(p1 in ps){
            cxt.lineTo(p1.getX(),p1.getY());
          }
          cxt.stroke();
        }
      }
      /*绘制圆角矩形工具方法*/
      var drawRoundedRect=function(x,y,width,height,radius){
        cxt.beginPath();
        cxt.moveTo(x,y+radius);
        cxt.lineTo(x,y+height-radius);
        cxt.quadraticCurveTo(x,y+height,x+radius,y+height);
        cxt.lineTo(x+width-radius,y+height);
        cxt.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
        cxt.lineTo(x+width,y+radius);
        cxt.quadraticCurveTo(x+width,y,x+width-radius,y);
        cxt.lineTo(x+radius,y);
        cxt.quadraticCurveTo(x,y,x,y+radius);
        cxt.stroke();
      }
      /*绘制圆工具方法*/
      var drawCircle=function(c){
        var p=c.getPoint();//坐标点
        var x=p.getX();
        var y=p.getY();
        var r=c.getRadius();
        cxt.beginPath();
        //x,y,半径,开始点,结束点,顺时针/逆时针
        cxt.arc(x,y,r,0,Math.PI*2,false); // 绘制圆
        cxt.stroke();
      }
      //计算圆半径工具方法
      var calculateRadius=function(p1,p2){
        var width=p2.getX()-p1.getX();
        var height=p2.getY()-p1.getY();
        //如果是负数
        if(width<0||height<0){
          width=Math.abs(width);
        }
        //计算两点距离=平方根(width^2+height^2)
        c=Math.sqrt(Math.pow(width,2)+Math.pow(height,2));
        return c;
      }
      //鼠标按键点击(首次点击确定开始坐标点,拖动鼠标不断进行图形重绘)
      var mouseDown = function(e){
        var btnNum = e.button;
        if(btnNum==0){
          console.log("选择:"+ctrlConfig.kind);
          //设置起始点
          switch(ctrlConfig.kind){
            case graphkind.pen://画笔(不松开鼠标按键一直画)
              beginDrawing();//开始绘制
              cxt.beginPath();
              cxt.moveTo(e.offsetX,e.offsetY);
              break;
            case graphkind.poly://多边形
              var p=new Point(e.offsetX,e.offsetY);
              if(isDrawing()){
                getCuGraph().add(p);//添加到
              }else{//第一次确定开始坐标
                beginDrawing();//开始绘制
                setStartPoint(p);
                var poly=new Poly();
                poly.add(p);
                setCuGraph(poly);//设置当前绘制图形
              }
              break;
            case graphkind.line://线条
            case graphkind.arrow://方向
            case graphkind.trian://三角形
            case graphkind.rect://矩形
            case graphkind.parallel://平行四边形
            case graphkind.trapezoid://梯形
              beginDrawing();//开始绘制
              var p=new Point(e.offsetX,e.offsetY);
              setStartPoint(p);
              var poly=new Poly();
              poly.add(p);
              setCuGraph(poly);//设置当前绘制图形
              break;
            case graphkind.circle://圆
              console.log("确定图形绘制开始坐标点:"+e.offsetX+","+e.offsetY);//点击确定图形的开始坐标点
              beginDrawing();//开始绘制
              var p=new Point(e.offsetX,e.offsetY);
              setStartPoint(p);
              var circle= new Circle({'start':p});
              setCuGraph(circle);
              break;
            case ctrlConfig.cursor: //手型鼠标
            default://默认是手型鼠标,不允许绘制
          }
        }else if(btnNum==2){
          console.log("右键由于结束多边形绘制");
          if(isDrawing()){
            if(ctrlConfig.kind==graphkind.poly){
              repaint();
              getCuGraph().draw();
              stopDrawing();//结束绘制
            }
          }
        }
        hideDefRM();//屏蔽浏览器默认事件
      }
      //鼠标移动(拖动,根据鼠标移动的位置不断重绘图形)
      var mouseMove = function(e){
        if(isDrawing()&&hasStartPoint()){//检查是否开始绘制,检查是否有开始坐标点
          //画笔不需要重绘
          if(ctrlConfig.kind>1){
            repaint();//重绘
          }
          var p=setCuPointXY(e.offsetX,e.offsetY,0);//设置共享的临时坐标点,用于防止重复创建对象
          switch(ctrlConfig.kind){
            case graphkind.pen://画笔(一直画)
              cxt.lineTo(e.offsetX,e.offsetY);
              cxt.stroke();
              break;
            case graphkind.poly://多边形
              var poly=getCuGraph(poly);
              var size=poly.getSize();
              poly.setPoint(p,(size-1));
              poly.draw();
              break;
            case graphkind.line://线条
              var line=new Line(getStartPoint(),p,false);
              ctrlConfig.cuGraph=line;
              line.draw();
              break;
            case graphkind.arrow://方向
              var line=new Line(getStartPoint(),p,true);
              ctrlConfig.cuGraph=line;
              line.draw();
              break;
            case graphkind.trian://三角形
              var lu=getStartPoint();
              var x2=p.getX();
              var x1=lu.getX();
              //三角形左边的点坐标计算方法:(x1-(x2-x1),y2)
              var x3=x1-(x2-x1);
              var l=setCuPointXY(x3,p.getY(),1);//设置共享的临时坐标点,用于防止重复创建对象
              var poly=getCuGraph();//获取当前图形
              poly.set([lu,p,l]);
              poly.draw();//即时绘制
              break;
            case graphkind.parallel://平行四边形
              var lu=getStartPoint();
              var x3=p.getX();
              var x1=lu.getX();
              //平行四边形两个未知坐标点计算方法:(x1-(x3-x1),y3),(x1+(x3-x1),y1)
              var x2=x3+(x3-x1);
              var x4=x1-(x3-x1);
              var ld=setCuPointXY(x2,lu.getY(),1);//设置共享的临时坐标点,用于防止重复创建对象
              var ru=setCuPointXY(x4,p.getY(),2);//设置共享的临时坐标点,用于防止重复创建对象
              var poly=getCuGraph();//获取当前图形
              poly.set([lu,ru,p,ld]);
              poly.draw();//即时绘制
              break;
            case graphkind.trapezoid://梯形
              var lu=getStartPoint();
              var x3=p.getX();
              var x1=lu.getX();
              //梯形两个未知坐标点计算方法:(x3-(x3-x1)/2,y1),(x1-(x3-x1)/2,y3)
              var x2=x3-(x3-x1)/2;
              var x4=x1-(x3-x1)/2;
              var ld=setCuPointXY(x2,lu.getY(),1);
              var ru=setCuPointXY(x4,p.getY(),2);
              var poly=getCuGraph();
              poly.set([lu,ru,p,ld]);
              poly.draw();
              break;
            case graphkind.rect://矩形
              var lu=getStartPoint();
              //矩形右上角和左上角坐标计算方法
              var ld=setCuPointXY(lu.getX(),p.getY(),1);
              var ru=setCuPointXY(p.getX(),lu.getY(),2);
              var poly=getCuGraph();
              poly.set([lu,ru,p,ld]);
              poly.draw();
              break;
            case graphkind.circle://圆
              var circle=getCuGraph();//获取当前图形
              circle.set({'start':getStartPoint(),'end':p});
              circle.draw();//即时绘制
              break;
          }
        }
      }
      //鼠标按键松开
      var mouseUp = function(e){
        if(isDrawing()){
          //console.log("松开鼠标按键:"+e.offsetX+","+e.offsetY);
          //画笔不需要重绘
          if(ctrlConfig.kind>1){
            repaint();
            getCuGraph().draw();
          }
          if(ctrlConfig.kind!=graphkind.poly){//多边形绘制鼠标按键松开不结束绘制,多边形只有右键点击才能结束绘制
            stopDrawing();//结束绘制
          }
        }
      }
      //鼠标移出
      var mouseOut = function(e){
        console.log("鼠标移出绘制区域"+e.offsetX+","+e.offsetY);
        if(isDrawing()){
          console.log("停止绘制");
          if(ctrlConfig.kind>1){
            repaint();
            getCuGraph().draw();
          }
          stopDrawing();//停止绘制
        }
      }
      return{
        isNull:isNull,
        getDom:getDom,
        clear:function(){
          stopDrawing();//停止绘制
          repaint();
        },
        /**初始化*/
        init:function(params){
          cbtCanvas=getDom(params.id);
          //浏览器是否支持Canvas
          if (cbtCanvas.getContext){
            /**绘图对象*/
            cxt=cbtCanvas.getContext("2d");
            cbtCanvas.onmousedown = mouseDown;
            cbtCanvas.onmouseup = mouseUp;
            cbtCanvas.onmousemove = mouseMove;
            cbtCanvas.onmouseout = mouseOut;
            resetStyle();//载入样式
            return true;
          }else{
            return false;
          }
        },
        /**设置背景图片*/
        setBgPic:loadPicture,
        /**选择图形类型*/
        begin:function(k){
          console.log("选择绘制图形:"+k);
          if(isNaN(k)){//如果不是数字,先转换为对应字符
            ctrlConfig.kind=kind[k];
          }else{
            ctrlConfig.kind=k;
          }
          switchCorser(true);//切换鼠标样式
        },
        /*手型,并停止绘图*/
        hand:function(){
          ctrlConfig.kind=0;
          stopDrawing();//停止绘制
          switchCorser(false);//切换鼠标样式
        }
      }
    })

三、使用方式

1、图形类型

0:鼠标,1:画笔,2:线条,3:三角形,4:矩形,5:多边形,6:圆形,21:箭头,41:平行四边形,42:梯形

var graphkind={'cursor':0,'pen':1,'line':2,'trian':3,'rect':4,'poly':5,'circle':6,'arrow':21,'parallel':41,'trapezoid':42};

2、初始化以及使用背景图片和画笔选择

var drawUtil=new DrawingTools();
//初始化,(如果浏览器不支持H5,会初始化失败,返回false)
if(drawUtil.init({'id':'calibrationCanvas'})){
//加载图片
var imgsrc='图片地址';
if(!drawUtil.isNull(imgsrc)){
  drawUtil.setBgPic(imgsrc,true);//设置背景图片(异步加载图片)
}
}
drawUtil.begin(1);//选择画笔

2、绘制箭头

drawUtil.begin(21);

总结

以上所述是小编给大家介绍的原生JS使用Canvas实现拖拽式绘图功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
JS 巧妙获取剪贴板数据 Excel数据的粘贴
Jul 09 Javascript
jquery命令汇总,方便使用jquery的朋友
Jun 26 Javascript
jQuery实现简单滚动动画效果
Apr 07 Javascript
深入理解JQuery中的事件与动画
May 18 Javascript
简单实现jQuery弹幕效果
May 06 jQuery
js 倒计时(高效率服务器时间同步)
Sep 12 Javascript
你可能不知道的前端算法之文字避让(inMap)
Jan 12 Javascript
vue无限轮播插件代码实例
May 10 Javascript
解决layer弹出层的内容页点击按钮跳转到新的页面问题
Sep 14 Javascript
Node.js HTTP服务器中的文件、图片上传的方法
Sep 23 Javascript
ant-design-vue 快速避坑指南(推荐)
Jan 21 Javascript
html5 录制mp3音频支持采样率和比特率设置
Jul 15 Javascript
Node.js 路由的实现方法
Jun 05 #Javascript
JS实现动态添加外部js、css到head标签的方法
Jun 05 #Javascript
JS函数动态传递参数的方法分析【基于arguments对象】
Jun 05 #Javascript
jQuery操作cookie的示例代码
Jun 05 #jQuery
JS实现从对象获取对象中单个键值的方法示例
Jun 05 #Javascript
微信小程序如何实现全局重新加载
Jun 05 #Javascript
JS数组Object.keys()方法的使用示例
Jun 05 #Javascript
You might like
PHP 处理TXT文件(打开/关闭/检查/读取)
2013/05/13 PHP
PHP提示Cannot modify header information - headers already sent by解决方法
2014/09/22 PHP
详解php几行代码实现CSV格式文件输出
2017/07/01 PHP
Jquey拖拽控件Draggable使用方法(asp.net环境)
2010/09/28 Javascript
jquery 插件学习(六)
2012/08/06 Javascript
js中function()使用方法
2013/12/24 Javascript
jquery鼠标放上去显示悬浮层即弹出定位的div层
2014/04/25 Javascript
Mvc提交表单的四种方法全程详解
2016/08/10 Javascript
angularJS 指令封装回到顶部示例详解
2017/01/22 Javascript
ES7中利用Await减少回调嵌套的方法详解
2017/11/01 Javascript
使用vue-infinite-scroll实现无限滚动效果
2018/06/22 Javascript
解决vue 格式化银行卡(信用卡)每4位一个符号隔断的问题
2018/09/14 Javascript
layui复选框限制选择个数的方法
2019/09/18 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
python+django加载静态网页模板解析
2017/12/12 Python
Python使用matplotlib实现基础绘图功能示例
2018/07/03 Python
python 设置输出图像的像素大小方法
2019/07/04 Python
python multiprocessing模块用法及原理介绍
2019/08/20 Python
python生成器推导式用法简单示例
2019/10/08 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
2019/10/14 Python
Python + Requests + Unittest接口自动化测试实例分析
2019/12/12 Python
python对批量WAV音频进行等长分割的方法实现
2020/09/25 Python
python Timer 类使用介绍
2020/12/28 Python
M1芯片安装python3.9.1的实现
2021/02/02 Python
anaconda升级sklearn版本的实现方法
2021/02/22 Python
Django实现简单的分页功能
2021/02/22 Python
html5中地理位置定位api接口开发应用小结
2013/01/04 HTML / CSS
欧洲品牌瓷器餐具网上商店:Porzellantreff.de
2018/04/04 全球购物
SQL面试题
2013/12/09 面试题
创业计划实施的7大步骤
2014/02/05 职场文书
说明书范文
2014/05/07 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
2014年监理工作总结范文
2014/11/17 职场文书
小学总务工作总结
2015/08/13 职场文书
总结Java对象被序列化的两种方法
2021/06/30 Java/Android
python实现MD5进行文件去重的示例代码
2021/07/09 Python