在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>

  

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; }

 运行效果如下:

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

     上面的方法很容易让文字垂直显示,但效果不是很理想,中英文混合时,英文也被一个字母一个字母地分开了。有没有更好的方案?答案是肯定的,借助于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();

		}

	}

}

  

 

运行效果如下:

在TWaver Flex中实现垂直文字布局      的确这样效果就好多了,英文不会被一个字母一个字母地打断,然后我们自定义一个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>

  

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); }); }

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

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

更多关于FTE和TLF的信息,请参考Adobe官方文档:

TextLayoutFormat

TextFlow

Textlayout

本文完整代码见附件:FTELabelAttachment

你可能感兴趣的:(TWaver)