`

在TWaver Flex中实现垂直文字布局

阅读更多

     最近有客户提到如何让Network上网元的标签垂直显示,首先想到的就是每个字符之间插入一个回车。这个用Network#labelFunction就能达到目的:

network.labelFunction = function (element:IElement):String {
	var name:String = element.name;
	if(element.getClient('vertical')) {
		var result:String = '';
		for(var i:int=0,n:int=name.length; i<n; i++) {
			result += name.charAt(i) + '\n';
		}
		result = result.substr(0, result.length-1);
		return result;
	} else {
		return name;
	}
};

    来段代码测试看看:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
				layout="absolute" width="100%" height="100%"
				creationComplete="init()" backgroundColor="#FFFFFF" >
	<mx:Script>
		<![CDATA[
			import twaver.Consts;
			import twaver.ElementBox;
			import twaver.IElement;
			import twaver.Node;
			import twaver.Styles;

			private var box:ElementBox = new ElementBox();

			private function init():void {
				network.labelFunction = function (element:IElement):String {
					var name:String = element.name;
					if(element.getClient('vertical')) {
						var result:String = '';
						for(var i:int=0,n:int=name.length; i<n; i++) {
							result += name.charAt(i) + '\n';
						}
						result = result.substr(0, result.length-1);
						return result;
					} else {
						return name;
					}
				};

				var node1:Node = new Node();
				node1.location = new Point(100, 100);
				node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
				node1.setClient('vertical', true);
				node1.name = '竖向文字Vertical Text';
				box.add(node1);

				network.elementBox = box;
			}
		]]>
	</mx:Script>
	<twaver:Network id="network" width="100%" height="100%" />
</mx:Application>

 

      运行效果如下:


     上面的方法很容易让文字垂直显示,但效果不是很理想,中英文混合时,英文也被一个字母一个字母地分开了。有没有更好的方案?答案是肯定的,借助于Flex的Flash Text Engine (FTE)和Text Layout Framework (TLF),可以很容易的让文字从上到下显示。
      先来看看一个小例子,设置TextLayoutFormat的blockProgression属性为BlockProgression.RL即可:

package {
	import flash.display.Sprite;

	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.conversion.TextConverter;
	import flashx.textLayout.elements.TextFlow;
	import flashx.textLayout.formats.BlockProgression;
	import flashx.textLayout.formats.TextLayoutFormat;

	public class StaticHelloWorld extends Sprite {
		public function StaticHelloWorld() {
			var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
			textLayoutFormat.lineHeight = 30;
			textLayoutFormat.locale = 'zh';
			textLayoutFormat.blockProgression = BlockProgression.RL;

			var text:String = "测试竖向文字,再看看English如何?";
			var textFlow:TextFlow = TextConverter.importToFlow(text, TextConverter.PLAIN_TEXT_FORMAT);
			textFlow.hostFormat = textLayoutFormat;
			textFlow.flowComposer.addController(new ContainerController(this, 25, 200));
			textFlow.flowComposer.updateAllControllers();
		}
	}
}

 

运行效果如下:


       的确这样效果就好多了,英文不会被一个字母一个字母地打断,然后我们自定义一个Attachment:

package {
	import flash.display.Sprite;
	import flash.text.engine.FontPosture;
	import flash.text.engine.FontWeight;

	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.elements.ParagraphElement;
	import flashx.textLayout.elements.SpanElement;
	import flashx.textLayout.elements.TextFlow;
	import flashx.textLayout.formats.BlockProgression;
	import flashx.textLayout.formats.TextDecoration;
	import flashx.textLayout.formats.TextLayoutFormat;

	import twaver.Styles;
	import twaver.network.ui.BasicAttachment;
	import twaver.network.ui.ElementUI;

	public class FTELabelAttachment extends BasicAttachment {

		private var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();

		public function FTELabelAttachment(elementUI:ElementUI, showInAttachmentCanvas:Boolean=false) {
			super(elementUI, showInAttachmentCanvas);

			this.textLayoutFormat.locale = 'zh';
			this.textLayoutFormat.blockProgression = BlockProgression.RL;
		}

		override public function updateProperties():void {
			super.updateProperties();

			this.textLayoutFormat.fontFamily = element.getStyle(Styles.LABEL_FONT);
			this.textLayoutFormat.color = element.getStyle(Styles.LABEL_COLOR);
			this.textLayoutFormat.fontSize = element.getStyle(Styles.LABEL_SIZE);
			this.textLayoutFormat.fontStyle = element.getStyle(Styles.LABEL_ITALIC) ? FontPosture.ITALIC : FontPosture.NORMAL;
			this.textLayoutFormat.fontWeight = element.getStyle(Styles.LABEL_BOLD) ? FontWeight.BOLD : FontWeight.NORMAL;
			this.textLayoutFormat.textDecoration = element.getStyle(Styles.LABEL_UNDERLINE ? TextDecoration.UNDERLINE : TextDecoration.NONE);

			var textFlow:TextFlow = new TextFlow();
			textFlow.hostFormat = this.textLayoutFormat;
			var p:ParagraphElement = new ParagraphElement();
			textFlow.addChild(p);
			var span:SpanElement = new SpanElement();
			span.text = network.getLabel(element);
			p.addChild(span);

			var fteLabel:Sprite = new Sprite();
			this.content = fteLabel;
			var containerController:ContainerController = new ContainerController(fteLabel, this.textLayoutFormat.fontSize, 1000);
			textFlow.flowComposer.addController(containerController);
			textFlow.flowComposer.updateAllControllers();
		}

		override public function get position():String {
			return element.getStyle(Styles.LABEL_POSITION);
		}

		override public function get xOffset():Number {
			return element.getStyle(Styles.LABEL_XOFFSET);
		}

		override public function get yOffset():Number {
			return element.getStyle(Styles.LABEL_YOFFSET);
		}

		override public function get padding():Number {
			return element.getStyle(Styles.LABEL_PADDING);
		}

		override public function get paddingLeft():Number {
			return element.getStyle(Styles.LABEL_PADDING_LEFT);
		}

		override public function get paddingRight():Number {
			return element.getStyle(Styles.LABEL_PADDING_RIGHT);
		}

		override public function get paddingTop():Number {
			return element.getStyle(Styles.LABEL_PADDING_TOP);
		}

		override public function get paddingBottom():Number {
			return element.getStyle(Styles.LABEL_PADDING_BOTTOM);
		}

		override public function get cornerRadius():Number {
			return element.getStyle(Styles.LABEL_CORNER_RADIUS);
		}

		override public function get pointerLength():Number {
			return element.getStyle(Styles.LABEL_POINTER_LENGTH);
		}

		override public function get pointerWidth():Number {
			return element.getStyle(Styles.LABEL_POINTER_WIDTH);
		}

		override public function get direction():String {
			return element.getStyle(Styles.LABEL_DIRECTION);
		}

		override public function get fill():Boolean {
			return element.getStyle(Styles.LABEL_FILL);
		}

		override public function get fillColor():Number {
			return element.getStyle(Styles.LABEL_FILL_COLOR);
		}

		override public function get fillAlpha():Number {
			return element.getStyle(Styles.LABEL_FILL_ALPHA);
		}

		override public function get gradient():String {
			return element.getStyle(Styles.LABEL_GRADIENT);
		}

		override public function get gradientColor():Number {
			return element.getStyle(Styles.LABEL_GRADIENT_COLOR);
		}

		override public function get gradientAlpha():Number {
			return element.getStyle(Styles.LABEL_GRADIENT_ALPHA);
		}

		override public function get contentXScale():Number {
			return element.getStyle(Styles.LABEL_CONTENT_XSCALE);
		}

		override public function get contentYScale():Number {
			return element.getStyle(Styles.LABEL_CONTENT_YSCALE);
		}

		override public function get outlineWidth():Number {
			return element.getStyle(Styles.LABEL_OUTLINE_WIDTH);
		}

		override public function get outlineColor():Number {
			return element.getStyle(Styles.LABEL_OUTLINE_COLOR);
		}

		override public function get outlineAlpha():Number {
			return element.getStyle(Styles.LABEL_OUTLINE_ALPHA);
		}
	}
}

 

      再自定义Node和NodeUI,使用这个Attachment代替TWaver自带的LabelAttachment:

自定义Node:

package {
	import twaver.Node;

	public class FTELabelNode extends Node {
		public function FTELabelNode(id:Object=null) {
			super(id);
		}

		public override function get elementUIClass():Class {
			return FTELabelNodeUI;
		}
	}
}

     自定义NodeUI:

package {
	import twaver.Node;
	import twaver.network.Network;
	import twaver.network.ui.NodeUI;

	public class FTELabelNodeUI extends NodeUI {

		private var _labelAttachment:FTELabelAttachment = null;

		public function FTELabelNodeUI(network:Network, node:Node) {
			super(network, node);
		}

		override protected function checkLabelAttachment():void{
			var label:String = this.network.getLabel(element);
			if(label != null && label != ""){
				if(this._labelAttachment == null){
					this._labelAttachment = new FTELabelAttachment(this, false);
					this.addAttachment(this._labelAttachment);
				}
			}else{
				if(this._labelAttachment != null){
					this.removeAttachment(this._labelAttachment);
					this._labelAttachment = null;
				}
			}
		}
	}
}

 

最后,写个例子看看效果:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex"
				layout="absolute" width="100%" height="100%"
				creationComplete="init()" backgroundColor="#FFFFFF" >
	<mx:Script>
		<![CDATA[
			import twaver.Consts;
			import twaver.ElementBox;
			import twaver.IElement;
			import twaver.Node;
			import twaver.Styles;

			private var box:ElementBox = new ElementBox();

			private function init():void {
				network.labelFunction = function (element:IElement):String {
					var name:String = element.name;
					if(element.getClient('vertical')) {
						var result:String = '';
						for(var i:int=0,n:int=name.length; i<n; i++) {
							result += name.charAt(i) + '\n';
						}
						result = result.substr(0, result.length-1);
						return result;
					} else {
						return name;
					}
				};

				var node1:Node = new Node();
				node1.location = new Point(100, 100);
				node1.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
				node1.setClient('vertical', true);
				node1.name = '竖向文字Vertical Text';
				box.add(node1);

				var node2:Node = new FTELabelNode();
				node2.location = new Point(300, 100);
				node2.setStyle(Styles.LABEL_POSITION, Consts.POSITION_LEFT_LEFT);
				node2.name = '竖向文字Vertical Text';
				box.add(node2);

				network.elementBox = box;
			}

			private function changeFontSize():void {
				box.forEach(function (element:IElement):void {
					element.setStyle(Styles.LABEL_SIZE, element.getStyle(Styles.LABEL_SIZE) + 2);
				});
			}
		]]>
	</mx:Script>
	<mx:VBox width="100%" height="100%">
		<mx:HBox width="100%" height="20">
			<mx:Button label="Change Font Size" click="changeFontSize()"/>
		</mx:HBox>
		<twaver:Network id="network" width="100%" height="100%" />
	</mx:VBox>
</mx:Application>

 

恩,这就是我想要的效果:

更多关于FTE和TLF的信息,请参考Adobe官方文档:
TextLayoutFormat
TextFlow
Textlayout
本文完整代码见附件:FTELabelAttachment

分享到:
评论

相关推荐

    twaver flex 中文用户使用手册

    《Twaver Flex中文用户使用手册》是一份专为使用Twaver Flex产品的用户准备的详尽指南,旨在帮助用户深入理解和高效应用这款强大的图形化建模工具。Twaver Flex是一款基于Adobe Flex技术的可视化开发框架,它提供了...

    flex Twaver组件使用

    数据管理容器,尤其是`twaver.DataBox`,在TWaver Flex中扮演着Model的角色。它可以驱动多个视图,如`twaver.controls.Tree`、`twaver.controls.Table`和`twaver.network.Network`。当`DataBox`中的数据发生变化时,...

    Twaver Flex技术

    6. **源码与工具**:标签中的“源码”意味着学习和使用Twaver Flex可能涉及到查看和修改源代码,以便深入理解和定制。而“工具”可能指的是Adobe Flex Builder或其他相关开发工具,这些工具可以帮助开发者更有效地...

    twaver flex developer guid

    - **约定俗成**:在TWaver Flex开发过程中,遵循一定的命名规则和代码风格是十分必要的。这些规则不仅有助于提升代码的可读性和可维护性,还能帮助开发者更好地理解和协作。 - **命名规范**:例如,类名通常采用...

    TWaver_Flex中文帮助文档

    TWaver Flex中的告警功能是该组件的一个重要组成部分,文档中讲解了告警的使用,包括告警级别、状态与统计、以及告警的呈现方式。 ### 版权声明和使用许可 文档中也明确了版权信息和版权声明,强调了文档是...

    TWaver Flex网元任意位置添加icon

    在Flex中,我们通常使用ActionScript 3.0来编写代码。TWaver库提供了丰富的API和类,用于创建、操作和定制图表组件。要实现“任意位置添加icon”,你需要以下步骤: 1. **创建TWaver图**:首先,你需要创建一个...

    Twaver Flex Demo

    Twaver Flex Demo SWF格式

    twaver-flex-3.6.5 官方demo

    在压缩包文件"twaver-flex-3.6.5"中,用户可以找到关于如何在Flex项目中集成和使用Twaver库的示例代码、资源文件以及可能的文档。这通常包括: 1. **源代码**:官方Demo的AS3源码,开发者可以通过阅读和修改这些...

    twaver for flex 开发手册

    这些控件允许开发者在 Flex 应用程序中轻松实现复杂的网络拓扑图、表格、树形结构等图形界面,从而极大地提高了应用程序的可读性和可用性。 #### 二、TWaverFlex 快速入门 **TWaverFlex 快速上手**:为了帮助初学...

    TWaver 3D Flex 3D 实例 例子

    标题中的“TWaver 3D Flex 3D 实例 例子”表明这是一份关于TWaver 3D技术在Flex 3D环境下的应用实例。TWaver是一款强大的数据可视化工具,它提供了丰富的图表类型和交互功能,而Flex 3D是Adobe Flex框架的一个扩展,...

    Flex与Twaver资料

    在Flex中,TWaver作为一个扩展库,提供了强大的数据模型和视图组件。TWaverFlex的核心数据元素是`twaver.IData`,这是一个接口,代表了数据的基本单位。`twaver.Data`是`twaver.IData`的实现类,包含了如id、name、...

    twaverflex 3D开发文档

    因此,开发者需要在安装有Flex Builder 4.6的环境中进行TWaver3D的开发工作。 ### 3. 第一个3D应用程序的创建 文档介绍了如何构建第一个3D应用程序,这包括了3D应用的基本概念,如事件驱动、元素的组织、3D样式、...

    Flex Twaver 入门指南中文版

    **前期准备**:在开始使用 Flex Twaver 之前,需要确保已经安装了 Java 开发环境,并了解基本的 Java 编程知识。此外,还需要获取 Flex Twaver 的安装包并按照指引完成安装。 **TWAVER 组件概览**:Flex Twaver ...

    基于TWaver实现的3D机房Demo

    为了更好地理解TWaver在3D机房管理中的应用,可以查看"demo"文件夹中的内容。这个示例可能包含HTML、CSS和JavaScript文件,展示了如何将TWaver集成到网页中并创建3D机房场景。通过阅读和分析这些代码,开发者可以...

    TWaver.swc 3.3.1

    TWaver-flex的库TWaver.swc

    twaver web实例源码

    【描述】"twaver web结合extjs源码学习资料"意味着这个压缩包包含了一组实际项目的源代码,用于展示如何在Web环境中整合Twaver和ExtJS。通过学习这些源码,开发者可以深入了解这两个库如何协同工作,创建交互式和...

Global site tag (gtag.js) - Google Analytics