AS3 Starling 下实现 文本的超链接功能

相信使用Starling开发的,在使用TextField时,会遇到,超链接文件功能不可用的问题;

看一下源码;就知道,毕竟他是在原生的TextField基础上实现的,将TextField draw成Texture然后放到GPU显示;

如果要实现链接功能;

那么有个思路:

1)、获取:超链接文本的显示内容;

2)、获取:超链接文件的链接内容;

3)、使用原生的TextField,计算,第1)点中的,所有显示内容的字符;并计算该所有字符的有效矩形区域;(在Touch或是Mouse交互时,作坐标与矩形区域判断);

           生成类型这样的数据结构,作为触发Link事件数据对象;

           如:var data:Object = {rects:Vector.<Rectangle>, linkTxt:第2)点的链接内容}


这样在加上,Touch事件,判断Touch的End阶段事件,的x,y位置是否与上面的:rects有交集,有则触发事件,并将:linkTxt数据传过事件对象中即可;


下面给出一个GitHub国外人写好的一个(关键要看,回贴内容)

Textfields with hyperlinks

其中有个回贴有提供实现的另一种方式


Jave特别提示:Textfield width hyperlinks中的rects都union在一起,该方法最好还是不要联合一起,特别是对那些链接内容遇到换行时,那么矩形区域就会变得不准确;


自己写了个测试程序:

以下实现方式,我没写使用矩形与交互点的碰撞检测方式;

也是使用了,国外代码的写方,直接使用一个可交互的对象:Sprite

如果要使用矩形方式,那些就得对所有的rect都遍历并碰撞检测试;

如果要优化,还可以使用,四叉树,对矩形的合理分布区域,再做高交的选择性检测;

主要代码:

package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.filters.GlowFilter;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	
	/**
	 * 测试TextField超链接内容自定义的热区交互方式
	 * @author Jave.Lin
	 * @date 2013-9-29
	 **/
	[SWF(width="1000", height="600")]
	public class RegexpTestingProject extends Sprite
	{
		private var tf:TextField;
		
		private var txt:String = "<a href='event:test'>测试</a>一下,这是带链接的文件信息,<a href='event:on link click event'>点击这里</a>,就可以超链接到<a href='event:http://www.baidu.com'>百度</a>";
		private var hrefRegexp:RegExp = /<a.*?href=[""'](?<url>.*?)[""'].*?>(?<name>.*?)<\/a>|<(.|\n)*?>/g;
		
		private var hotAreaSpArr:Array = [];
		
		public function RegexpTestingProject()
		{
			stage.color = 0x888888;
			stage.frameRate = 60;
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			
			tf = new TextField();
			tf.x = 100;
			tf.y = 100;
			tf.autoSize = TextFieldAutoSize.LEFT;
			
			var format:TextFormat = tf.defaultTextFormat;
			format.color = 0xffffff;
			
			tf.defaultTextFormat = format;
			tf.setTextFormat(format);
			
			tf.filters = [new GlowFilter(0, 1, 1.2, 1.2, 10)];
			
			tf.htmlText = txt;
			tf.mouseEnabled = false;
			
			addChild(tf);
			
			// 刷新超链接热区
			refreshLinkHotArea();
		}
		
		private function refreshLinkHotArea():void
		{
			hotAreaSpArr.length = 0;
			
			var result:Object;
			var hrefsIndx:int;
			while((result = hrefRegexp.exec(txt)) !== null)
			{
				const tag:String = String(result[0]);
				const tagLength:int = tag.length;
				const href:String = String(result[1]);
				const value:String = String(result[2]);
				trace("href = " + href + " value = " + value);
				
				const data:Object = {href:href, value:value};
				var sIdx:int = result.index - hrefsIndx;
				var eIdx:int = sIdx + value.length;
				var rect:Rectangle;
				for (var i:int = sIdx; i < eIdx; i++) 
				{
					rect = tf.getCharBoundaries(i);
					if(!rect) continue;
//					var key:String = toKey(rect);
//					trace("key = " + key);
					var hotArea:LinkHotArea = new LinkHotArea(rect, data);
					hotArea.x = tf.x + rect.x;
					hotArea.y = tf.y + rect.y;
					addChild(hotArea);
					hotAreaSpArr.push(hotArea);
				}
				hrefsIndx += tag.length - value.length;
			}
		}
		
		public static function toKey(rect:Rectangle):String
		{
			var keyArr:Array = [
				rect.x,
				rect.y,
				rect.width,
				rect.height
			];
			var key:String = keyArr.join("_");
			return key;
		}
	}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

class LinkHotArea extends Sprite
{
	public var data:Object;
	public var rect:Rectangle;
	
	public function LinkHotArea(rect:Rectangle, data:Object)
	{
		this.rect = rect;
		this.data = data;
		this.graphics.beginFill(0x00ff00, .5);//0);//.5);//这里换成.5,即可看到热区的位置,大小
		this.graphics.drawRect(0, 0, rect.width, rect.height);
		this.graphics.endFill();
		buttonMode = true;
		addEventListener(MouseEvent.CLICK, onClick);
	}
	
	private function onClick(e:MouseEvent):void
	{
		var rectKey:String = RegexpTestingProject.toKey(rect);
		var dataStr:String = "";
		for (var key:String in data)
		{
			dataStr += key + " = " + data[key] + ", ";
		}
		trace("LinkHotArea trigger : rectKey = " + rectKey + ", " + dataStr );
	}
}

运行效果图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值