`
xuela_net
  • 浏览: 496037 次
文章分类
社区版块
存档分类
最新评论

HTML5 Canvas中实现文字链接

 
阅读更多

HTML5中没有关于链接的API,所以我们只有自己来实现了。

首先,我们来想一下,链接有什么特点。第一个想到的估计就是它能跳转,这是链接最显著的特点,当然这也是废话,要不怎么能叫链接?第二个想到的可能就是文字下方的下划线;第三可能就是当鼠标盘旋在它上空时,鼠标要变成一只手。这些都不难实现,因为跳转可以用window.open()来实现,下划线用html5 canvas API就能实现,更改鼠标的样式用css改就OK。接下来就来讲一下如何实现这些。

本次开发依然用到了开源引擎lufylegend,引擎的一些信息如下:

引擎官方网站:

http://lufylegend.com/lufylegend

引擎API文档:

http://lufylegend.com/lufylegend/api


一,LLink类


首先我们来创建一个LLink类。代码如下:

function LLink(url,text,type,color,font,size){
	var self = this;
	base(self,LSprite,[]);
	
	self.type = "LLink";
	self.url = url;
	self.openType = type || "blank";
	
	self.x = 0;
	self.y = 0;
}
这只是一个很基本的类,有6个参数,分别是打开【链接的地址】,【显示文字】,【链接打开的类型】,【链接颜色】,【链接字体】,【链接尺寸】。由于这个类是继承自LSprite,所以它享有LSprite的一切属性和函数,比如x,y,addChild()等。(注:在lufylegend中base()函数可用于继承,用法可参照API文档。LSprite的用法亦可以参照API文档上的说明)

接着我们更改它的type属性,以便和其他类进行区分。然后用url属性保存链接,用openType保存链接打开的类型。如果链接类型没有设置,就默认为"blank",表示在新的标签页打开。至于xxx || yyy的用法以前也讲过,意思是如果xxx的值为null之类的,就将值设置为yyy。

由于是继承自LSprite,所以不能直接显示文字。因此要加入一个属性text,这个属性是一个LTextField(用法见API文档)对象,用于显示文字,具体代码如下:

self.text.color = color || "blue";
self.text.font = font || "urf-8";
self.text.size = size || 12;
self.text.x = 0;
self.text.y = 0;
self.text.text = text || url;
self.addChild(self.text);

从上面的代码可以看出,如果不设置链接的显示文字,显示文字就为网址。不设置颜色就自动设置为蓝色

为了方便加一个下划线,我们建立一个名为underLine的LSprite对象,然后通过LSprite实现画线,具体代码如下:

self.underLine = new LSprite();
self.underLine.graphics.drawRect(0,self.text.color,[0,0,self.text.getWidth(),Math.floor(self.text.size * 0.1)],true,self.text.color);
self.underLine.x = 0;
self.underLine.y = parseInt(self.text.getHeight()) + Math.floor(self.text.size * 0.3);
self.addChild(self.underLine);
由于LTextField类没有鼠标事件,所以我们没法判断链接文字是否被点击,为了实现点击事件,我特地问了lufy,lufy给我提了一个dirty way(虽说是一个dirty way,不过还真的好使 ^_^):在文本上方画一个与文本大小一样的透明矩形,由于LSprite是可以加入事件的,而且矩形是可以响应事件的,所以就给自身加一个鼠标事件,如果点到文字上,相当于点到透明矩形上,然后就触发事件。于是我们加一个LSprite:

self.back = new LSprite();
self.back.graphics.drawRect(0,"transparent",[0,0,self.text.getWidth(),self.text.getHeight()],true,"transparent");
self.addChild(self.back);

然后加入鼠标事件:

self.addEventListener(LMouseEvent.MOUSE_DOWN,self._jump);

到现在为止,LLink里的代码有这些:

function LLink(url,text,type,color,font,size){
	var self = this;
	base(self,LSprite,[]);
	
	self.type = "LLink";
	self.url = url;
	self.openType = type || "blank";
	
	self.x = 0;
	self.y = 0;
	
	self.text = new LTextField();
	self.text.color = color || "blue";
	self.text.font = font || "urf-8";
	self.text.size = size || 12;
	self.text.x = 0;
	self.text.y = 0;
	self.text.text = text || url;
	self.addChild(self.text);
	
	self.underLine = new LSprite();
	self.underLine.graphics.drawRect(0,self.text.color,[0,0,self.text.getWidth(),Math.floor(self.text.size * 0.1)],true,self.text.color);
	self.underLine.x = 0;
	self.underLine.y = parseInt(self.text.getHeight()) + Math.floor(self.text.size * 0.3);
	self.addChild(self.underLine);
	
	self.back = new LSprite();
	self.back.graphics.drawRect(0,"transparent",[0,0,self.text.getWidth(),self.text.getHeight()],true,"transparent");
	self.addChild(self.back);
	
	self.addEventListener(LMouseEvent.MOUSE_DOWN,self._jump);
}

二,跳转网页


在上面的代码中我们已经实现了下划线,和链接文字,并且加入了鼠标事件。

接下来要实现一下如何跳转网页。前面我们说了,跳转网页的的话可以用到window.open(),这个函数的用法如下

语法:

window.open(URL,name,features,replace)
参数 描述
URL 一个可选的字符串,声明了要在新窗口中显示的文档的 URL。如果省略了这个参数,或者它的值是空字符串,那么新窗口就不会显示任何文档。
name 一个可选的字符串,该字符串是一个由逗号分隔的特征列表,其中包括数字、字母和下划线,该字符声明了新窗口的名称。这个名称可以用作标记 <a> 和 <form> 的属性 target 的值。如果该参数指定了一个已经存在的窗口,那么 open() 方法就不再创建一个新窗口,而只是返回对指定窗口的引用。在这种情况下,features 将被忽略。
features 一个可选的字符串,声明了新窗口要显示的标准浏览器的特征。如果省略该参数,新窗口将具有所有标准特征。在窗口特征这个表格中,我们对该字符串的格式进行了详细的说明。
replace

一个可选的布尔值。规定了装载到窗口的 URL 是在窗口的浏览历史中创建一个新条目,还是替换浏览历史中的当前条目。支持下面的值:

  • true - URL 替换浏览历史中的当前条目。
  • false - URL 在浏览历史中创建新的条目。

(以上内容来自w3school,网址:http://www.w3school.com.cn/htmldom/met_win_open.asp

有了以上的介绍,我想实现跳转已经是很简单的了。

由于我们的鼠标事件触发的是_jump成员函数,所以加入_jump方法,代码如下:

LLink.prototype._jump = function(event,self){
	var openType = "_" + self.openType;
	window.open(self.url, openType);
}


三,更改鼠标样式

首先,为了了解css如何更改鼠标样式,我先介绍一下css里的cursor属性:

实例

一些不同的光标:
span.crosshair {cursor:crosshair;}
span.help {cursor:help;}
span.wait {cursor:wait;}

可能的值

值 描述
url

需使用的自定义光标的 URL。

注释:请在此列表的末端始终定义一种普通的光标,以防没有由 URL 定义的可用光标。

default 默认光标(通常是一个箭头)
auto 默认。浏览器设置的光标。
crosshair 光标呈现为十字线。
pointer 光标呈现为指示链接的指针(一只手)
move 此光标指示某对象可被移动。
e-resize 此光标指示矩形框的边缘可被向右(东)移动。
ne-resize 此光标指示矩形框的边缘可被向上及向右移动(北/东)。
nw-resize 此光标指示矩形框的边缘可被向上及向左移动(北/西)。
n-resize 此光标指示矩形框的边缘可被向上(北)移动。
se-resize 此光标指示矩形框的边缘可被向下及向右移动(南/东)。
sw-resize 此光标指示矩形框的边缘可被向下及向左移动(南/西)。
s-resize 此光标指示矩形框的边缘可被向下移动(北/西)。
w-resize 此光标指示矩形框的边缘可被向左移动(西)。
text 此光标指示文本。
wait 此光标指示程序正忙(通常是一只表或沙漏)。
help 此光标指示可用的帮助(通常是一个问号或一个气球)。

测试链接:http://www.w3school.com.cn/tiy/t.asp?f=csse_cursor

(以上内容均来自w3school,网址:http://www.w3school.com.cn/css/pr_class_cursor.asp


有了这些就好办多了,lufylegend中有MOUSE_MOVE事件,它是用来判断鼠标是否盘旋在某对象上。用这个事件很显然能做出这个效果,但是出现了一个问题,那就是不能判断鼠标是否在对象之外,换句话说,就是不能把鼠标转换为正常样式。因此,我们就只能自己来做这个事件了。

由于我初略得研究过lufylegend这个引擎,所以了解了LEvent这个类。因此我先用它给整个canvas加一个鼠标移动事件,在LLink构造器中加入代码如下:

LEvent.addEventListener(LGlobal.object,LMouseEvent.MOUSE_MOVE,LStage._addLinkEvent);
由于我们不能直接给对象加入事件,因此取不出对象当前的位置,从而无法判断鼠标是否盘旋在某对象上面。为了解决这个问题,我建立一个列表,把所有的LLink对象都加进去。代码如下:

LStage._linkList = new Array();
给列表添加对象的代码要写到LLink构造器中,如下:

LStage._linkList.push(self);
因为我们加的canvas事件触发LStage._addLinkEvent这个函数,所以把LStage._addLinkEvent代码展示如下:

LStage._addLinkEvent = function(event){ 
	for(var i in LStage._linkList){
		o = LStage._linkList[i];
		if(event.offsetX < parseInt(o.x) + parseInt(o.getWidth()) && event.offsetY < parseInt(o.y) + parseInt(o.getHeight()) + parseInt(Math.floor(o.text.size * 0.4)) && event.offsetX > parseInt(o.x) && event.offsetY > parseInt(o.y)){
			document.body.style.cursor = "pointer";
			return;
		}else{
			document.body.style.cursor = "default";
		}
	}
}
这个代码也不难理解,就是遍历一下上面定义的列表,判断鼠标的位置是否在遍历到的对象上,如果在上面,就更改鼠标样式为一只手,如果不在就改回来。

但是给canvas加事件应该只用加一次,所以我们判断一下是否已经加入,如果是就不再加了,不是的话就继续,说白了就是个判断,因此加一个属性:

LStage._isAddLinkEvent = false;

然后给加事件的地方加一个判断就行了,LLink构造器最后的完整代码如下:

function LLink(url,text,type,color,font,size){
	var self = this;
	base(self,LSprite,[]);
	
	self.type = "LLink";
	self.url = url;
	self.openType = type || "blank";
	
	self.x = 0;
	self.y = 0;
	
	self.text = new LTextField();
	self.text.color = color || "blue";
	self.text.font = font || "urf-8";
	self.text.size = size || 12;
	self.text.x = 0;
	self.text.y = 0;
	self.text.text = text || url;
	self.addChild(self.text);
	
	self.underLine = new LSprite();
	self.underLine.graphics.drawRect(0,self.text.color,[0,0,self.text.getWidth(),Math.floor(self.text.size * 0.1)],true,self.text.color);
	self.underLine.x = 0;
	self.underLine.y = parseInt(self.text.getHeight()) + Math.floor(self.text.size * 0.3);
	self.addChild(self.underLine);
	
	self.back = new LSprite();
	self.back.graphics.drawRect(0,"transparent",[0,0,self.text.getWidth(),self.text.getHeight()],true,"transparent");
	self.addChild(self.back);
	
	LStage._linkList.push(self);
	
	self.addEventListener(LMouseEvent.MOUSE_DOWN,self._jump);
	
	if(LStage._isAddLinkEvent == false){
		LEvent.addEventListener(LGlobal.object,LMouseEvent.MOUSE_MOVE,LStage._addLinkEvent);
		LStage._isAddLinkEvent = true;
	}
}

本次开发所有的代码如下,要用的朋友尽管拿去用,代码也不多,完全免费:

/**
*LLink.js
*/
LStage._linkList = new Array();
LStage._isAddLinkEvent = false;
LStage._addLinkEvent = function(event){
	for(var i in LStage._linkList){
		o = LStage._linkList[i];
		if(event.offsetX < parseInt(o.x) + parseInt(o.getWidth()) && event.offsetY < parseInt(o.y) + parseInt(o.getHeight()) + parseInt(Math.floor(o.text.size * 0.4)) && event.offsetX > parseInt(o.x) && event.offsetY > parseInt(o.y)){
			document.body.style.cursor = "pointer";
			return;
		}else{
			document.body.style.cursor = "default";
		}
	}
}
function LLink(url,text,type,color,font,size){
	var self = this;
	base(self,LSprite,[]);
	
	self.type = "LLink";
	self.url = url;
	self.openType = type || "blank";
	
	self.x = 0;
	self.y = 0;
	
	self.text = new LTextField();
	self.text.color = color || "blue";
	self.text.font = font || "urf-8";
	self.text.size = size || 12;
	self.text.x = 0;
	self.text.y = 0;
	self.text.text = text || url;
	self.addChild(self.text);
	
	self.underLine = new LSprite();
	self.underLine.graphics.drawRect(0,self.text.color,[0,0,self.text.getWidth(),Math.floor(self.text.size * 0.1)],true,self.text.color);
	self.underLine.x = 0;
	self.underLine.y = parseInt(self.text.getHeight()) + Math.floor(self.text.size * 0.3);
	self.addChild(self.underLine);
	
	self.back = new LSprite();
	self.back.graphics.drawRect(0,"transparent",[0,0,self.text.getWidth(),self.text.getHeight()],true,"transparent");
	self.addChild(self.back);
	
	LStage._linkList.push(self);
	
	self.addEventListener(LMouseEvent.MOUSE_DOWN,self._jump);
	
	if(LStage._isAddLinkEvent == false){
		LEvent.addEventListener(LGlobal.object,LMouseEvent.MOUSE_MOVE,LStage._addLinkEvent);
		LStage._isAddLinkEvent = true;
	}
}
LLink.prototype._jump = function(event,self){
	var openType = "_" + self.openType;
	window.open(self.url, openType);
}

要写的时候就直接这样写:

var link = new LLink("http://lufylegend.com","链接测试");
addChild(link);

Over,是不是很简单?


最后奉上演示地址:http://www.cnblogs.com/yorhom/articles/3227576.html
截图如下:


点击链接后跳转网页:




----------------------------------------------------------------

欢迎大家转载我的文章。

转载请注明:转自Yorhom's Game Box

http://blog.csdn.net/yorhomwang

欢迎继续关注我的博客

分享到:
评论

相关推荐

    HTML5 Canvas简单透明文字动画

    NULL 博文链接:https://128kj.iteye.com/blog/2213384

    HTML5Canvas开发详解(第2版)

    资源名称:HTML5 Canvas开发详解(第2版)内容简介:随着Canvas的持续升温,Flash的光芒迅速消退。本书是Canvas的畅销图书,它在上一版的基础上,通过讲解...资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    canvas创建文字笔画坐标,绘制和识别

    3.2 检测 会检测你所链接的点的是完全和本地位置数组是否一致。只有写字笔划与创建的笔划一样时才为正确,顺序可以不一样。 3.3 撤销 撤销笔画 3.4 识别 访问接口,把画布转图片,上传服务器,服务器调用文字识别...

    HTML5 Canvas画印章

    NULL 博文链接:https://128kj.iteye.com/blog/2062673

    HTML5 canvas画圆角框

    NULL 博文链接:https://chinaandroid.iteye.com/blog/606033

    HTML5 Canvas简单淡入淡出游戏启动界面

    NULL 博文链接:https://128kj.iteye.com/blog/2076185

    HTML5 Canvas火焰文字动画特效.zip

    转载请注明原资源链接! 转载请注明原资源链接! 转载请注明原资源链接!

    从入门到精通HTML5——PDF——网盘链接

     第15章 HTML 5中的文件与拖放 280  视频讲解:40分钟  15.1 选择文件 281  15.1.1 通过file对象选择文件 281  15.1.2 使用blob接口获取文件的类型与大小 282  15.1.3 通过类型过滤选择的文件 283  15.2 ...

    Html5中文手册(程序员必备手册)

    11、&lt;base&gt; 定义页面中链接的基准 URL。 12、&lt;bdo&gt; 定义文本显示的方向。 13、&lt;blockquote&gt; 定义摘自另一个源的块引用。 14、&lt;body&gt; 定义文档主体。 15、 定义换行符。 16、&lt;button&gt; 定义按钮。 17、&lt;canvas&gt; ...

    9款令人惊叹的HTML5 3D动画应用

    之前我们已经向大家分享了很多HTML5动画应用了,大部分都非常炫酷,也有一小部分是很实用的。今天我们要向各位HTML5动画爱好者介绍...3、HTML5 Canvas绘制灰太狼 超级可爱 HTML5 Canvas相当于一个[......] 阅读全文&gt;&gt;

    9个非常有意思的HTML5动画推荐

    这次要推荐的是9款非常有意思的HTML5动画,这些动画有些是基于Cavans的,有些是SVG结合HTML5实现的,让我们一起来看看。 1、HTML5梦幻特效 可给任意元素添加魔幻效果 我们之前介绍HTML5动画特效比较多的是HTML5 3D...

    force-graph:在HTML5画布上呈现的力导向图

    链接中的文字(来源) 短划线奇数链接( 源) 突出显示节点/链接(源) 多节点选择( 源) 自动上色的节点/链接(源) 自定义节点形状( 源) 缩放/平移视口(源) 单击以专注于节点( 源) 单击以展开/...

    TagCanvas:HTML5基于画布的标签云

    TagCanvas HTML5画布标签云TagCanvas将文本或图像链接转换为3D旋转标签云。 有关示例,文档等,请访问: :

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    (4)针对系统的功能实现问题,通过结合利用原生态框架与HTML5的跨平台性,实现了“认我测”在线认证检测系统。 综上所述,“认我测”在线认证检测系统,率先填补了认证检测领域移动端的空缺,提供了Web浏览器+...

    delphi 开发经验技巧宝典源码

    0206 如何在DBGrid中实现复制、粘贴功能 137 0207 在DBGrid中将选中的多行删除 137 0208 在DataGrid中如何使标题文字居中 138 0209 如何把ListBox中的内容拖曳到另一个ListBox中 139 0210 把DBGrid中的数据...

    大一网页设计课程期末大作业(包含说明文档)

    4. 使用HTML5元素,CSS3常用样式 5. JavaScript动态更新页面上元素的内容,事件响应 6. 含必要的图片、表格、列表、链接 7. 色彩均衡,页面简洁,文字精炼,体现个性 8. 使用音、视频 9. 使用 Canvas 绘图,CSS动画...

    超炫酷精致的个人网站模板

    首先博客的登录界面login.html:是利用html5和css3结合写出的一个超炫酷的页面,根据canvas粒子制作出背景具有动态的效果。登陆后根据存入数据进行比对,对其用户名、密码、验证码验证,只有通过验证后才能登录成功...

Global site tag (gtag.js) - Google Analytics