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 ...
随机推荐
- 从C到C++的升级
C++的语言类型 C++是静态的强类型语言. 静态语言:数据类型在编译期间检查,因此在写程序时需要声明变量的类型 强类型语言:强调数据类型,不同的数据类型间的转换需要进行强制类型转换 C与C++的关系 ...
- (原+译)win7远程连接ubuntu16.04
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5711214.html 原始网址: http://ubuntuhandbook.org/index.ph ...
- WAMP下定义wordpress固定连接出现文章页面404
在修改为如下设置后,一切更新正常,但回到博客主页访问单独文章时出现了404问题 最后一项改为index.php/%postname%后可正常访问,但是去掉那个php文件则不行. 找到的解决方法为:开启 ...
- JavaScript、Ajax与jQuery的关系
简单总结: 1.JS是一门前端语言. 2.Ajax是一门技术,它提供了异步更新的机制,使用客户端与服务器间交换数据而非整个页面文档,实现页面的局部更新. 3.jQuery是一个框架,它对JS进行了封装 ...
- 视差滚动(Parallax Scrolling)效果的原理和实现
视差滚动(Parallax Scrolling)是指让多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验.作为今年网页设计的热点趋势,越来越多的网站应用了这项技术. 一.什么是视差滚 ...
- docker镜像与容器存储结构分析
注意:转载请注明出处:http://www.programfish.com/blog/?p=9 Docker是一个开源的应用容器引擎,主要利用linux内核namespace实现沙盒隔离,用cgrou ...
- js阻止元素的默认事件与冒泡事件
嵌套的div元素,如果父级和子元素都绑定了一些事件,那么在点击最内层子元素时可能会触发父级元素的事件,从而带来一定的影响. 1. event.preventDefault(); -- 阻止元素的默认 ...
- SPOJDIVCNT2: Counting Divisors(莫比乌斯反演)
http://acm.tzc.edu.cn/acmhome/vProblemList.do?method=problemdetail&oj=SPOJ&pid=DIVCNT2 给出n求 ...
- zend支持sql server
1.修改Zend下Db下Adapter下Pdo下Abstract.php中的connect方法 protected function _connect() { // if we already hav ...
- uva 1589 by sixleaves
坑爹的模拟题目.自己对于这种比较复杂点得模拟题的能力概述还不够,还多加练习.贴别是做得时候一直再想如何检查车中间有没有棋子,炮中间有没有棋子.到网上参考别人的代码才发先这么简单的办法,自己尽然想不到. ...