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 ...
随机推荐
- 退出ssh,程序继续运行的解决办法
对Unix.Linux类服务器维护经常是通过ssh完成的,而有些操作执行时间较长,如:更新程序.文件备份.软件编译安装等.此时如果断开ssh连接的话,更新程序就会随之被中断.如何保证断开ssh后仍旧能 ...
- thinkphp3.2之模型(M层)
最近学习了php框架thinkphp,回头总结了些学习心得知识,希望对大家有帮助 1.模型的概念: 模型(Model)是 ThinkPHP 中一个很重要的概念,粗略的理解模型就是与数据库交互信息进行c ...
- PROCEDURE_监测系统_告警信息存储过程—产生告警信息插入告警表
create or replace procedure proc_alarmlog(in_id in number, --采集器编码 ...
- JavaScript 类的封装以及实现
类的封装: JavaScript 不是一门面向对象的语言,也不支持类的封装,但是我们可以利用闭包函数的概念去实现类的封装. // 在 Function 内部声明一个闭包函数(对象方法) functio ...
- Centos下搭建 nginx+uwsgi+python
python做web应用最麻烦的还是配置服务器了,此话不假,光中间件就有好几种选择,fastcgi.wsgi.uwsgi,难 免让人眼花缭乱. 而听说uwsgi的效率是fastcgi和wsgi的10倍 ...
- 转(havel 算法)
http://www.cnblogs.com/wally/p/3281361.html poj 1659(havel算法) 题目链接:http://poj.org/problem?id=1659 思路 ...
- sql语句收集
一.基础 1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备 ...
- Kyoya and Colored Balls(组合数)
Kyoya and Colored Balls time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- Winpcap网络编程九之Winpcap实战,ARP协议获得MAC表及主机通信
大家好,本次我们须要完毕的任务是: 完毕两台主机之间的数据通信(数据链路层) 仿真ARP协议获得网段内主机的MAC表 使用帧完毕两台主机的通信(Hello! I'm -) 声明:本文章的目的是为大家的 ...
- LINQ to SQL和Entity Framework对照
LINQ to SQL和Entity Framework都是一种包括LINQ功能的对象关系映射技术.他们之间的本质差别在于EF对数据库架构和我们查询的类型实行了更好的解耦. 使用EF,我们查询的对象不 ...