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;
};
}
HTML5 canvas 在线画笔绘图工具(四)的更多相关文章
- HTML5 canvas 在线画笔绘图工具(一)
HTML5 canvas 在线画笔绘图工具(一) 功能介绍 这是我用Javascript写的第一个程序,在写的过程中走了很多弯路,所以写完之后想分享出来,给与我一样的初学者做为学习的参考,同时在编写这 ...
- HTML5 canvas 在线画笔绘图工具(三)
组装画板(TDrawBuilder) 在这一小节中我们要把工具条和画板组装起来,让他们可以协同进行工作. 画板通过一个命名为TDrawBuilder来进行组装.在详细讲解TDrawBuilder对象之 ...
- HTML5 canvas 在线画笔绘图工具(二)
Canvas+Javascript 带图标的工具条制作 TToolbar 工具条是由一个TToolbar对象和两个按钮对象(TImageButton.TColorButton)组成,因为之前我大部分时 ...
- html5 canvas在线文本第二步设置(字体边框)等我全部写完,我会写在页面底部
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- HTML5 canvas 在线涂鸦
插件地址 http://bencentra.github.io/jq-signature/ 采用技术 jq-signature.min.js Developed using jQuery 2.1.4. ...
- 18个基于 HTML5 Canvas 开发的图表库
如今,HTML5 可谓如众星捧月一般,受到许多业内巨头的青睐.很多Web开发者也尝试着用 HTML 5 来制作各种各样的富 Web 应用.HTML 5 规范引进了很多新特性,其中之一就是 Canvas ...
- 基于HTML5 Canvas和jQuery 的绘图工具的实现
简单介绍 HTML5 提供了强大的Canvas元素.使用Canvas并结合Javascript 能够实现一些很强大的功能.本文就介绍一下基于HTML5 Canvas 的绘图工具的实现.废话少说,先看成 ...
- [js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具)
之前,我写了一个arc函数的用法:[js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形). arcTo: cxt.arcTo( cx, cy, x2, y2, ...
- Processon 一款基于HTML5的在线作图工具
CSDN的蒋涛不久前在微博上评价说ProcessOn是web版的visio,出于好奇私下对ProcessOn进行了一番研究.最后发现无论是在用户体验上,还是在技术上,ProcessOn都比微软的Vis ...
随机推荐
- poi操作excel设置数据有效性
private void setDataValidationList(short firstRow,short endRow,short firstCol, short endCol,String d ...
- [原]此程序专用来说明C++模板的用法
#include using namespace std; //此程序专用来说明模版的使用 template void swap1(T& a,T& b){ T temp=a; ...
- C语言数据类型转换
变量的数据类型是可以转换的.转换的方法有两种,一种是自动转换,一种是强制转换. 自动转换 自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成.自动转换遵循以下规则: 若参与运算量的类型不同, ...
- connectionStrings基本配置
常用connectionStrings配置: <connectionStrings> <add name="LocalSqlServer" ...
- POP3、SMTP、IMAP和Exchange都是个什么玩意?
很多时候一直对POP3.SMTP.IMAP和Exchange等迷迷糊糊的.下面就整理说明一下: 当前常用的电子邮件协议有SMTP.POP3.IMAP4,它们都隶属于TCP/IP协议簇,默认状态下,分别 ...
- C# 反射_基础
反射用于在程序运行过程中,获取类里面的信息或发现程序集并运行的一个过程.通过反射可以获得.dll和.exe后缀的程序集里面的信息.使用反射可以看到一个程序集内部的类,接口,字段,属性,方法,特性等信息 ...
- C语言的本质(36)——makefile基础
除了Hello World这种极简单的程序之外,一般的程序都是由多个源文件编译链接而成的,这些源文件的处理步骤通常用Makefile来管理.makefile带来的好处就是--"自动化编译&q ...
- Grunt制作个人博客简集
原文:http://www.gbtags.com/gb/share/4916.htm GitHub地址:http://yansm.github.io/fromone/
- The Java™ Tutorials下载地址
1.The Java™ Tutorials下载地址: http://www.oracle.com/technetwork/java/javase/java-tutorial-downloads-200 ...
- poj 3411 Paid Roads(dfs)
Description A network of m roads connects N cities (numbered to N). There may be more than one road ...