使用原生JavaScript的Canvas實現拖拽式圖形繪製,支持畫筆、線條、箭頭、三角形、矩形、平行四邊形、梯形以及多邊形和圓形,不依賴任何庫和插件,有演示demo

来源:http://www.cnblogs.com/eguid/archive/2017/11/09/7809187.html
-Advertisement-
Play Games

前言 需要用到圖形繪製,沒有找到完整的圖形繪製實現,所以自己實現了一個 - - 一、實現的功能 1、基於oop思想構建,支持坐標點、線條(由坐標點組成,包含方向)、多邊形(由多個坐標點組成)、圓形(包含圓心坐標點和半徑)等實體 2、原生JavaScript實現,不依賴任何第三方js庫和插件 3、多圖 ...


前言

需要用到圖形繪製,沒有找到完整的圖形繪製實現,所以自己實現了一個 - -

一、實現的功能

1、基於oop思想構建,支持坐標點、線條(由坐標點組成,包含方向)、多邊形(由多個坐標點組成)、圓形(包含圓心坐標點和半徑)等實體

2、原生JavaScript實現,不依賴任何第三方js庫和插件

3、多圖形繪製(支持畫筆、線條、箭頭、三角形、矩形、平行四邊形、梯形以及多邊形和圓形繪製)

4、拖拽式繪製(滑鼠移動過程中不斷進行canvas重繪)

5、圖片繪製(作為背景圖片時重繪會發生閃爍現象,暫時有點問題,後面繼續完善)

5、清空繪製功能

6、新版本優化繪製性能(使用共用坐標變數數組,減少了大量的對象創建操作)

7、新版本支持箭頭繪製功能

二、完整實現代碼

  [javascript] view plain copy  
  1. DrawingTools =(function(){  
  2.     //公共方法  
  3.     var getDom=function(id){return document.getElementById(id)};  
  4.     var isNull=function(s){return s==undefined||typeof(s)=='undefined'||s==null||s=='null'||s==''||s.length<1};  
  5.     var hideDefRM=function(){document.oncontextmenu=function(){return false}};//屏蔽瀏覽器預設滑鼠事件  
  6.     /**繪圖容器*/  
  7.     var cbtCanvas;  
  8.     /**繪圖對象*/  
  9.     var cxt;  
  10.     /**繪製的圖形列表*/  
  11.     var shapes=new Array();  
  12.   
  13.     var graphkind={'cursor':0,'pen':1,'line':2,'trian':3,'rect':4,'poly':5,'circle':6,'arrow':21,'parallel':41,'trapezoid':42};  
  14.     //背景圖片繪製配置  
  15.     var bgPictureConfig={  
  16.             pic:null,//背景圖片地址或路徑  
  17.             repaint:true,//是否作為永久背景圖,每次清除時會進行重繪  
  18.     };  
  19.     //載入並繪製圖片(src:圖片路徑或地址),預設重繪背景圖  
  20.     var loadPicture=function(src){  
  21.         if(isNull(bgPictureConfig.repaint)||bgPictureConfig.repaint){bgPictureConfig.pic=src}  
  22.         var img = new Image();  
  23.         img.onload = function(){cxt.drawImage(img,0,0)}  
  24.         img.src =src;  
  25.     }  
  26.       
  27.     //繪圖基礎配置  
  28.     var paintConfig={lineWidth:1,//線條寬度,預設1  
  29.                 strokeStyle:'red',//畫筆顏色,預設紅色  
  30.                 fillStyle:'red',//填充色  
  31.                 lineJoin:"round",//線條交角樣式,預設圓角  
  32.                 lineCap:"round",//線條結束樣式,預設圓角  
  33.         };  
  34.     //重新載入繪製樣式  
  35.     var resetStyle=function(){  
  36.         cxt.strokeStyle=paintConfig.strokeStyle;  
  37.         cxt.lineWidth=paintConfig.lineWidth;  
  38.         cxt.lineJoin=paintConfig.lineJoin;  
  39.         cxt.lineCap=paintConfig.lineCap;  
  40.         cxt.fillStyle=paintConfig.fillStyle;  
  41.     }  
  42.       
  43.     //滑鼠圖形  
  44.     var cursors=['crosshair','pointer'];  
  45.     /** 切換滑鼠樣式*/  
  46.     var switchCorser=function(b){  
  47.         cbtCanvas.style.cursor=((isNull(b)?isDrawing():b)?cursors[0]:cursors[1]);  
  48.     }  
  49.     //操作控制變數組  
  50.     var ctrlConfig={  
  51.             kind:0,//當前繪畫分類  
  52.             isPainting:false,//是否開始繪製  
  53.             startPoint:null,//起始點  
  54.             cuGraph:null,//當前繪製的圖像  
  55.             cuPoint:null,//當前臨時坐標點,確定一個坐標點後重新構建  
  56.             cuAngle:null,//當前箭頭角度  
  57.             vertex:[],//坐標點  
  58.     }  
  59.     /**獲取當前坐標點*/  
  60.     var getCuPoint=function(i){  
  61.         return ctrlConfig.cuPoint[i];  
  62.     }  
  63.     /**設置當前坐標點*/  
  64.     var setCuPoint=function(p,i){  
  65.         return ctrlConfig.cuPoint[i]=p;  
  66.     }  
  67.     /**設置當前臨時坐標點值*/  
  68.     var setCuPointXY=function(x,y,i){  
  69.         if(isNull(ctrlConfig.cuPoint)){  
  70.             var arr=new Array();  
  71.             arr[i]=new Point(x,y);  
  72.             ctrlConfig.cuPoint=arr;  
  73.         }else if(isNull(ctrlConfig.cuPoint[i])){  
  74.             setCuPoint(new Point(x,y),i);  
  75.         }else{  
  76.             ctrlConfig.cuPoint[i].setXY(x,y);  
  77.         }  
  78.         return getCuPoint(i);  
  79.     }  
  80.       
  81.     /**是否正在繪製*/  
  82.     var isDrawing=function (){  
  83.         return ctrlConfig.isPainting;  
  84.     }  
  85.     /**開始繪製狀態*/  
  86.     var beginDrawing=function(){  
  87.         ctrlConfig.isPainting=true;  
  88.     }  
  89.     /**結束繪製狀態*/  
  90.     var stopDrawing=function(){  
  91.         ctrlConfig.isPainting=false;  
  92.     }  
  93.     /**是否有開始坐標點*/  
  94.     var hasStartPoint=function(){  
  95.         return !isNull(ctrlConfig.startPoint);  
  96.     }  
  97.     /**設置當前繪製的圖形*/  
  98.     var setCuGraph=function(g){  
  99.          ctrlConfig.cuGraph=g;  
  100.     }  
  101.     /**獲取當前繪製的圖形*/  
  102.     var getCuGraph=function(){  
  103.         return ctrlConfig.cuGraph;  
  104.     }  
  105.     /**設置開始坐標點(線條的起始點,三角形的頂點,圓形的圓心,四邊形的左上角或右下角,多邊形的起始點)*/  
  106.     var setStartPoint=function(p){  
  107.         ctrlConfig.startPoint=p;  
  108.     }  
  109.     /**獲取開始坐標點*/  
  110.     var getStartPoint=function(){  
  111.         return ctrlConfig.startPoint;  
  112.     }  
  113.       
  114.     /**清空全部*/  
  115.     var clearAll=function(){  
  116.         cxt.clearRect(0,0,cbtCanvas.width,cbtCanvas.height);  
  117.     }  
  118.     /**重繪*/  
  119.     var repaint=function(){  
  120.         clearAll();  
  121.         /* 
  122.         if(bgPictureConfig.repaint){ 
  123.             loadPicture(bgPictureConfig.pic); 
  124.         }*/  
  125.     }  
  126.       
  127.     /**點(坐標,繪圖的基本要素,包含x,y坐標)*/  
  128.     var Point=(function(x1,y1){  
  129.         var x=x1,y=y1;  
  130.         return{  
  131.             set:function(p){  
  132.                 x=p.x,y=p.y;  
  133.             },  
  134.             setXY:function(x2,y2){  
  135.                 x=x2;y=y2;  
  136.             },  
  137.             setX:function(x3){  
  138.                 x=x3;  
  139.             },  
  140.             setY:function(y3){  
  141.                 y=y3;  
  142.             },  
  143.             getX:function(){  
  144.                 return x;  
  145.             },  
  146.             getY:function(){  
  147.                 return y;  
  148.             }  
  149.         }  
  150.     });  
  151.     /**多角形(三角形、矩形、多邊形),由多個點組成*/  
  152.     var Poly=(function(ps1){  
  153.         var ps=isNull(ps1)?new Array():ps1;  
  154.         var size=ps.length;  
  155.         return{  
  156.             set:function(ps2){  
  157.                 ps=ps2;  
  158.             },  
  159.             getSize:function(){  
  160.                 return size;  
  161.             },  
  162.             setPoint:function(p,i){  
  163.                 if(isNull(p)&&isNaN(i)){  
  164.                     return;  
  165.                 }  
  166.                 ps[i]=p;  
  167.             },  
  168.             setStart:function(p1){  
  169.                 if(isNull(ps)){  
  170.                     ps=new Array();  
  171.                     return ps.push(p1);  
  172.                 }else{  
  173.                     ps[0]=p1;  
  174.                 }  
  175.             },  
  176.             add:function(p){  
  177.                 if(isNull(ps)){  
  178.                     ps=new Array();  
  179.                 }  
  180.                 return ps.push(p);  
  181.             },  
  182.             pop:function(){  
  183.                 if(isNull(ps)){  
  184.                     return;  
  185.                 }  
  186.                 return ps.pop();  
  187.             },  
  188.             shift:function(){  
  189.                 if(isNull(ps)){  
  190.                     return;  
  191.                 }  
  192.                 return ps.shift;  
  193.             },  
  194.             get:function(){  
  195.                 if(isNull(ps)){  
  196.                     return null;  
  197.                 }  
  198.                 return ps;  
  199.             },  
  200.             draw:function(){  
  201.                 cxt.beginPath();  
  202.                 for(i in ps){  
  203.                     if(i==0){  
  204.                         cxt.moveTo(ps[i].getX(),ps[i].getY());  
  205.                     }else{  
  206.                         cxt.lineTo(ps[i].getX(),ps[i].getY());  
  207.                     }  
  208.                 }  
  209.                 cxt.closePath();  
  210.                 cxt.stroke();  
  211.             }  
  212.         }  
  213.     });  
  214.     /*線條(由兩個點組成,包含方向)*/  
  215.     var Line=(function(p1,p2,al){  
  216.         var start=p1,end=p2,angle=al;  
  217.           
  218.         var drawLine=function(){  
  219.             cxt.beginPath();  
  220.             cxt.moveTo(p1.getX(),p1.getY());  
  221.             cxt.lineTo(p2.getX(),p2.getY());  
  222.             cxt.stroke();  
  223.         }  
  224.         //畫箭頭  
  225.         var drawArrow=function() {  
  226.             var vertex =ctrlConfig.vertex;  
  227.             var x1=p1.getX(),y1=p1.getY(),x2=p2.getX(),y2=p2.getY();  
  228.             var el=50,al=15;        
  229.             //計算箭頭底邊兩個點(開始點,結束點,兩邊角度,箭頭角度)  
  230.             vertex[0] = x1,vertex[1] = y1, vertex[6] = x2,vertex[7] = y2;  
  231.             //計算起點坐標與X軸之間的夾角角度值  
  232.             var angle = Math.atan2(y2 - y1, x2 - x1) / Math.PI * 180;  
  233.             var x = x2 - x1,y = y2 - y1,length = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));  
  234.             if (length < 250) {  
  235.                 el/=2,al/2;  
  236.             }else if(length<500){  
  237.                 el*=length/500,al*=length/500;  
  238.             }  
  239.             vertex[8] = x2 - el * Math.cos(Math.PI / 180 * (angle + al));  
  240.             vertex[9] = y2- el * Math.sin(Math.PI / 180 * (angle + al));  
  241.             vertex[4] = x2- el* Math.cos(Math.PI / 180 * (angle - al));  
  242.             vertex[5] = y2 - el * Math.sin(Math.PI / 180 * (angle - al));  
  243.             //獲取另外兩個頂點坐標  
  244.             x=(vertex[4]+vertex[8])/2,y=(vertex[5]+vertex[9])/2;  
  245.             vertex[2] = (vertex[4] + x) / 2;  
  246.             vertex[3] = (vertex[5] + y) / 2;  
  247.             vertex[10] = (vertex[8] +x) / 2;  
  248.             vertex[11] = (vertex[9] +y) / 2;  
  249.             //計算完成,開始繪製  
  250.             cxt.beginPath();  
  251.             cxt.moveTo(vertex[0], vertex[1]);  
  252.             cxt.lineTo(vertex[2], vertex[3]);  
  253.             cxt.lineTo(vertex[4], vertex[5]);  
  254.             cxt.lineTo(vertex[6], vertex[7]);  
  255.             cxt.lineTo(vertex[8], vertex[9]);  
  256.             cxt.lineTo(vertex[10], vertex[11]);  
  257.             cxt.closePath();  
  258.             cxt.fill();  
  259.             cxt.stroke();  
  260.         }  
  261.         return{  
  262.             setStart:function(s){  
  263.                 start=s;  
  264.             },  
  265.             setEnd:function(e){  
  266.                 end=e;  
  267.             },  
  268.             getStart:function(){  
  269.                 return start;  
  270.             },  
  271.             getEnd:function(){  
  272.                 return end;   
  273.             },  
  274.             draw:function(){  
  275.                 if(angle){  
  276.                     drawArrow();  
  277.                 }else{  
  278.                     drawLine();  
  279.                 }  
  280.             }  
  281.         }  
  282.     });  
  283.     /**圓形(包含圓心點和半徑)*/  
  284.     var Circle=(function(arr){  
  285.         //包含起始點(圓心)和結束點,以及圓半徑  
  286.         var startPoint=arr.start,endPoint=arr.end,radius=arr.radius;  
  287.         /*繪製圓*/  
  288.         var drawCircle=function(){  
  289.             cxt.beginPath();  
  290.             var x=startPoint.getX();  
  291.             var y=startPoint.getY();  
  292.             if(isNull(radius)){  
  293.                 radius=calculateRadius(startPoint,endPoint);  
  294.             }  
  295.             //x,y,半徑,開始點,結束點,順時針/逆時針  
  296.             cxt.arc(x,y,radius,0,Math.PI*2,false); // 繪製圓  
  297.             cxt.stroke();  
  298.         }  
  299.         //計算圓半徑  
  300.         var calculateRadius=function(p1,p2){  
  301.             var width=p2.getX()-p1.getX();  
  302.             var height=p2.getY()-p1.getY();  
  303.             //如果是負數  
  304.             if(width<0||height<0){  
  305.                 width=Math.abs(width);  
  306.             }  
  307.             //計算兩點距離=平方根(width^2+height^2)  
  308.             c=Math.sqrt(Math.pow(width,2)+Math.pow(height,2));  
  309.             return c;  
  310.         }  
  311.         return{  
  312.             set:function(params){  
  313.                 startPoint=params.start;  
  314.                 endPoint=params.end;  
  315.                 radius=params.radius;  
  316.             },  
  317.             setPoint:function(p1){  
  318.                 p=p1;  
  319.             },  
  320.             getPoint:function(){  
  321.                 return p;  
  322.             },  
  323.             setRadius:function(r1){  
  324.                 radius=r1;  
  325.             },  
  326.             getRadius:function(){  
  327.                 return radius;  
  328.             },  
  329.             calcRadius:calculateRadius,  
  330.             //繪製  
  331.             draw:drawCircle,  
  332.         }  
  333.     });  
  334.     /**繪製線條工具方法*/  
  335.     var drawLine=function(p){  
  336.         cxt.beginPath();  
  337.         cxt.moveTo(startPosition.getX(),startPosition.getY());  
  338.         cxt.lineTo(p.getX(),p.getY());  
  339.         cxt.stroke();  
  340.     }  
  341.   
  342.     /**繪製三角形工具方法*/  
  343.     var drawTrian=function(ps){  
  344.         cxt.beginPath();  
  345.         var a=ps.get();  
  346.         cxt.moveTo(a[0].getX(),a[0].getY());  
  347.         cxt.lineTo(a[1].getX(),a[1].getY());  
  348.         cxt.lineTo(a[2].getX(),a[2].getY());  
  349.         cxt.closePath();  
  350.         cxt.stroke();  
  351.     }  
  352.       
  353.     /**繪製矩形工具方法*/  
  354.     var drawRect=function(p2){  
  355.             var p=getStartPoint();  
  356.             var width=p.getX()-p2.getX();  
  357.             var height=p.getY()-p2.getY();  
  358.             cxt.beginPath();  
  359.             cxt.strokeRect(x,y,width,height);//繪製矩形  
  360.     }  
  361.       
  362.     /*繪製多邊形工具方法*/  
  363.     var drawpolygon=function(ps){  
  364.         if(ps.length>1){//保證只有兩個坐標點才是矩形  
  365.             cxt.beginPath();  
  366.             var p=ctrlConfig.startPoint;  
  367.             var x=p.getX();  
  368.             var y=p.getY();  
  369.             cxt.moveTo(x,y);  
  370.             for(p1 in ps){  
  371.                 cxt.lineTo(p1.getX(),p1.getY());  
  372.             }  
  373.             cxt.stroke();  
  374.         }  
  375.     }  
  376.       
  377.     /*繪製圓角矩形工具方法*/  
  378.     var  drawRoundedRect=function(x,y,width,height,radius){  
  379.         cxt.beginPath();  
  380.         cxt.moveTo(x,y+radius);  
  381.         cxt.lineTo(x,y+height-radius);  
  382.         cxt.quadraticCurveTo(x,y+height,x+radius,y+height);  
  383.         cxt.lineTo(x+width-radius,y+height);  
  384.         cxt.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);  
  385.         cxt.lineTo(x+width,y+radius);  
  386.         cxt.quadraticCurveTo(x+width,y,x+width-radius,y);  
  387.         cxt.lineTo(x+radius,y);  
  388.         cxt.quadraticCurveTo(x,y,x,y+radius);  
  389.         cxt.stroke();  
  390.     }  
  391.     /*繪製圓工具方法*/  
  392.     var drawCircle=function(c){  
  393.         var p=c.getPoint();//坐標點  
  394.         var x=p.getX();  
  395.         var y=p.getY();  
  396.         var r=c.getRadius();  
  397.         cxt.beginPath();  
  398.         //x,y,半徑,開始點,結束點,順時針/逆時針  
  399.         cxt.arc(x,y,r,0,Math.PI*2,false); // 繪製圓  
  400.         cxt.stroke();  
  401.     }  
  402.     //計算圓半徑工具方法  
  403.     var calculateRadius=function(p1,p2){  
  404.         var width=p2.getX()-p1.getX();  
  405.         var height=p2.getY()-p1.getY();  
  406.         //如果是負數  
  407.         if(width<0||height<0){  
  408.             width=Math.abs(width);  
  409.         }  
  410.         //計算兩點距離=平方根(width^2+height^2)  
  411.         c=Math.sqrt(Math.pow(width,2)+Math.pow(height,2));  
  412.         return c;  
  413.     }  
  414.       
  415.     //滑鼠按鍵點擊(首次點擊確定開始坐標點,拖動滑鼠不斷進行圖形重繪)  
  416.     var mouseDown = function(e){  
  417.         var btnNum = e.button;  
  418.         if(btnNum==0){  
  419.             console.log("選擇:"+ctrlConfig.kind);  
  420.             //設置起始點  
  421.             switch(ctrlConfig.kind){  
  422.                 case graphkind.pen://畫筆(不鬆開滑鼠按鍵一直畫)  
  423.                     beginDrawing();//開始繪製  
  424.                     cxt.beginPath();  
  425.                     cxt.moveTo(e.offsetX,e.offsetY);  
  426.                     break;  
  427.                 case graphkind.poly://多邊形  
  428.                     var p=new Point(e.offsetX,e.offsetY);  
  429.                     if(isDrawing()){  
  430.                         getCuGraph().add(p);//添加到  
  431.                     }else{//第一次確定開始坐標  
  432.                         beginDrawing();//開始繪製  
  433.                         setStartPoint(p);  
  434.                         var poly=new Poly();  
  435.                         poly.add(p);  
  436.                         setCuGraph(poly);//設置當前繪製圖形  
  437.                     }  
  438.                     break;  
  439.                 case graphkind.line://線條  
  440.                 case graphkind.arrow://方向  
  441.                 case graphkind.trian://三角形  
  442.                 case graphkind.rect://矩形  
  443.                 case graphkind.parallel://平行四邊形  
  444.                 case graphkind.trapezoid://梯形  
  445.                     beginDrawing();//開始繪製  
  446.                     var p=new Point(e.offsetX,e.offsetY);  
  447.                     setStartPoint(p);  
  448.                     var poly=new Poly();  
  449.                     poly.add(p);  
  450.                     setCuGraph(poly);//設置當前繪製圖形  
  451.                     break;  
  452.                 case graphkind.circle://圓  
  453.                     console.log("確定圖形繪製開始坐標點:"+e.offsetX+","+e.offsetY);//點擊確定圖形的開始坐標點  
  454.                     beginDrawing();//開始繪製  
  455.                     var p=new Point(e.offsetX,e.offsetY);  
  456.                     setStartPoint(p);  
  457.                     var circle= new Circle({'start':p});  
  458.                     setCuGraph(circle);  
  459.                     break;  
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 從大一開始學習前端,今年大三,10月份開始投簡歷,陸續收到很多家公司的面試,目前為止的面試通過率是百分之百,總結下麵試題。 今天晚上面的小米不太好,感覺自己回答非常不好,覺得百分百的通過率要終結了,後來面試官打來電話說還OK,真想不到,一會再說小米,他問的問題,哎,真是。。。 算了,說吧。 百度 一 ...
  • 引 如今,各種互聯網的Web應用程式層出不窮,那麼如何快速入門,成長為一個優秀的Web開發工作者呢? 這個問題不容易回答,幾乎所有的培訓機構都不能清晰地解答。 所以對於Web開發剛剛入門的菜鳥們,我覺得只有通過去做,去實驗,學會Web開發,可能是學著學著,實驗著實驗著就會了。 沒有人告訴你如何去做。 ...
  • 中文原地址 1.對所有的引用使用 const 而非 var。這能確保你無法對引用重覆賦值。 當需要變動引用時,使用let。 const和let都是塊級作用域。 2.創建對象的方式: const item = {}; 使用對象屬性的簡寫,且為簡寫的屬性分組。 3.創建數組的方式: const arr ...
  • 你有兩年以上的前端開發經驗嗎?你會用 Sass 和 Autoprefixer 等高級的CSS輔助技能嗎?你的 JavaScript 知識是否融匯貫通,你是否喜歡使用 Gulp , npm 和 jQuery ?如果是這樣,根據 Ashley Nolan 的前端問卷調查,你是一個典型的前端開發工程師。 ...
  • relative/static: 包含塊為最近的塊級框,表單元格或行內塊祖先框的內容邊界構成 absolute: 包含塊為最近的最近的、position不是static的祖先元素 fixed: 包含塊為視窗,結合top | left | right | bottom,left等初始值為auto ...
  • 個人博客記錄:2017-11-09 png 32位無損壓縮演算法形成的圖片,主要用於logo小圖標和一些點綴的小圖像。放大縮小不會失真,質量好 jpeg,jpg 壓縮比例較高(可達到100:1,即壓縮一百倍),放大縮小失真。適用於比較大的圖片,省流量 gif 動態圖,(你懂得),適用於動畫效果。 ...
  • 效果圖展示: 原理很簡單,主要運用transform這個樣式,通過斜切和旋轉達成 html: css: 怎樣,是不是很簡單 ...
  • 在Web前端頁面實現圓角效果,CSS3幫你輕鬆實現,一個人人皆知的屬性 圓角邊框的繪製是Web頁面和Web應用程式中經常用來美化頁面效果的手法之一。今天,小編為大家介紹CSS3提供的可以將矩形變為圓角矩形的一個屬性 技術等級:中級 | 適合有一定的CSS基礎的人士閱讀。 希望收藏了這篇文章的你同時也 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...