HTML5 canvas 在线画笔绘图工具(二)
Canvas+Javascript 带图标的工具条制作 TToolbar
工具条是由一个TToolbar对象和两个按钮对象(TImageButton、TColorButton)组成,因为之前我大部分时间是使用d.e.l.p.h.i进行开发,所以命名方面比较偏向于d.e.l.p.h.i的风格,请处女座的同学忍耐将就一下。
图标按钮 TImageButton
TImageButton 是一个图标按钮对象,可以设置三个图标文件,分别是正常状态,鼠标移上状态,鼠标点击状态。
下面我们介绍一下TImageButton的参数:
Command是按钮对应的功能编号,比如我们定义1为直线,2为矩形.
NormalSrc, MouseOnSrc, MouseDownSrc 分别为正常状态,鼠标移上状态,鼠标点击状态 的图标地址。
x, y, width, height 按钮在工具条上的位置和尺寸。
Toolbar 为宿主工具条。
Group 是按钮所属分组。
- function TImageButton(Command,
- NormalSrc,
- MouseOnSrc,
- MouseDownSrc,
- x,
- y,
- width,
- height,
- Toolbar,
- group)
- {
- }
下面为在Canvas上绘制按钮图标的代码
当鼠标移进按钮或鼠标移出按钮时,将调用ChangeState来改变按钮的状态.为按钮设置不同的图标属性,然后通过Clear()函数将原来的图素清除,再利用RenderImage函数绘制新的按钮。
- function Clear() {
- Context.clearRect(Toolbar.x + x, Toolbar.y + y, width, height);
- }
- function LoadImage(newsrc) {
- image.src = newsrc;
- if (image.complete) {
- RenderImage(image);
- } else
- image.onload = function() {
- RenderImage(image);
- };
- }
- function RenderImage(image) {
- Context.drawImage(image, Toolbar.x + x, Toolbar.y + y, width, height);
- }
- function ChangeState(NewState) {
- state = NewState;
- Clear();
- if (NewState == CSN)
- LoadImage(NormalSrc);
- else if (NewState == CSO)
- LoadImage(MouseOnSrc);
- else if (NewState == CSD)
- LoadImage(MouseDownSrc);
- }
PointIn函数用于检测鼠标所在位置是否在当前按钮所覆盖区域中。
注意这里的AbsX与AbsY函数,由于鼠标的x值和y值是鼠标在页面中的坐标,而当前TImageButton对象的x,y是其在TToolbar对象中的坐标位置。因此我们在计算该TImageButton所覆盖区域时,应当加上画布在页中的坐标以及TToolbar对象在画布中的偏移量。
- </pre><pre class="javascript" name="code"> function PointIn (testx,testy)
- {
- if ((testx>Absx())&&(testx<(Absx()+width))
- &&(testy>Absy()) && (testy<(Absy()+height)))
- {
- return true;
- }
- else
- return false;
- };
- function Absx() {
- return Canvas.offsetLeft + Toolbar.x + x;
- };
- function Absy() {
- return Canvas.offsetTop + Toolbar.y + y;
- };
颜色选择按钮TColorButton
从下面TColorButton对象的建立参数我们可以看到,它与TImageButton基本类似,按照面向对象的法则,应当抽取一个基类,由两个TColorButton和TImageButton来继承。但我还没有学会如何在Javascript中实现对类的继承,所以暂时将它们分成两个完全不相干的类。
注意一下这个建立函数与TImageButton的唯一区别是它的Command参数不再是保存命令的编号,而是保存颜色的值。
- function TColorButton(Command,
- x,
- y,
- width,
- height,
- Toolbar,
- group)
- {
TColorButton同样有 mousemoveon,mouseleave,click三种状态。当鼠标在按钮上时在颜色选择小框外画一个淡黄色的小框。
- function Clear()
- {
- Context.clearRect(Toolbar.x+ x,Toolbar.y+ y,width,height);
- }
- function RenderButton()
- {
- Context.fillStyle=command;
- Context.fillRect(Toolbar.x+ x, Toolbar.y+ y,width,height);
- if (state==CSO)
- {
- Context.strokeStyle="#FFCC33";
- Context.lineWidth=2;
- Context.strokeRect(Toolbar.x+ x+2, Toolbar.y+ y+2,width-4,height-4);
- }
- }
- function ChangeState(NewState)
- {
- state=NewState;
- Clear();
- RenderButton();
- }
主工具条TToolbar
- function TToolbar(Canvas, x, y, width, height) {
- var Context = Canvas.getContext('2d');
- this.Canvas = Canvas;
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- var CurrentShapeProperty;
- var BorderColor;
- btnList = new Array();
- btnCounter = 0;
- Create();
- }
首先我们来看一下TToolbar的建立参数和成员变量
Canvas是工具条的图象载体,与用户交互的UI元素. x,y 为工具条在画布(Canvas) 上的偏移量,width,height分别为工具条的宽度和高度.
定义画布的上下文
var Context = Canvas.getContext('2d');
CurrentShapeProperty 用于记录选择的一些图形属性 如画笔的宽度,颜色等.
TToolbar负责做两件重要的工作
1.判断鼠标移动到了哪个按钮或者鼠标点击了哪个按钮.
利用 InstallEvents 绑定工具条的画布Canvas鼠标事件.
mousemove函数逐个判断当前工具条所管理的按钮是否获得了鼠标焦点. 如果当前鼠标移到了该按钮上,将该按钮的图标设为相应图标(在testHit函数中).其余图标设置为普通状态.
mousedown 函数逐个判断当前工具条所管理的按钮是否获得了鼠标点击.如果是颜色按钮则将当前选中的颜色值拷贝到大颜色按钮.
- mousemove = function(event) {
- var Current = null;
- for (var i = 0; i < btnList.length; i++) {
- if (btnList[i].testHit(event.clientX, event.clientY) == true)
- Current = btnList[i];
- }
- if (Current != null) {
- for (var i = 0; i < btnList.length; i++) {
- if ((btnList[i] != Current) && (btnList[i].getisChecked() == false))
- btnList[i].setNormal();
- }
- }
- };
- mousedown = function(evnet) {
- var Current = null;
- for (var i = 0; i < btnList.length; i++) {
- if (btnList[i].testMouseDown(event.clientX, event.clientY) == true)
- Current = btnList[i];
- }
- if (Current != null) {
- for (var i = 0; i < btnList.length; i++) {
- if (Current.getGroup() == btnList[i].getGroup()) {
- if (btnList[i] != Current)
- btnList[i].setNormal();
- }
- }
- if (Current.getGroup()==3)
- {
- var Color=Current.Command();
- ColorSelected(Color);
- }
- }
- };
- //安装鼠标移动、点击等方法
- this.InstallEvents = function() {
- Canvas.onmousemove = function(event) {
- mousemove(event);
- };
- Canvas.onmousedown = function(event) {
- mousedown(event);
- };
- };
另外我之前想用以下方法来绑定鼠标事件,没有成功请帮看一下问题出在哪里,谢谢
- function AddEvent(element, eventName, eventHandler) {
- window.alert( typeof element.addEventListener);
- if ( typeof element.addEventListener != "undefined") {
- window.alert(eventHandler);
- element.addEventListener(eventName, eventHandler, false);
- window.alert(element.onmousemove);
- } else
- element.attachEvent(eventName, eventHandler);
- }
- //安装鼠标移动、点击等方法
- this.InstallEvents = function() {
- AddEvent(Canvas,"onmousemove",this.mousemove);
- AddEvent(Canvas,"onmousedown",this.mousedown);
- };
2.管理画图的命令(TComand)
建立绘图命令会在后续的章节进行介绍.
- this.getNewCommand = function(DisplayCanvas) {
- for (var i = 0; i < btnList.length; i++) {
- if (btnList[i].getGroup() == 1) {
- if (btnList[i].getisChecked()) {
- var commandId = btnList[i].Command();
- var command = new TCommand(DisplayCanvas, commandId);
- return command;
- }
- }
- }
- return null;
- };
工具条对象完整代码(TToolbar)
- function TToolbar(Canvas, x, y, width, height) {
- var Context = Canvas.getContext('2d');
- this.Canvas = Canvas;
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- var CurrentShapeProperty;
- var BorderColor;
- btnList = new Array();
- btnCounter = 0;
- Create();
- // InstallEvents();
- function Create() {
- Context.strokeStyle = "black";
- Context.lineWidth = "2";
- Context.strokeRect(x, y, width, height);
- }
- this.AddButton = function(button) {
- btnList[btnCounter++] = button;
- };
- function AddEvent(element, eventName, eventHandler) {
- window.alert( typeof element.addEventListener);
- if ( typeof element.addEventListener != "undefined") {
- window.alert(eventHandler);
- element.addEventListener(eventName, eventHandler, false);
- window.alert(element.onmousemove);
- } else
- element.attachEvent(eventName, eventHandler);
- }
- mousemove = function(event) {
- var Current = null;
- for (var i = 0; i < btnList.length; i++) {
- if (btnList[i].testHit(event.clientX, event.clientY) == true)
- Current = btnList[i];
- }
- if (Current != null) {
- for (var i = 0; i < btnList.length; i++) {
- if ((btnList[i] != Current) && (btnList[i].getisChecked() == false))
- btnList[i].setNormal();
- }
- }
- };
- mousedown = function(evnet) {
- var Current = null;
- for (var i = 0; i < btnList.length; i++) {
- if (btnList[i].testMouseDown(event.clientX, event.clientY) == true)
- Current = btnList[i];
- }
- if (Current != null) {
- for (var i = 0; i < btnList.length; i++) {
- if (Current.getGroup() == btnList[i].getGroup()) {
- if (btnList[i] != Current)
- btnList[i].setNormal();
- }
- }
- if (Current.getGroup()==3)
- {
- var Color=Current.Command();
- ColorSelected(Color);
- }
- }
- };
- //安装鼠标移动、点击等方法
- this.InstallEvents = function() {
- //AddEvent(Canvas,"onmousemove",this.mousemove);
- //AddEvent(Canvas,"onmousedown",this.mousedown);
- //Canvas.onmousemove=this.mousemove;
- Canvas.onmousemove = function(event) {
- mousemove(event);
- };
- Canvas.onmousedown = function(event) {
- mousedown(event);
- };
- };
- this.setBorderColorButton=function(ColorButton)
- {
- BorderColor=ColorButton;
- };
- function ColorSelected (color) {
- BorderColor.setColor(color);
- }
- this.getNewCommand = function(DisplayCanvas) {
- for (var i = 0; i < btnList.length; i++) {
- if (btnList[i].getGroup() == 1) {
- if (btnList[i].getisChecked()) {
- var commandId = btnList[i].Command();
- var command = new TCommand(DisplayCanvas, commandId);
- return command;
- }
- }
- }
- return null;
- };
- this.getShapeProperty = function() {
- if (typeof CurrentShapeProperty=="undefined")
- CurrentShapeProperty = new TShapeProperty();
- CurrentShapeProperty.setLineColor(BorderColor.Command());
- for (var i = 0; i < btnList.length; i++) {
- if (btnList[i].getGroup() == 2) {
- if (btnList[i].getisChecked()) {
- CurrentShapeProperty.setLineWidth(btnList[i].Command());
- }
- }
- }
- return CurrentShapeProperty;
- };
- }
图片按钮完整代码(TImageButton)
- function TImageButton(Command, NormalSrc, MouseOnSrc, MouseDownSrc, x, y, width, height, Toolbar, group) {
- var command = Command;
- var NormalSrc = NormalSrc;
- var MouseOnSrc = MouseOnSrc;
- var MouseDownSrc = MouseDownSrc;
- var x = x;
- var y = y;
- var width = width;
- var height = height;
- var Canvas = Toolbar.Canvas;
- var Context = Canvas.getContext("2d");
- var CSN = "Normal";
- var CSO = "MouseOn";
- var CSD = "MouseDown";
- var state = CSN;
- var Group = group;
- var image = new Image();
- CreateButton();
- function CreateButton() {
- LoadImage(NormalSrc);
- }
- function Absx() {
- return Canvas.offsetLeft + Toolbar.x + x;
- };
- function Absy() {
- return Canvas.offsetTop + Toolbar.y + y;
- };
- function PointIn(testx, testy) {
- if ((testx > Absx()) && (testx < (Absx() + width)) && (testy > Absy()) && (testy < (Absy() + height))) {
- return true;
- } else
- return false;
- };
- function Clear() {
- Context.clearRect(Toolbar.x + x, Toolbar.y + y, width, height);
- }
- function LoadImage(newsrc) {
- image.src = newsrc;
- if (image.complete) {
- RenderImage(image);
- } else
- image.onload = function() {
- RenderImage(image);
- };
- }
- function RenderImage(image) {
- Context.drawImage(image, Toolbar.x + x, Toolbar.y + y, width, height);
- }
- function ChangeState(NewState) {
- state = NewState;
- Clear();
- if (NewState == CSN)
- LoadImage(NormalSrc);
- else if (NewState == CSO)
- LoadImage(MouseOnSrc);
- else if (NewState == CSD)
- LoadImage(MouseDownSrc);
- }
- this.testHit = function(dx, dy) {
- if (PointIn(dx, dy)) {
- if (state == CSN) {
- ChangeState(CSO);
- }
- return true;
- }
- return false;
- };
- this.OnClick = function() {
- };
- this.testMouseDown = function(dx, dy) {
- if (PointIn(dx, dy)) {
- ChangeState(CSD);
- this.OnClick();
- return true;
- }
- return false;
- };
- this.getisChecked = function() {
- return (state == CSD);
- };
- this.Command = function() {
- return command;
- };
- this.MoveOn = function() {
- return (state == CSO);
- };
- this.setNormal = function() {
- ChangeState(CSN);
- };
- this.getGroup = function() {
- return Group;
- };
- }
颜色选择框的完整代码(TColorButton)
- <span style="font-size:12px;">function TColorButton(Command,
- x,
- y,
- width,
- height,
- Toolbar,
- group)
- {
- var command=Command;
- var x=x;
- var y=y;
- var width=width;
- var height=height;
- var Canvas=Toolbar.Canvas;
- var Context=Canvas.getContext("2d");
- var CSN="Normal";
- var CSO="MouseOn";
- var CSD="MouseDown";
- var state=CSN;
- var Group=group;
- CreateButton();
- function CreateButton()
- {
- RenderButton();
- }
- function Absx()
- {
- return Canvas.offsetLeft+Toolbar.x+x;
- };
- function Absy()
- {
- return Canvas.offsetTop+Toolbar.y+y;
- };
- function PointIn (testx,testy)
- {
- if ((testx>Absx())&&(testx<(Absx()+width))
- &&(testy>Absy()) && (testy<(Absy()+height)))
- {
- return true;
- }
- else
- return false;
- };
- function Clear()
- {
- Context.clearRect(Toolbar.x+ x,Toolbar.y+ y,width,height);
- }
- function RenderButton()
- {
- Context.fillStyle=command;
- Context.fillRect(Toolbar.x+ x, Toolbar.y+ y,width,height);
- if (state==CSO)
- {
- Context.strokeStyle="#FFCC33";
- Context.lineWidth=2;
- Context.strokeRect(Toolbar.x+ x+2, Toolbar.y+ y+2,width-4,height-4);
- }
- }
- function ChangeState(NewState)
- {
- state=NewState;
- Clear();
- RenderButton();
- }
- this.testHit=function(dx,dy)
- {
- if (PointIn(dx,dy))
- {
- if (state==CSN)
- {
- ChangeState(CSO);
- }
- return true;
- }
- return false;
- };
- this.testMouseDown=function(dx,dy)
- {
- if (PointIn(dx,dy))
- {
- ChangeState(CSD);
- return true;
- }
- return false;
- };
- this.getisChecked=function()
- {
- return (state==CSD);
- };
- this.Command=function()
- {
- return command;
- };
- this.MoveOn=function()
- {
- return (state==CSO);
- };
- this.setNormal=function()
- {
- ChangeState(CSN);
- };
- this.getGroup=function()
- {
- return Group;
- };
- this.setColor=function(color)
- {
- command=color;
- Context.fillStyle=command;
- Context.fillRect(Toolbar.x+ x, Toolbar.y+ y,width,height);
- };
- }
HTML5 canvas 在线画笔绘图工具(二)的更多相关文章
- HTML5 canvas 在线画笔绘图工具(三)
组装画板(TDrawBuilder) 在这一小节中我们要把工具条和画板组装起来,让他们可以协同进行工作. 画板通过一个命名为TDrawBuilder来进行组装.在详细讲解TDrawBuilder对象之 ...
- HTML5 canvas 在线画笔绘图工具(一)
HTML5 canvas 在线画笔绘图工具(一) 功能介绍 这是我用Javascript写的第一个程序,在写的过程中走了很多弯路,所以写完之后想分享出来,给与我一样的初学者做为学习的参考,同时在编写这 ...
- HTML5 canvas 在线画笔绘图工具(四)
HTML5画图命令 图形的绘制是由TDrawHandler与TCommand 协同工作完成. TDrawHandler需要完成以下工作 1.聚集类用于管理绘图的命令 TCommand 2.管理鼠标事件 ...
- 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 ...
- [js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具)
之前,我写了一个arc函数的用法:[js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形). arcTo: cxt.arcTo( cx, cy, x2, y2, ...
- 基于HTML5 Canvas和jQuery 的绘图工具的实现
简单介绍 HTML5 提供了强大的Canvas元素.使用Canvas并结合Javascript 能够实现一些很强大的功能.本文就介绍一下基于HTML5 Canvas 的绘图工具的实现.废话少说,先看成 ...
- Processon 一款基于HTML5的在线作图工具
CSDN的蒋涛不久前在微博上评价说ProcessOn是web版的visio,出于好奇私下对ProcessOn进行了一番研究.最后发现无论是在用户体验上,还是在技术上,ProcessOn都比微软的Vis ...
随机推荐
- 库函数 Math
int abs( int num ); double fabs( double arg ); long labs( long num ); 函数返回num的绝对值 #include <mat ...
- 基于zigbee与tiny4412开发板的环境监测系统
一.开发板环境搭建 1.tiny4412 linux系统的布置 参考博客:http://www.cnblogs.com/luoxiang/p/4186391.html 二.boa服务器的搭建 下载 ...
- Java学习笔记--Swing用户界面组件
很多与AWT类似. 事件处理参考:Java学习笔记--AWT事件处理 1.设计模式: 模型:存储内容视图:显示内容控制器:处理用户输入· 2. 文本输入常用组件 2.1 文本域: JLabel lab ...
- 【iOS开发】单例模式设计(ARC & MRC)
适用于ARC & MRC // 帮助实现单例设计模式 // .h文件的实现 #define SingletonH(methodName) + (instancetype)shared##met ...
- js判断输入的是单字节还是双字节
计算机上每一个字符.数字.汉字.字母等,都对应着unicode编码,unicode编码小于255的为单字节,大于255.小于65535的为双子节或三字节 查看一个字符对应的unicode编码 var ...
- RAC之RMAN恢复
之前整理的RMAN 有关还原的文章: RMAN 系列(五) ---- RMAN 还原 与 恢复 http://blog.csdn.net/tianlesoftware/archive/2010/07/ ...
- HashMap和Hashtable的差别
1. HashMap 与 Hashtable继承自不同的类 1) HashMap 继承自AbstractMap,而AbstractMap实现了Map接口 2) Hashtable 继承自Dict ...
- 【转】Linux系统调用列表
一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 execve 运行可执行文件 exit 中止进程 _exit 立即中止当前进程 getdtablesize 进程所能打开的最 ...
- hdu 5640 King's Cake(模拟)
Problem Description It is the king's birthday before the military parade . The ministers prepared ...
- HDU 4362 Dragon Ball 线段树
#include <cstdio> #include <cstring> #include <cmath> #include <queue> #incl ...