前言

需要用到图形绘制,没有找到完整的图形绘制实现,所以自己实现了一个 - -

演示地址:查看演示DEMO

新版本支持IE5+(你没看错,就是某软的IE浏览器)以上任意浏览器的Canvas绘图:http://blog.csdn.net/eguid_1/article/details/79310269项目维护于github:https://github.com/eguid/graffitiCanvas

一、实现的功能

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);

四、演示demo

点击这里跳转demo

项目维护于github:https://github.com/eguid/graffitiCanvas
[Xiàngmù wéihù yú github:Https://Github.Com/eguid/graffitiCanvas]
Project maintenance on github: https: //github.com/eguid/graffitiCanvas
 

原生js实现Canvas实现拖拽式绘图,支持画笔、线条、箭头、三角形和圆形等等图形绘制功能,有实例Demo的更多相关文章

  1. 使用原生JavaScript的Canvas实现拖拽式图形绘制,支持画笔、线条、箭头、三角形、矩形、平行四边形、梯形以及多边形和圆形,不依赖任何库和插件,有演示demo

    前言 需要用到图形绘制,没有找到完整的图形绘制实现,所以自己实现了一个 - - 一.实现的功能 1.基于oop思想构建,支持坐标点.线条(由坐标点组成,包含方向).多边形(由多个坐标点组成).圆形(包 ...

  2. 原生js实现模块来回拖拽效果

    代码比较冗余,还没来得及做整理,往见谅. 主要用到的 JS 事件有: onmousedown:鼠标点下事件 onmousemove:鼠标移动事件 onmouseup:鼠标放开事件 具体代码如下: &l ...

  3. vuejs2.0运用原生js实现简单的拖拽元素功能

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  4. 纯JS Web在线可拖拽的流程设计器

    F2工作流引擎之-纯JS Web在线可拖拽的流程设计器 Web纯JS流程设计器无需编程,完全是通过鼠标拖.拉.拽的方式来完成,支持串行.并行.分支.异或分支.M取N路分支.会签.聚合.多重聚合.退回. ...

  5. EgLine V0.3—LVGL官方拖拽式UI编辑工具(可导出代码)

    ** EdgeLine ** 是LVGL官方团队退出的一款拖拽式UI编辑工具,现在还处于测试间断,目前最新版本为v0.3,已经可导出代码. 注意: 使用该软件需要注册lvgl账号,这一步可能需要代理 ...

  6. canvas 图片拖拽旋转之二——canvas状态保存(save和restore)

    引言 在上一篇日志“canvas 图片拖拽旋转之一”中,对坐标转换有了比较深入的了解,但是仅仅利用坐标转换实现的拖拽旋转,会改变canvas坐标系的状态,从而影响画布上其他元素的绘制.因此,这个时候需 ...

  7. js div浮动层拖拽效果代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 原生js实现canvas气泡冒泡效果

    说明: 本文章主要分为ES5和ES6两个版本 ES5版本是早期版本,后面用ES6重写优化的,建议使用ES6版本. 1, 原生js实现canvas气泡冒泡效果的插件,api丰富,使用简单2, 只需引入J ...

  9. js 实现table表格拖拽和点击表头升降序排序

    js 实现table表格拖拽和点击表头升降序排序,写的比较乱,用的时候可以把其中的一些模块函数提取出来 样式,由于是可拖拽表格,所以样式 table tr th{cursor:move;} js实现 ...

随机推荐

  1. 【C语言天天练(二)】statickeyword

    引言:                 statickeyword不仅能够修饰变量.并且能够修饰函数.了解它的使用方法,不仅对阅读别人的代码有帮助,也有助于自己写出更加健壮的程序. 使用方法:     ...

  2. 美景听听Ai语音导游,助力华为荣耀PLAY手机发布

    6月6日,荣耀PLAY科技酷玩新品发布会在北京大学生体育馆如期举办,美景听听Ai语音讲解助力新EUMI系统智慧旅行成新卖点,震撼登场! 随着生活水平的不断提升,出门旅行已经成了许多亲们释放压力.调节自 ...

  3. 通过PHP获取文件创建与修改时间

    1.获取文件创建时间示例: 1 2 $ctime=filectime("chinawinxp.txt"); echo "创建时间:".date("Y- ...

  4. chessy 提高篇系列 阅读笔记

    java提高篇(一)—–理解java的三大特性之封装 封装的好处, 汇聚属性和方法 减少修改对 其他处的影响 控制get和set方法. java提高篇(二)—–理解java的三大特性之继承 继承的好处 ...

  5. 调整图像的尺寸 - cvResize() 函数实现

    前言 有时会碰到一张图片太大了,想将它缩小.本文将讲解一个很好用的函数解决这个问题. 图像尺寸调整函数 cvResize() // 图像尺寸调整函数 void Resize ( const CvArr ...

  6. python 基础 8.4 re的 spilt() findall() finditer() 方法

      #/usr/bin/python #coding=utf-8 #@Time   :2017/11/18 18:24 #@Auther :liuzhenchuan #@File   :re的spli ...

  7. COGS1532. [IOI2001]移动电话

    1532. [IOI2001]移动电话 ★☆   输入文件:mobilephones.in   输出文件:mobilephones.out   简单对比时间限制:5 s   内存限制:256 MB [ ...

  8. Centos7升级python版本

    升级Python 我的安装目录是/home/python 下载 ` cd /home/python wget https://www.python.org/ftp/python/3.5.0/Pytho ...

  9. android菜鸟学习笔记13----Android控件(二) 自定义控件简单示例

    有时候,可能觉得系统提供的控件太丑,就会需要自定义控件来实现自己想要的效果. 以下主要参考<第一行代码> 1.自定义一个标题栏: 系统自带的标题栏很丑,且没什么大的作用,所以我们之前会在o ...

  10. 【网络与系统安全】20179209 利用metasploit对windows系统的渗透

    这次实验的主角是素有"内网杀手"之称的metasploit.还是少说一些夸赞它的话(因为即使功能再强大,不明白它的原理,不会灵活使用它集成的功能,一样没有用),我们直入主题.简单说 ...