HTML5 canvas 在线画笔绘图工具(四)

HTML5画图命令

图形的绘制是由TDrawHandler与TCommand 协同工作完成。

TDrawHandler需要完成以下工作

1、聚集类用于管理绘图的命令 TCommand

2、管理鼠标事件 ,鼠标点击第一下开始绘图,鼠标点击第二下绘图完成。在点第一次和第二次之间在画板上拖动鼠标时系统动态的根据鼠标位置绘图。

3、将所有绘图命令生成json数据,以便于保存。

4、打开新的图形

TCommand类由 直线、矩形、圆几个基本命令组成。

画图控制类 TDrawHandler

如下代码所示

TDrawhandler 首先管理着一个CommandList记载得所有的绘图命令。并通过RedrawScreen 函数完成图形的绘制,该函数循环调用所有的绘图命令的RunCommand函数,完成在画布上的各自绘图任务,最终完成完整的图形绘制。

当检测到画布的第一次鼠标单击事件时,调用 Toolbar的getNewCommand函数,Toolbar会根据当前在Toolbar上选中的命令按钮生成对应的TCommand对象。

</pre><p></p><p><span style="font-size:14px"></span></p><pre name="code" class="javascript">function TDrawHandler(Canvas,Toolbar)
{
var Context=Canvas.getContext('2d');
this.Canvas=Canvas;
this.Toolbar=Toolbar;
var isDrawing=false;
var CommandList=new Array();
var CommandCount=0;
var Title='未命名图片';
var Author='';
var Date='';
var Id='';
var Open=false;
InstallEvents();
function domousedown(event)
{ if (isDrawing==false)
{ CurrentCommand=Toolbar.getNewCommand(Canvas);
CurrentCommand.setShapeProperty(Toolbar.getShapeProperty());
if (CurrentCommand=="undefined") return;
isDrawing=true;
CommandList[CommandCount++]=CurrentCommand;
CurrentCommand.setFirstPoint(event.clientX,event.clientY);
} else
{
CurrentCommand.OnClick();
if (CurrentCommand.Finished())
{
isDrawing=false;
}
}
}
function domouseup(event)
{
//isMouseDown=false;
}
function ClearScreen()
{
Context.clearRect(0,0,Canvas.width,Canvas.height);
} function RedrawScreen()
{ ClearScreen();
for (var i=0;i<CommandList.length;i++)
{
CommandList[i].RunCommand();
}
}
function domousemove(event)
{
if (isDrawing==true)
{
CurrentCommand.setSecondPoint(event.clientX,event.clientY);
//CurrentCommand.RunCommand();
RedrawScreen();
}
}
function InstallEvents()
{
Canvas.onmousedown=function(event)
{
domousedown(event);
};
Canvas.onmousemove=function(event)
{
domousemove(event);
};
Canvas.onmouseup=function(event)
{
domouseup(event);
};
}
this.NewDrawing=function()
{
CommandList=new Array();
CommandCount=0;
RedrawScreen();
Open=false;
};
this.SaveDrawing=function()
{ };
this.haveCommand=function()
{
return CommandList.length>0;
};
function getOneCommand(CommandItem)
{
var JSONCommand="{";
JSONCommand=JSONCommand+'"CommandType":"'+CommandItem.CommandType()+'",';
JSONCommand=JSONCommand+'"LineWidth":"'+CommandItem.getLineWidth()+'",';
JSONCommand=JSONCommand+'"BorderColor":"'+CommandItem.getBorderColor()+'",';
var Point=CommandItem.getPoints();
if (Point.length==0)
{
JSONCommand=JSONCommand+'"Points":[{"x":"'+CommandItem.getFirstPoint().x+'","y":"'+CommandItem.getFirstPoint().y+'"},';
JSONCommand=JSONCommand+'{"x":"'+CommandItem.getSecondPoint().x+'","y":"'+CommandItem.getSecondPoint().y+'"}';
JSONCommand=JSONCommand+"]";
}else
{ } JSONCommand=JSONCommand+"}";
return JSONCommand;
}
this.DrawingToJSON=function()
{
var JSONData='{';
JSONData=JSONData+'"Title":"'+Title+'",';
JSONData=JSONData+'"Author":"'+Author+'",';
JSONData=JSONData+'"Date":"'+Date+'",';
JSONData=JSONData+'"Commands":[';
for (var i=0;i<CommandList.length;i++)
{
if (CommandList[i].Finished())
JSONData=JSONData+getOneCommand(CommandList[i]);
if (i<CommandList.length-1)
JSONData=JSONData+',';
}
JSONData=JSONData+']';
JSONData=JSONData+'}';
return JSONData;
};
this.setId=function(id)
{
Id=id;
};
this.getId=function()
{
return Id;
};
function LoadJsonObject(DrawingGraphics) { Title = DrawingGraphics.Title;
Author = DrawingGraphics.Author;
CommandList.length=0;
for (var i = 0; i < DrawingGraphics.Commands.length; i++) {
var NewCommand = new TCommand(Canvas, DrawingGraphics.Commands[i].CommandType);
CommandList[i] = NewCommand; if (DrawingGraphics.Commands[i].Points.length == 2) {
NewCommand.setFirstPoint(DrawingGraphics.Commands[i].Points[0].x, DrawingGraphics.Commands[i].Points[0].y);
NewCommand.setSecondPoint(DrawingGraphics.Commands[i].Points[1].x, DrawingGraphics.Commands[i].Points[1].y);
ShapeProperty = new TShapeProperty();
ShapeProperty.setLineWidth(DrawingGraphics.Commands[i].LineWidth);
ShapeProperty.setLineColor(DrawingGraphics.Commands[i].BorderColor);
NewCommand.setShapeProperty(ShapeProperty);
} else { };
}
CommandCount=CommandList.length;
RedrawScreen();
}
this.openDrawing=function(DrawingGraphics,drawingid)
{
id=drawingid;
LoadJsonObject(DrawingGraphics);
Open=true;
};
this.getOpen=function()
{
return Open;
};
}

画图命令 TCommand

在TCommand中有三个内部类,分别是TLineCommand、TArcCommand,TRectCommand司职具体的图形绘制任务。

在建立TCommand时自动调用 CreateCommand根据命令的类型建立相应的Command对象。每一个Command内部类均有一个draw函数来完成具体的图形绘制任务。

function TCommand(Canvas,CommandType)
{
var ctLine=1;
var ctRect=2;
var ctArc=3;
var commandtype=CommandType;
var Command;
var firstPoint=new function(){var x;var y;};
var secondPoint=new function(){var x;var y;};
var Context=Canvas.getContext("2d");
var BorderColor='#990000';
var LineWidth=2;
var FillColor='black';
var ShapeProperty;
csRunning='running';
csFinish='finish';
var State=csRunning;
var Points=new Array();
var Offset=new function(){var x=0;var y=0;};
CreateCommand(CommandType);
Offset.x=0;
Offset.y=0;
function CreateCommand(ct)
{ if (ct==1)
Command=new TLineCommand();
else if (ct==2)
Command=new TRectCommand();
else if (ct==3)
Command=new TArcCommand();
}
this.RunCommand=function()
{
Command.draw();
};
function LX(x)
{
return x-Canvas.offsetLeft+Offset.x; }
function LY(y)
{
return y-Canvas.offsetTop+Offset.y; }
function TLineCommand()
{
this.draw=function()
{
Context.strokeStyle=BorderColor;
Context.lineWidth=LineWidth;
Context.beginPath();
Context.moveTo(LX(firstPoint.x),LY(firstPoint.y));
Context.lineTo(LX(secondPoint.x),LY(secondPoint.y));
Context.stroke();
Context.closePath();
};
}
function TRectCommand()
{
this.draw=function()
{
Context.strokeStyle=BorderColor;
Context.lineWidth=LineWidth;
Context.strokeRect(LX(firstPoint.x),LY(firstPoint.y),LX(secondPoint.x)-LX(firstPoint.x),LY(secondPoint.y)-LY(firstPoint.y));
};
}
function TArcCommand()
{
this.draw=function()
{ Context.beginPath();
dx=LX(secondPoint.x)-LX(firstPoint.x);
dy=LY(secondPoint.y)-LY(firstPoint.y);
r=dx>dy?dx:dy;
if (r<0) return;
Context.arc(LX(firstPoint.x),LY(firstPoint.y),r,0,2*Math.PI,1);
Context.strokeStyle = BorderColor;
Context.lineWidth = LineWidth;
Context.stroke();
Context.closePath();
};
}
this.getLineWidth=function()
{
return LineWidth;
};
this.getBorderColor=function()
{
return BorderColor;
};
this.CommandType=function()
{
return commandtype; };
this.setFirstPoint=function(x,y)
{
firstPoint.x=x;
firstPoint.y=y;
};
this.getFirstPoint=function()
{
return firstPoint;
};
this.getSecondPoint=function()
{
return secondPoint;
};
this.setSecondPoint=function(x,y)
{
secondPoint.x=x;
secondPoint.y=y;
};
this.setOffset=function (x,y)
{
Offset.x=x;
Offset.y=y;
};
var Finish=function()
{
State=csFinish;
};
this.Finished=function()
{
return (State==csFinish);
};
this.OnClick=function()
{
if ((commandtype==ctLine)||(commandtype==ctRect)||(commandtype==ctArc))
{
Finish();
}
};
this.setShapeProperty=function(value)
{
ShapeProperty=value;
LineWidth=ShapeProperty.getLineWidth();
BorderColor=ShapeProperty.getLineColor();
};
this.getPoints=function()
{
return Points;
};
}
上一篇:Vim cscope


下一篇:NodeJs之定时器与队列