原生JS使用Canvas實(shí)現(xiàn)拖拽式繪圖功能
一、實(shí)現(xiàn)的功能
1、基于oop思想構(gòu)建,支持坐標(biāo)點(diǎn)、線條(由坐標(biāo)點(diǎn)組成,包含方向)、多邊形(由多個(gè)坐標(biāo)點(diǎn)組成)、圓形(包含圓心坐標(biāo)點(diǎn)和半徑)等實(shí)體
2、原生JavaScript實(shí)現(xiàn),不依賴任何第三方j(luò)s庫和插件
3、多圖形繪制(支持畫筆、線條、箭頭、三角形、矩形、平行四邊形、梯形以及多邊形和圓形繪制)
4、拖拽式繪制(鼠標(biāo)移動(dòng)過程中不斷進(jìn)行canvas重繪)
5、圖片繪制(作為背景圖片時(shí)重繪會(huì)發(fā)生閃爍現(xiàn)象,暫時(shí)有點(diǎn)問題,后面繼續(xù)完善)
5、清空繪制功能
6、新版本優(yōu)化繪制性能(使用共享坐標(biāo)變量數(shù)組,減少了大量的對象創(chuàng)建操作)
7、新版本支持箭頭繪制功能
二、完整實(shí)現(xiàn)代碼
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}};//屏蔽瀏覽器默認(rèn)鼠標(biāo)事件
/**繪圖容器*/
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,//是否作為永久背景圖,每次清除時(shí)會(huì)進(jìn)行重繪
};
//加載并繪制圖片(src:圖片路徑或地址),默認(rèn)重繪背景圖
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;
}
//繪圖基礎(chǔ)配置
var paintConfig={lineWidth:1,//線條寬度,默認(rèn)1
strokeStyle:'red',//畫筆顏色,默認(rèn)紅色
fillStyle:'red',//填充色
lineJoin:"round",//線條交角樣式,默認(rèn)圓角
lineCap:"round",//線條結(jié)束樣式,默認(rèn)圓角
};
//重新載入繪制樣式
var resetStyle=function(){
cxt.strokeStyle=paintConfig.strokeStyle;
cxt.lineWidth=paintConfig.lineWidth;
cxt.lineJoin=paintConfig.lineJoin;
cxt.lineCap=paintConfig.lineCap;
cxt.fillStyle=paintConfig.fillStyle;
}
//鼠標(biāo)圖形
var cursors=['crosshair','pointer'];
/** 切換鼠標(biāo)樣式*/
var switchCorser=function(b){
cbtCanvas.style.cursor=((isNull(b)?isDrawing():b)?cursors[0]:cursors[1]);
}
//操作控制變量組
var ctrlConfig={
kind:0,//當(dāng)前繪畫分類
isPainting:false,//是否開始繪制
startPoint:null,//起始點(diǎn)
cuGraph:null,//當(dāng)前繪制的圖像
cuPoint:null,//當(dāng)前臨時(shí)坐標(biāo)點(diǎn),確定一個(gè)坐標(biāo)點(diǎn)后重新構(gòu)建
cuAngle:null,//當(dāng)前箭頭角度
vertex:[],//坐標(biāo)點(diǎn)
}
/**獲取當(dāng)前坐標(biāo)點(diǎn)*/
var getCuPoint=function(i){
return ctrlConfig.cuPoint[i];
}
/**設(shè)置當(dāng)前坐標(biāo)點(diǎn)*/
var setCuPoint=function(p,i){
return ctrlConfig.cuPoint[i]=p;
}
/**設(shè)置當(dāng)前臨時(shí)坐標(biāo)點(diǎn)值*/
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;
}
/**開始繪制狀態(tài)*/
var beginDrawing=function(){
ctrlConfig.isPainting=true;
}
/**結(jié)束繪制狀態(tài)*/
var stopDrawing=function(){
ctrlConfig.isPainting=false;
}
/**是否有開始坐標(biāo)點(diǎn)*/
var hasStartPoint=function(){
return !isNull(ctrlConfig.startPoint);
}
/**設(shè)置當(dāng)前繪制的圖形*/
var setCuGraph=function(g){
ctrlConfig.cuGraph=g;
}
/**獲取當(dāng)前繪制的圖形*/
var getCuGraph=function(){
return ctrlConfig.cuGraph;
}
/**設(shè)置開始坐標(biāo)點(diǎn)(線條的起始點(diǎn),三角形的頂點(diǎn),圓形的圓心,四邊形的左上角或右下角,多邊形的起始點(diǎn))*/
var setStartPoint=function(p){
ctrlConfig.startPoint=p;
}
/**獲取開始坐標(biāo)點(diǎn)*/
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);
}*/
}
/**點(diǎn)(坐標(biāo),繪圖的基本要素,包含x,y坐標(biāo))*/
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;
}
}
});
/**多角形(三角形、矩形、多邊形),由多個(gè)點(diǎn)組成*/
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();
}
}
});
/*線條(由兩個(gè)點(diǎn)組成,包含方向)*/
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;
//計(jì)算箭頭底邊兩個(gè)點(diǎn)(開始點(diǎn),結(jié)束點(diǎn),兩邊角度,箭頭角度)
vertex[0] = x1,vertex[1] = y1, vertex[6] = x2,vertex[7] = y2;
//計(jì)算起點(diǎn)坐標(biāo)與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));
//獲取另外兩個(gè)頂點(diǎn)坐標(biāo)
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;
//計(jì)算完成,開始繪制
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();
}
}
}
});
/**圓形(包含圓心點(diǎn)和半徑)*/
var Circle=(function(arr){
//包含起始點(diǎn)(圓心)和結(jié)束點(diǎn),以及圓半徑
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,半徑,開始點(diǎn),結(jié)束點(diǎn),順時(shí)針/逆時(shí)針
cxt.arc(x,y,radius,0,Math.PI*2,false); // 繪制圓
cxt.stroke();
}
//計(jì)算圓半徑
var calculateRadius=function(p1,p2){
var width=p2.getX()-p1.getX();
var height=p2.getY()-p1.getY();
//如果是負(fù)數(shù)
if(width<0||height<0){
width=Math.abs(width);
}
//計(jì)算兩點(diǎn)距離=平方根(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){//保證只有兩個(gè)坐標(biāo)點(diǎn)才是矩形
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();//坐標(biāo)點(diǎn)
var x=p.getX();
var y=p.getY();
var r=c.getRadius();
cxt.beginPath();
//x,y,半徑,開始點(diǎn),結(jié)束點(diǎn),順時(shí)針/逆時(shí)針
cxt.arc(x,y,r,0,Math.PI*2,false); // 繪制圓
cxt.stroke();
}
//計(jì)算圓半徑工具方法
var calculateRadius=function(p1,p2){
var width=p2.getX()-p1.getX();
var height=p2.getY()-p1.getY();
//如果是負(fù)數(shù)
if(width<0||height<0){
width=Math.abs(width);
}
//計(jì)算兩點(diǎn)距離=平方根(width^2+height^2)
c=Math.sqrt(Math.pow(width,2)+Math.pow(height,2));
return c;
}
//鼠標(biāo)按鍵點(diǎn)擊(首次點(diǎn)擊確定開始坐標(biāo)點(diǎn),拖動(dòng)鼠標(biāo)不斷進(jìn)行圖形重繪)
var mouseDown = function(e){
var btnNum = e.button;
if(btnNum==0){
console.log("選擇:"+ctrlConfig.kind);
//設(shè)置起始點(diǎn)
switch(ctrlConfig.kind){
case graphkind.pen://畫筆(不松開鼠標(biāo)按鍵一直畫)
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{//第一次確定開始坐標(biāo)
beginDrawing();//開始繪制
setStartPoint(p);
var poly=new Poly();
poly.add(p);
setCuGraph(poly);//設(shè)置當(dāng)前繪制圖形
}
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);//設(shè)置當(dāng)前繪制圖形
break;
case graphkind.circle://圓
console.log("確定圖形繪制開始坐標(biāo)點(diǎn):"+e.offsetX+","+e.offsetY);//點(diǎn)擊確定圖形的開始坐標(biāo)點(diǎn)
beginDrawing();//開始繪制
var p=new Point(e.offsetX,e.offsetY);
setStartPoint(p);
var circle= new Circle({'start':p});
setCuGraph(circle);
break;
case ctrlConfig.cursor: //手型鼠標(biāo)
default://默認(rèn)是手型鼠標(biāo),不允許繪制
}
}else if(btnNum==2){
console.log("右鍵由于結(jié)束多邊形繪制");
if(isDrawing()){
if(ctrlConfig.kind==graphkind.poly){
repaint();
getCuGraph().draw();
stopDrawing();//結(jié)束繪制
}
}
}
hideDefRM();//屏蔽瀏覽器默認(rèn)事件
}
//鼠標(biāo)移動(dòng)(拖動(dòng),根據(jù)鼠標(biāo)移動(dòng)的位置不斷重繪圖形)
var mouseMove = function(e){
if(isDrawing()&&hasStartPoint()){//檢查是否開始繪制,檢查是否有開始坐標(biāo)點(diǎn)
//畫筆不需要重繪
if(ctrlConfig.kind>1){
repaint();//重繪
}
var p=setCuPointXY(e.offsetX,e.offsetY,0);//設(shè)置共享的臨時(shí)坐標(biāo)點(diǎn),用于防止重復(fù)創(chuàng)建對象
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();
//三角形左邊的點(diǎn)坐標(biāo)計(jì)算方法:(x1-(x2-x1),y2)
var x3=x1-(x2-x1);
var l=setCuPointXY(x3,p.getY(),1);//設(shè)置共享的臨時(shí)坐標(biāo)點(diǎn),用于防止重復(fù)創(chuàng)建對象
var poly=getCuGraph();//獲取當(dāng)前圖形
poly.set([lu,p,l]);
poly.draw();//即時(shí)繪制
break;
case graphkind.parallel://平行四邊形
var lu=getStartPoint();
var x3=p.getX();
var x1=lu.getX();
//平行四邊形兩個(gè)未知坐標(biāo)點(diǎn)計(jì)算方法:(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);//設(shè)置共享的臨時(shí)坐標(biāo)點(diǎn),用于防止重復(fù)創(chuàng)建對象
var ru=setCuPointXY(x4,p.getY(),2);//設(shè)置共享的臨時(shí)坐標(biāo)點(diǎn),用于防止重復(fù)創(chuàng)建對象
var poly=getCuGraph();//獲取當(dāng)前圖形
poly.set([lu,ru,p,ld]);
poly.draw();//即時(shí)繪制
break;
case graphkind.trapezoid://梯形
var lu=getStartPoint();
var x3=p.getX();
var x1=lu.getX();
//梯形兩個(gè)未知坐標(biāo)點(diǎn)計(jì)算方法:(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();
//矩形右上角和左上角坐標(biāo)計(jì)算方法
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();//獲取當(dāng)前圖形
circle.set({'start':getStartPoint(),'end':p});
circle.draw();//即時(shí)繪制
break;
}
}
}
//鼠標(biāo)按鍵松開
var mouseUp = function(e){
if(isDrawing()){
//console.log("松開鼠標(biāo)按鍵:"+e.offsetX+","+e.offsetY);
//畫筆不需要重繪
if(ctrlConfig.kind>1){
repaint();
getCuGraph().draw();
}
if(ctrlConfig.kind!=graphkind.poly){//多邊形繪制鼠標(biāo)按鍵松開不結(jié)束繪制,多邊形只有右鍵點(diǎn)擊才能結(jié)束繪制
stopDrawing();//結(jié)束繪制
}
}
}
//鼠標(biāo)移出
var mouseOut = function(e){
console.log("鼠標(biāo)移出繪制區(qū)域"+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;
}
},
/**設(shè)置背景圖片*/
setBgPic:loadPicture,
/**選擇圖形類型*/
begin:function(k){
console.log("選擇繪制圖形:"+k);
if(isNaN(k)){//如果不是數(shù)字,先轉(zhuǎn)換為對應(yīng)字符
ctrlConfig.kind=kind[k];
}else{
ctrlConfig.kind=k;
}
switchCorser(true);//切換鼠標(biāo)樣式
},
/*手型,并停止繪圖*/
hand:function(){
ctrlConfig.kind=0;
stopDrawing();//停止繪制
switchCorser(false);//切換鼠標(biāo)樣式
}
}
})
三、使用方式
1、圖形類型
0:鼠標(biāo),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,會(huì)初始化失敗,返回false)
if(drawUtil.init({'id':'calibrationCanvas'})){
//加載圖片
var imgsrc='圖片地址';
if(!drawUtil.isNull(imgsrc)){
drawUtil.setBgPic(imgsrc,true);//設(shè)置背景圖片(異步加載圖片)
}
}
drawUtil.begin(1);//選擇畫筆
2、繪制箭頭
drawUtil.begin(21);
總結(jié)
以上所述是小編給大家介紹的原生JS使用Canvas實(shí)現(xiàn)拖拽式繪圖功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
相關(guān)文章
uni?app跨端自定義指令實(shí)現(xiàn)按鈕權(quán)限
這篇文章主要為大家介紹了uni?app跨端自定義指令實(shí)現(xiàn)按鈕權(quán)限詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
微信小程序?qū)崿F(xiàn)二維碼簽到考勤系統(tǒng)
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)二維碼簽到考勤系統(tǒng),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
JavaScript async/await原理及實(shí)例解析
這篇文章主要介紹了JavaScript async/await原理及實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
JavaScript數(shù)組排序功能簡單實(shí)現(xiàn)
這篇文章主要介紹了JavaScript數(shù)組排序功能簡單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
JS將數(shù)字轉(zhuǎn)換成三位逗號分隔的樣式(示例代碼)
本篇文章主要是對JS將數(shù)字轉(zhuǎn)換成三位逗號分隔的樣式(示例代碼)進(jìn)行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助2014-02-02

