LayaAir2.0引擎之字幕类
在实际的项目中可能有一些特殊的文字效果,比如颜色混合搭配,或者横排布局或竖排布局,或者根据布局的不同方式展现不同的打字机效果。在因为项目开发需要扩展了一个组件,可以满足一些简单的文字复制布局效果,有需要的同学可以下载了玩玩,目前字幕类是基于LayaAir2.0引擎扩展的,后面在提供基于LayaAir1.0引擎的版本。
字母类支持的功能描述:
1、支持文本多种颜色混合使用,
2、横排排版(竖排排版感觉加个下划线比较怪异,暂时没支持)支持下划线使用,无需引用htmldivelement组件;
3、支持横排全部排版,包括左对齐、右对齐、居中对齐
4、支持竖排全部排版,包括左对齐、右对齐、居中对齐;
5、支持竖排左对齐第一排显示,后面每排追加,类似流行诗的效果;
6、支持竖排右对齐右侧第一排显示,后面每排追加,类似流行诗效果;
7、支持横排或竖排打字机效果;
8、支持淡入、淡出效果;
9、支持设置字间距和行间距;
10、支持横排或竖排自动排版(此效果仅限单色内容);
效果截图:
1、下划线:
2、竖排左对齐:
3、竖排右对齐:
4、打字机横排左对齐:
5、打字机竖排左对齐:
6、打字机竖排右对齐:
7、淡入淡出效果:
代码使用说明:
这里解释下上面的文字内容结构,这里需要好好理解下,在上面的文字里存在 "=11.0pt|#ffcc00|25|1|0|1"
几个接口使用说明:
1、打字机接口,支持设置打字机的速度:
2、淡入接口,支持设置淡入的速度:
3、淡出接口,支持设置淡出的速度:
附件是实现类,目前是基于AS3的,有其他语言的同学,可以自己翻译下,翻译代码这个应该对每个同学来说肯定是so easy!
使用过程中遇到问题的同学可以留言
字母类支持的功能描述:
1、支持文本多种颜色混合使用,
2、横排排版(竖排排版感觉加个下划线比较怪异,暂时没支持)支持下划线使用,无需引用htmldivelement组件;
3、支持横排全部排版,包括左对齐、右对齐、居中对齐
4、支持竖排全部排版,包括左对齐、右对齐、居中对齐;
5、支持竖排左对齐第一排显示,后面每排追加,类似流行诗的效果;
6、支持竖排右对齐右侧第一排显示,后面每排追加,类似流行诗效果;
7、支持横排或竖排打字机效果;
8、支持淡入、淡出效果;
9、支持设置字间距和行间距;
10、支持横排或竖排自动排版(此效果仅限单色内容);
效果截图:
1、下划线:
2、竖排左对齐:
3、竖排右对齐:
4、打字机横排左对齐:
5、打字机竖排左对齐:
6、打字机竖排右对齐:
7、淡入淡出效果:
代码使用说明:
var complexStyleText:ComplexStyleText = new ComplexStyleText();
Laya.stage.addChild(complexStyleText);
complexStyleText.leading = 0;//设置行间距
complexStyleText.setSize(500,500);//设置字幕类的尺寸
complexStyleText.wordSpace = 5;//设置文字字间距
complexStyleText.valign = ComplexStyleText.VALIGN_TOP;//垂直居上
complexStyleText.align = ComplexStyleText.VERTICAL_LEFT;//水平居左
complexStyleText.text ="江城子,十年生死两茫茫,不思量,自难忘。千里孤坟,无处话凄凉,纵使相逢应不识,尘满面,鬓如霜。|#ffcc00|25|1|0|1";
这里解释下上面的文字内容结构,这里需要好好理解下,在上面的文字里存在 "=11.0pt|#ffcc00|25|1|0|1"
#ffcc00:代表当前文字设置的颜色;
25:代表文字设置的字号大小;
1:代表是否带下划线,1显示下划线;0隐藏
0:是否主动折行;1折行;0隐藏
1:代表是否显示;1显示;0隐藏
如果你要设置多种颜色的字体,需要重复上面的内容,例如:
"江城子|#ffcc00|25|1|0|1|_|十年生死两茫茫,|#ff9900|25|0|1|1|_|不思量,自难忘。|#ffcc00|25|1|1|1|_|千里孤坟,无处话凄凉|#00cc00|25|0|1|1|_|纵使相逢应不识,|#ff9900|25|1|1|1|_|尘满面,鬓如霜。|#ffcc00|25|0|1|1"
几个接口使用说明:
1、打字机接口,支持设置打字机的速度:
complexStyleText.typewriter("江城子|#ffcc00|25|1|0|1|_|十年生死两茫茫,|#ff9900|25|0|1|1|_|不思量,自难忘。|#ffcc00|25|1|1|1|_|千里孤坟,无处话凄凉|#00cc00|25|0|1|1|_|纵使相逢应不识,|#ff9900|25|1|1|1|_|尘满面,鬓如霜。|#ffcc00|25|0|1|1",100);
2、淡入接口,支持设置淡入的速度:
complexStyleText.fadeIn("江城子|#ffcc00|25|1|0|1|_|十年生死两茫茫,|#ff9900|25|0|1|1|_|不思量,自难忘。|#ffcc00|25|1|1|1|_|千里孤坟,无处话凄凉|#00cc00|25|0|1|1|_|纵使相逢应不识,|#ff9900|25|1|1|1|_|尘满面,鬓如霜。|#ffcc00|25|0|1|1",100);
3、淡出接口,支持设置淡出的速度:
complexStyleText.fadeOut("江城子|#ffcc00|25|1|0|1|_|十年生死两茫茫,|#ff9900|25|0|1|1|_|不思量,自难忘。|#ffcc00|25|1|1|1|_|千里孤坟,无处话凄凉|#00cc00|25|0|1|1|_|纵使相逢应不识,|#ff9900|25|1|1|1|_|尘满面,鬓如霜。|#ffcc00|25|0|1|1",100); //淡出
附件是实现类,目前是基于AS3的,有其他语言的同学,可以自己翻译下,翻译代码这个应该对每个同学来说肯定是so easy!
使用过程中遇到问题的同学可以留言
5 个评论
请问下 描边好像没效果
嗯,借用楼主的想法,然后自己改成ts版本,并且进行封装和改动一下。
1.去掉设置间距,宽高,换行,文本,字体,对齐等方式时调用渲染的方法,增加一个onShowText方法直接渲染,实现上面所设置参数时的效果(说直接白点,就是集合在该方法中)
2.修改一下楼主文本设置格式(在最终渲染时需要进行解析出来,那我就直接点,直接传对应数据进行就行了,减少解析这一步)
3.删掉一些不适用的局部变量。都不使用,那就删了吧(做拓展时,自己根据自己需要定义得了)
4.使用: var txtVo:TextVo = new TextVo();
txtVo.posArr =[20,20];
txtVo.textSize =[300,300];
txtVo.leading = 5;
txtVo.lableVo = [];
txtVo.align = ComplexStyleText.VERTICAL_LEFT;
txtVo.valign = ComplexStyleText.VALIGN_TOP;//垂直居上
txtVo.lableVo.push(new FontInfo(["江城子","#ffcc00","25","1","0","1"]));
txtVo.lableVo.push(new FontInfo(["十年生死两茫茫,","#ff9900","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["不思量,自难忘。","#ffcc00","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["千里孤坟,无处话凄凉","#00cc00","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["纵使相逢应不识,","#ff9900","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["尘满面,鬓如霜。","#ffcc00","25","0","1","1"]));
var complexStyleText:ComplexStyleText = TextUtil.ComplexText(txtVo);
Laya.stage.addChild(complexStyleText);
如果其他人觉得lableVo的数据不方便,可以直接改成自己喜欢的格式。反正在FontInfo那边本身就有说明,是喜欢给数组格式过去还是字符串或其他的。都看个人情况吧
嗯,附一下代码
1.去掉设置间距,宽高,换行,文本,字体,对齐等方式时调用渲染的方法,增加一个onShowText方法直接渲染,实现上面所设置参数时的效果(说直接白点,就是集合在该方法中)
2.修改一下楼主文本设置格式(在最终渲染时需要进行解析出来,那我就直接点,直接传对应数据进行就行了,减少解析这一步)
3.删掉一些不适用的局部变量。都不使用,那就删了吧(做拓展时,自己根据自己需要定义得了)
4.使用: var txtVo:TextVo = new TextVo();
txtVo.posArr =[20,20];
txtVo.textSize =[300,300];
txtVo.leading = 5;
txtVo.lableVo = [];
txtVo.align = ComplexStyleText.VERTICAL_LEFT;
txtVo.valign = ComplexStyleText.VALIGN_TOP;//垂直居上
txtVo.lableVo.push(new FontInfo(["江城子","#ffcc00","25","1","0","1"]));
txtVo.lableVo.push(new FontInfo(["十年生死两茫茫,","#ff9900","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["不思量,自难忘。","#ffcc00","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["千里孤坟,无处话凄凉","#00cc00","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["纵使相逢应不识,","#ff9900","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["尘满面,鬓如霜。","#ffcc00","25","0","1","1"]));
var complexStyleText:ComplexStyleText = TextUtil.ComplexText(txtVo);
Laya.stage.addChild(complexStyleText);
如果其他人觉得lableVo的数据不方便,可以直接改成自己喜欢的格式。反正在FontInfo那边本身就有说明,是喜欢给数组格式过去还是字符串或其他的。都看个人情况吧
嗯,附一下代码
嗯,借用楼主的想法,然后自己改成ts版本,并且进行封装和改动一下。
1.去掉设置间距,宽高,换行,文本,字体,对齐等方式时调用渲染的方法,增加一个onShowText方法直接渲染,实现上面所设置参数时的效果(说直接白点,就是集合在该方法中)
2.修改一下楼主文本设置格式(在最终渲染时需要进行解析出来,那我就直接点,直接传对应数据进行就行了,减少解析这一步)
3.删掉一些不适用的局部变量。都不使用,那就删了吧(做拓展时,自己根据自己需要定义得了)
4.使用: var txtVo:TextVo = new TextVo();
txtVo.posArr =[20,20];
txtVo.textSize =[300,300];
txtVo.leading = 5;
txtVo.lableVo = [];
txtVo.align = ComplexStyleText.VERTICAL_LEFT;
txtVo.valign = ComplexStyleText.VALIGN_TOP;//垂直居上
txtVo.lableVo.push(new FontInfo(["江城子","#ffcc00","25","1","0","1"]));
txtVo.lableVo.push(new FontInfo(["十年生死两茫茫,","#ff9900","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["不思量,自难忘。","#ffcc00","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["千里孤坟,无处话凄凉","#00cc00","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["纵使相逢应不识,","#ff9900","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["尘满面,鬓如霜。","#ffcc00","25","0","1","1"]));
var complexStyleText:ComplexStyleText = TextUtil.ComplexText(txtVo);
Laya.stage.addChild(complexStyleText);
如果其他人觉得lableVo的数据不方便,可以直接改成自己喜欢的格式。反正在FontInfo那边本身就有说明,是喜欢给数组格式过去还是字符串或其他的。都看个人情况吧
嗯,附一下代码
1.去掉设置间距,宽高,换行,文本,字体,对齐等方式时调用渲染的方法,增加一个onShowText方法直接渲染,实现上面所设置参数时的效果(说直接白点,就是集合在该方法中)
2.修改一下楼主文本设置格式(在最终渲染时需要进行解析出来,那我就直接点,直接传对应数据进行就行了,减少解析这一步)
3.删掉一些不适用的局部变量。都不使用,那就删了吧(做拓展时,自己根据自己需要定义得了)
4.使用: var txtVo:TextVo = new TextVo();
txtVo.posArr =[20,20];
txtVo.textSize =[300,300];
txtVo.leading = 5;
txtVo.lableVo = [];
txtVo.align = ComplexStyleText.VERTICAL_LEFT;
txtVo.valign = ComplexStyleText.VALIGN_TOP;//垂直居上
txtVo.lableVo.push(new FontInfo(["江城子","#ffcc00","25","1","0","1"]));
txtVo.lableVo.push(new FontInfo(["十年生死两茫茫,","#ff9900","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["不思量,自难忘。","#ffcc00","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["千里孤坟,无处话凄凉","#00cc00","25","0","1","1"]));
txtVo.lableVo.push(new FontInfo(["纵使相逢应不识,","#ff9900","25","1","1","1"]));
txtVo.lableVo.push(new FontInfo(["尘满面,鬓如霜。","#ffcc00","25","0","1","1"]));
var complexStyleText:ComplexStyleText = TextUtil.ComplexText(txtVo);
Laya.stage.addChild(complexStyleText);
如果其他人觉得lableVo的数据不方便,可以直接改成自己喜欢的格式。反正在FontInfo那边本身就有说明,是喜欢给数组格式过去还是字符串或其他的。都看个人情况吧
嗯,附一下代码
export class ComplexStyleText extends Laya.Box{
/**竖向左侧对齐**/
public static readonly VERTICAL_LEFT:string = "vertical_left";
/**竖向居中对齐**/
public static readonly VERTICAL_CENTER:string = "vertical_center";
/**竖向居右对齐**/
public static readonly VERTICAL_RIGHT:string = "vertical_right";
/**水平居左对齐方式。 */
public static readonly ALIGN_LEFT:string = "left";
/**水平居中对齐方式。 */
public static readonly ALIGN_CENTER:string = "center";
/**水平居右对齐方式。 */
public static readonly ALIGN_RIGHT:string = "right";
/**垂直居中对齐方式。 */
public static readonly VALIGN_TOP:string = "top";
/**垂直居中对齐方式。 */
public static readonly VALIGN_MIDDLE:string = "middle";
/**垂直居底部对齐方式。 */
public static readonly VALIGN_BOTTOM:string = "bottom";
/**文字容器**/
private _textBox:Laya.Box;
/**文字**/
private _textfiled:Laya.Label;
/**宽高信息[宽,高]**/
private _fontWHs:Array<number> = [100,100];
/**绘制数据**/
private _textDrawDatas:Array<any>;
/**绘制数据的最大宽高信息 [宽]**/
private _textDrawWidths:Array<any> = [];
/**绘制数据的最大高度信息[高]**/
private _textDrawHeights:Array<any> = [];
/**文本最大高度**/
private _textMaxHeight:number = 0;
/**是否是打字机效果**/
private _isPrinter:Boolean = false;
/**渲染文本对象信息**/
private _textVo:TextVo;
constructor()
{
super();
}
/**
* 设置宽高
* @param width
* @param height
*
*/
public setSize(width:number,height:number):void
{
if(this._fontWHs[0] != width || this._fontWHs[1] != height)
{
this._fontWHs[0] = width;
this._fontWHs[1] = height;
}
}
/**
* 直接渲染
* @param textVo
*/
public onShowText(textVo:TextVo):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this._isPrinter = false;
this.renderText();
}
}
/**
* 打字机效果
* @param text
* @param speed,默认100毫秒
*/
public typewriter(textVo:TextVo,speed:number = 100):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this._isPrinter = true;
this.renderText();
this._textfiled.graphics.clear();
var ziIndex:number = 0;//当前播放的字索引
Laya.timer.loop(speed,this,onPlayDaZi);
function onPlayDaZi():void
{
if(ziIndex >= this._printerTextWords.length)
{
Laya.timer.clear(this,onPlayDaZi);
return;
}
var printTextArr:Array<any> = this._printerTextWords[ziIndex];
this._textfiled.graphics.fillWords(printTextArr[0],printTextArr[1],printTextArr[2],printTextArr[3],printTextArr[4]);
ziIndex++;
}
}
}
/**
* 淡入效果
* @param text 操作的文字内容
* @param 间隔时间 默认 30毫秒
*/
public fadeIn(textVo:TextVo,speed:number = 30):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this.renderText(0);
var num:number = 0;
Laya.timer.loop(speed,this,onFadeIn);
function onFadeIn():void
{
num++;
this._textfiled.alpha = num/10;
console.info("_textfiled.alpha:" + this._textfiled.alpha);
if(num>=10)
Laya.timer.clear(this,onFadeIn);
}
}
}
/**
* 淡出效果
* @param text
* @param speed
*/
public fadeOut(textVo:TextVo,speed:number = 30):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this.renderText(1);
var num:number = 10;
Laya.timer.loop(speed,this,onFadeOut);
function onFadeOut():void
{
num--;
this._textfiled.alpha = num/10;
console.info("_textfiled.alpha:" + this._textfiled.alpha);
if(num<=0)
Laya.timer.clear(this,onFadeOut);
}
}
}
/**
* 渲染文字
* @param alpha
* @returns
*/
private renderText(alpha:number = 1):void
{
if(!this._textVo.lableVo||this._textVo.lableVo.length==0)
return;
if(!this._textBox)
{
this._textBox = new Laya.Box();
this.addChild(this._textBox);
this._textBox.size(this._fontWHs[0],this._fontWHs[1]);
this._textBox.graphics.drawRect(0,0,this._fontWHs[0],this._fontWHs[1],"#000000");
}
//创建文本
if(this._textfiled)
{
this._textfiled.graphics.clear();
}else
{
this._textfiled = new Laya.Label();
this._textBox.addChild(this._textfiled);
}
this._textfiled.alpha = alpha;//设置透明度
//记录绘制的文字数据
this._textDrawDatas = [];
var tempTextX:number =0;//文本临时X轴信息
var tempTextY:number = 0;//文本临时Y轴信息
var lineWrapInt:number = 0;//折行次数
for(var i:number = 0,sz:number =this._textVo.lableVo.length;i<sz;i++ )
{
//[文字内容|文字颜色|文字字号大小|文字是否显示下划线|文字是否显示]
var fontInfo:FontInfo = this._textVo.lableVo[i];
var words:Array<Laya.HTMLChar> = this.getWords(fontInfo.fontSize,fontInfo.fontText);
var temTextArr:Array<any> = this.getDanTextMaxWidth((words));//当前文本的总宽度和单个文字的宽度信息
var textWidth:number = temTextArr[0];//当前文本的最大宽度值
var currentTextWidth:number = temTextArr[1];//当前文字的宽度信息
var textHeight2:number = this.getDanTextMaxHeight((words));//用于竖排高度排版
if(!fontInfo.isVisible)
continue;//隐藏就忽略,继续下个文字处理
if(!fontInfo.isLineWrap)
{
this.onDrawTextLine(this._textfiled,words,tempTextX,tempTextY,fontInfo);
if(this._textVo.lableVo.length == 1 && this._textVo.align.indexOf("vertical")== -1)
{
this._textMaxHeight = this._textAutoWarpInt * (fontInfo.fontSize + this._textVo.leading);//横排
}
}
if(fontInfo.isLineWrap)
{
//折行
lineWrapInt +=1;
if(this._textVo.align.indexOf("vertical")== -1)
{
//横向折行,X轴坐标清0
tempTextY = tempTextY + fontInfo.fontSize + this._textVo.leading;
this.onDrawTextLine(this._textfiled,(words as Array<any>),0,tempTextY,fontInfo);
tempTextX = textWidth;
//记录文本最大的高度,用于布局跑排版
this._textMaxHeight = tempTextY + fontInfo.fontSize + this._textVo.leading+0;// 5 是差值,左下的时候下划线看不到,临时减去10的差值,显示下划线,后面差下这个问题
}else
{
//竖向折行,Y轴坐标清0
if(this._textVo.align == ComplexStyleText.VERTICAL_RIGHT)
{
tempTextX = tempTextX - currentTextWidth - this._textVo.wordSpace;
}else
{
tempTextX = tempTextX + currentTextWidth + this._textVo.wordSpace;
}
this.onDrawTextLine(this._textfiled,(words as Array<any>),tempTextX,0,fontInfo);
//记录文本最大的高度,用于布局跑排版
this._textMaxHeight = tempTextY + this._textVo.leading + 10;// 10 是差值,左下的时候下划线看不到,临时减去10的差值,显示下划线,后面差下这个问题
tempTextY = textHeight2;//记录折行时文本的高度
}
}else
{
if(this._textVo.align.indexOf("vertical")!= -1)
{
tempTextY += textHeight2;
if(fontInfo.isLineWrap)
tempTextX += textWidth;//竖向排版,有折行的情况下才能改变X轴位置
}else
{
tempTextX += textWidth;
}
}
//初始化文本的宽度信息
if(!this._textDrawWidths[lineWrapInt])
{
this._textDrawWidths[lineWrapInt] = 0;
}
//竖排计算高度
if(this._textVo.align.indexOf("vertical")!= -1)
{
if(!this._textDrawHeights[lineWrapInt])
{
this._textDrawHeights[lineWrapInt] = 0;
}
this._textDrawHeights[lineWrapInt] += textHeight2;
if(this._textVo.lableVo.length == 1)
{
//竖排根据高度自动折行,需要重新算宽度,用于对齐排版
currentTextWidth = this._textAutoWarpInt * (currentTextWidth +this._textVo.wordSpace);
}
//最大宽度计算
if(fontInfo.isLineWrap)
{
this._textDrawWidths[lineWrapInt] += currentTextWidth;
}
if(this._textDrawWidths[lineWrapInt]==0)
this._textDrawWidths[lineWrapInt] = currentTextWidth;//按上次记录的信息排版
}else
{
this._textDrawWidths[lineWrapInt] += textWidth;
}
}
//绘制文字数据
this.onRepaint();
}
private _textIndex:number = 0;
/**
* 绘制文字数据
*/
private onRepaint():void
{
this._textIndex = 0;
this._printerTextWords = [];
for(var i:number = 0,sz:number = this._textDrawDatas.length;i<sz;i++)
{
var textData:Array<any> = this._textDrawDatas[i];//数据里包括了文字数据和下划线数据
var drawTextData:Array<any> = textData[0];//绘制文字的数据
var drawTextLineData:Array<any> = textData[1];//文字下划线数据
var textStartX:number = drawTextData[1];//绘制文本的X轴起始点
var textStartY:number = drawTextData[2];//绘制文本的Y轴起始点
var lineStartX:number = 0;//绘制下划线的X轴起始点
var lineStartY:number = 0;//绘制下划线的Y轴起始点
var isWordWarp:Boolean = drawTextData[5];//是否折行
if(this._textVo.align == ComplexStyleText.ALIGN_LEFT || this._textVo.align == ComplexStyleText.VERTICAL_LEFT)
{
//横排居左
this.paintLeft(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY,isWordWarp);
}else if(this._textVo.align == ComplexStyleText.ALIGN_RIGHT || this._textVo.align == ComplexStyleText.VERTICAL_RIGHT)
{
//横排居右
this.paintRight(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY,isWordWarp);
}else if(this._textVo.align == ComplexStyleText.ALIGN_CENTER || this._textVo.align == ComplexStyleText.VERTICAL_CENTER)
{
//横排居中
this.paintMiddle(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY,isWordWarp);
}
}
}
/**
* 居中文字排版
* @param textData
*/
private paintMiddle(drawTextData:Array<any>,drawTextLineData:Array<any>,textStartX:number,textStartY:number,lineStartX:number,lineStartY:number,isWordWarp:Boolean = false):void
{
if(isWordWarp)
this._textIndex++;
var textMaxHeight:number = this._textVo.align.indexOf("vertical") == -1 ? this._textMaxHeight : this.getCurTextMaxheight;
if(this._textVo.valign == ComplexStyleText.VALIGN_TOP)
{
//居中上
textStartX = textStartX + (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
lineStartX = (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_MIDDLE)
{
//居中中
textStartX = textStartX + (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
lineStartX = (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
textStartY = textStartY + (this._fontWHs[1] -textMaxHeight)/2;
lineStartY = (this._fontWHs[1] -textMaxHeight)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_BOTTOM)
{
//居中下
textStartX = textStartX + (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
lineStartX = (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
textStartY = textStartY + this._fontWHs[1] -textMaxHeight;
lineStartY = this._fontWHs[1] -textMaxHeight;
}
this.paintDrawText(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY);
}
/**
* 右对齐文字排版
* @param textData
*/
private paintRight(drawTextData:Array<any>,drawTextLineData:Array<any>,textStartX:number,textStartY:number,lineStartX:number,lineStartY:number,isWordWarp:Boolean = false):void
{
//居右上
if(isWordWarp)
this._textIndex++;
var textMaxHeight:number = this._textVo.align.indexOf("vertical") == -1 ? this._textMaxHeight : this.getCurTextMaxheight;
if(this._textVo.valign == ComplexStyleText.VALIGN_TOP)
{
//居右上
textStartX = textStartX +this._fontWHs[0] - this.getCurTextMaxWidth;
lineStartX = this._fontWHs[0] - this.getCurTextMaxWidth;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_MIDDLE)
{
//居右中
textStartX = textStartX +this._fontWHs[0] - this.getCurTextMaxWidth;
lineStartX = this._fontWHs[0] - this.getCurTextMaxWidth;
textStartY = textStartY + (this._fontWHs[1] - textMaxHeight)/2;
lineStartY = (this._fontWHs[1] - textMaxHeight)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_BOTTOM)
{
//居右下
textStartX = textStartX +this._fontWHs[0] - this.getCurTextMaxWidth;
lineStartX = this._fontWHs[0] - this.getCurTextMaxWidth;
textStartY = textStartY + this._fontWHs[1] - textMaxHeight;
lineStartY = this._fontWHs[1] - textMaxHeight;
}
this.paintDrawText(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY);
}
/**
* 左对齐文字排版
*/
private paintLeft(drawTextData:Array<any>,drawTextLineData:Array<any>,textStartX:number,textStartY:number,lineStartX:number,lineStartY:number,isWordWarp:Boolean = false):void
{
if(isWordWarp)
this._textIndex++;
var textMaxHeight:number = this._textVo.align.indexOf("vertical") == -1 ? this._textMaxHeight : this.getCurTextMaxheight;
if(this._textVo.valign == ComplexStyleText.VALIGN_MIDDLE)
{
//居左中
textStartY = textStartY + (this._fontWHs[1] - textMaxHeight)/2;
lineStartY = (this._fontWHs[1] - textMaxHeight)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_BOTTOM)
{
//竖排居左
textStartY = textStartY + this._fontWHs[1] - textMaxHeight;
lineStartY = this._fontWHs[1] - textMaxHeight;
}
this.paintDrawText(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY);
}
/**
* 获取当前绘制文字的最大宽度,用于横向水平排版
* @return
*/
private get getCurTextMaxWidth():number
{
var width:number = 0;
for(var i:number = 0,sz:number = this._textDrawWidths.length;i<sz;i++)
{
if(this._textVo.align == ComplexStyleText.VERTICAL_CENTER)
{
//竖排居中排版需要计算文本的总宽度
width += this._textDrawWidths[i];
}else
{
if(width < this._textDrawWidths[i])
width = this._textDrawWidths[i];
}
}
return width;
}
/**
* 获得当前绘制文字的最大高度值,用于竖向排版
* @return
*/
private get getCurTextMaxheight():number
{
var height:number = 0;
for(var i:number = 0,sz:number = this._textDrawHeights.length;i<sz;i++)
{
if(height < this._textDrawHeights[i])
height = this._textDrawHeights[i];
}
return height;
}
/**
* 绘制文字和下划线排版
* @param drawTextData
* @param drawTextLineData
* @param textStartX
* @param textStartY
* @param lineStartX
* @param lineStartY
*/
private paintDrawText(
drawTextData:Array<any>,
drawTextLineData,
textStartX:number = 0,
textStartY:number = 0,
lineStartX:number = 0,
lineStartY:number = 0
):void
{
if(this._isPrinter)
{
//这里存在对象数据深度拷贝的问题,暂时区分渲染类型
//存储文字数据,用于做打字效果
var tempArr:Array<any> =drawTextData[0];
for(var i:number = 0,sz:number = tempArr.length;i<sz;i++)
{
var htmlchar:Laya.HTMLChar = tempArr[i];
var tempX:number = htmlchar.x;
var tempY:number = htmlchar.y;
htmlchar.x += textStartX;
htmlchar.y += textStartY;
this._printerTextWords.push([[htmlchar],0,0,drawTextData[3],drawTextData[4]]);
}
}else
{
this._textfiled.graphics.fillWords(drawTextData[0],textStartX,textStartY,drawTextData[3],drawTextData[4]);
if(drawTextLineData)
{
this._textfiled.graphics.drawLine(
drawTextLineData[0]+lineStartX, //起始X位置
drawTextLineData[1]+lineStartY, //起始Y位置
drawTextLineData[2]+lineStartX, //结束X位置
drawTextLineData[3]+lineStartY, //结束Y位置
drawTextLineData[4], //绘制下划线颜色
drawTextLineData[5]); //线条宽度
}
}
}
/**打字机所需的文字信息**/
private _printerTextWords:Array<any> = [];
/**
*
* @param words
* @param tempTextX
* @param tempTextY
* @param specialInfo
*
*/
private onDrawTextLine(textfiled:Laya.Label,words:Array<any>,tempTextX:number,tempTextY:number,fontlInfo:FontInfo):void
{
var textData:Array<any> = [];
var font:string = fontlInfo.fontSize + "px " + this._textVo.font;
textData.push([(words as Array<any>),tempTextX,tempTextY,font,fontlInfo.fontColor,fontlInfo.isLineWrap]);
if(fontlInfo.isUnderLine)
{
//带下划线效果
var lastIndex:number = words.length - 1;
var lastWords:Laya.HTMLChar = words[lastIndex];
var lineY:number = lastWords.y + lastWords.height + tempTextY;
var tempLineY:number = 2;//微调下划线距离文字的间距
if(lastWords.y == words[0].y)
{
textData.push([
tempTextX + words[0].x, //起始X位置
lineY+tempLineY, //起始Y位置
tempTextX + lastWords.x + lastWords.width+tempLineY, //结束X位置
lineY+tempLineY, //结束Y位置
fontlInfo.fontColor, //绘制下划线颜色
2
]);
}else
{
//带下划线折行,暂时不处理,后面考虑
}
}
this._textDrawDatas.push(textData);//储存当前需要绘制的文字数据
}
/**文字自动换行记录折行数量**/
private _textAutoWarpInt:number = 1;
/**
* 获取文字的htmlchar信息
* @param fontSize 文字字号
* @param text 绘制的文字内容
* @return
*/
private getWords(fontSize:number,text:string):Array<Laya.HTMLChar>
{
var words:Array<Laya.HTMLChar> = new Array<Laya.HTMLChar>();
var size:any;
var style:Object = {};
style["font"] = fontSize + "px " + this._textVo.font;
style["fontSize"] = fontSize;
var fontStr:string = style["font"];
this._textAutoWarpInt = 1;
for (var i:number = 0, n:number = text.length; i < n; i++) {
size = Laya.Browser.measureText(text.charAt(i), fontStr);
words[i] = Laya.HTMLChar.create().setData(text.charAt(i), size.width, size.height || style["fontSize"], style);
var word:Laya.HTMLChar = words[i];
var wordOld:Laya.HTMLChar = words[i-1];
//横排
if(wordOld)
{
if(this._textVo.align.indexOf("vertical")== -1)
{
//横排
var tempX:number = wordOld.x + wordOld.width + this._textVo.wordSpace;//这里没有考虑自动换行,如果考虑这里需要根据设置的宽度处理下就行
if((tempX + fontSize) >= this._fontWHs[0])
{
//单行文字自动换行处理
tempX = 0;
this._textAutoWarpInt += 1;
}
word.x = tempX;
//单行文字自动换行处理,重新计算高度
if(this._textAutoWarpInt!= 1)
word.y = (this._textAutoWarpInt -1) * (fontSize + this._textVo.leading);
}else
{
//竖排
var tempWordY:number = wordOld.y + wordOld.height + this._textVo.leading;//这里是有自己折行的考虑
if(tempWordY + word.height > this._fontWHs[1])
{
this._textAutoWarpInt +=1;
tempWordY = 0;//当前这个文字的高度超出总高度,需要自动换行
}
word.y = tempWordY;
//这里需要处理文字竖排的情况,根据父容器的高度做,竖排居左,竖排居中,竖排居右的排版
if(this._textVo.align == ComplexStyleText.VERTICAL_RIGHT)
{
//竖排居右
if(this._textAutoWarpInt != 1)
{
//折行需要重新计算X的位置
word.x = -(this._textAutoWarpInt -1) * (wordOld.width + this._textVo.wordSpace);
}else
{
if(word.x != wordOld.x)
word.x = wordOld.x - wordOld.width - this._textVo.wordSpace;
else
word.x = wordOld.x;
}
}else
{
if(this._textAutoWarpInt != 1)
{
word.x = (this._textAutoWarpInt -1) * (wordOld.width + this._textVo.wordSpace);
}else
{
//折行需要重新计算X的位置
if(word.x != wordOld.x)
word.x = wordOld.x + wordOld.width + this._textVo.wordSpace;
else
word.x = wordOld.x;
}
}
}
}
}
return words;
}
/**
* 获取单个文本的总宽度信息
* @param words
* @return
*/
public getDanTextMaxWidth(words:Array<any>):Array<any>
{
var width:number = 0;
var wordOldX:number = 0;
var charWidth:number = 0;
for(var i:number = 0,sz:number = words.length;i<sz;i++)
{
var word:Laya.HTMLChar= words[i];
//竖排考虑
if(this._textVo.align.indexOf("vertical")!= -1 && word.x <= wordOldX)
{
charWidth = word.width;
return [word.width,charWidth];//这里考虑自动折行的情况
}
width += word.width + this._textVo.wordSpace;
wordOldX = word.x;
charWidth = word.width;
}
return [width,charWidth];
}
/**
* 获取单个文本的总高度信息
* @param words
* @return
*/
public getDanTextMaxHeight(words:Array<any>):number
{
var height:number = 0;
var wordOldY:number = 0;
for(var i:number = 0,sz:number = words.length;i<sz;i++)
{
var word:Laya.HTMLChar= words[i];
if(word.y < wordOldY)
return height;//这里考虑自动折行的情况
height += word.height + this._textVo.leading;
wordOldY = word.y;
}
return height;
}
/**
* 销毁方法
*
*/
public dispose():void
{
if(this._textfiled)
{
this._textfiled.graphics.clear();
this._textfiled.removeSelf();
}
if(this._textBox)
this._textBox.removeSelf();
this._textBox = null;
this._textfiled = null;
this._textDrawDatas = null;
this._textDrawWidths = null;
this._textDrawHeights = null;
this._fontWHs = null;
}
}
export class FontInfo
{
/**文本信息**/
public fontText:string;
/**文本颜色**/
public fontColor:string;
/**文本字号**/
public fontSize:number;
/**是否显示下划线**/
public isUnderLine:Boolean;
/**是否折行**/
public isLineWrap:Boolean;
/**是否显示**/
public isVisible:Boolean;
constructor(data:Array<any>)
{
this.fontText = data[0];
this.fontColor = data[1];
this.fontSize = parseInt(data[2]);
this.isUnderLine = parseInt(data[3]) ? true : false;
this.isLineWrap = parseInt(data[4]) ? true : false;
this.isVisible =parseInt(data[5]) ? true : false;
}
}
export class TextVo
{
/**展示文字vo,FontInfo对象**/
public lableVo:Array<FontInfo>;
/**设置行间距,默认0像素**/
public leading:number = 0;
/**设置字幕类的坐标,格式:[x,y]**/
public posArr:Array<number>;
/**设置字幕类的尺寸,格式:[宽,高]**/
public textSize:Array<number>;
/**设置文字字间距,默认5像素**/
public wordSpace:number=5;
/**设置字体,默认:Arial***/
public font:string ="Arial";
/**垂直,默认居上**/
public valign:string = ComplexStyleText.VALIGN_TOP;
/**水平,默认居左**/
public align:string = ComplexStyleText.VERTICAL_LEFT;
/**功能类型:
* 0:打字机效果
* 1:淡出效果
* 2:淡入效果
* 3:直接渲染
* **/
public type:number = 3;
}
import { ComplexStyleText, TextVo } from "./ComplexStyleText";
export module TextUtil
{
export function ComplexText(textVo:TextVo):ComplexStyleText
{
var text:ComplexStyleText = new ComplexStyleText();
if(textVo && textVo.posArr.length)
text.pos(textVo.posArr[0],textVo.posArr[1]);
if(textVo && textVo.textSize&& textVo.textSize.length)
text.setSize(textVo.textSize[0],textVo.textSize[1]);//设置字幕类的尺寸
switch (textVo.type) {
case 0://打字机效果
text.typewriter(textVo);
break;
case 1://淡出效果
text.fadeOut(textVo);
break;
case 2://淡入效果
text.fadeIn(textVo);
break;
default://直接渲染
text.onShowText(textVo);
break;
}
return text;
}
}
/**竖向左侧对齐**/
public static readonly VERTICAL_LEFT:string = "vertical_left";
/**竖向居中对齐**/
public static readonly VERTICAL_CENTER:string = "vertical_center";
/**竖向居右对齐**/
public static readonly VERTICAL_RIGHT:string = "vertical_right";
/**水平居左对齐方式。 */
public static readonly ALIGN_LEFT:string = "left";
/**水平居中对齐方式。 */
public static readonly ALIGN_CENTER:string = "center";
/**水平居右对齐方式。 */
public static readonly ALIGN_RIGHT:string = "right";
/**垂直居中对齐方式。 */
public static readonly VALIGN_TOP:string = "top";
/**垂直居中对齐方式。 */
public static readonly VALIGN_MIDDLE:string = "middle";
/**垂直居底部对齐方式。 */
public static readonly VALIGN_BOTTOM:string = "bottom";
/**文字容器**/
private _textBox:Laya.Box;
/**文字**/
private _textfiled:Laya.Label;
/**宽高信息[宽,高]**/
private _fontWHs:Array<number> = [100,100];
/**绘制数据**/
private _textDrawDatas:Array<any>;
/**绘制数据的最大宽高信息 [宽]**/
private _textDrawWidths:Array<any> = [];
/**绘制数据的最大高度信息[高]**/
private _textDrawHeights:Array<any> = [];
/**文本最大高度**/
private _textMaxHeight:number = 0;
/**是否是打字机效果**/
private _isPrinter:Boolean = false;
/**渲染文本对象信息**/
private _textVo:TextVo;
constructor()
{
super();
}
/**
* 设置宽高
* @param width
* @param height
*
*/
public setSize(width:number,height:number):void
{
if(this._fontWHs[0] != width || this._fontWHs[1] != height)
{
this._fontWHs[0] = width;
this._fontWHs[1] = height;
}
}
/**
* 直接渲染
* @param textVo
*/
public onShowText(textVo:TextVo):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this._isPrinter = false;
this.renderText();
}
}
/**
* 打字机效果
* @param text
* @param speed,默认100毫秒
*/
public typewriter(textVo:TextVo,speed:number = 100):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this._isPrinter = true;
this.renderText();
this._textfiled.graphics.clear();
var ziIndex:number = 0;//当前播放的字索引
Laya.timer.loop(speed,this,onPlayDaZi);
function onPlayDaZi():void
{
if(ziIndex >= this._printerTextWords.length)
{
Laya.timer.clear(this,onPlayDaZi);
return;
}
var printTextArr:Array<any> = this._printerTextWords[ziIndex];
this._textfiled.graphics.fillWords(printTextArr[0],printTextArr[1],printTextArr[2],printTextArr[3],printTextArr[4]);
ziIndex++;
}
}
}
/**
* 淡入效果
* @param text 操作的文字内容
* @param 间隔时间 默认 30毫秒
*/
public fadeIn(textVo:TextVo,speed:number = 30):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this.renderText(0);
var num:number = 0;
Laya.timer.loop(speed,this,onFadeIn);
function onFadeIn():void
{
num++;
this._textfiled.alpha = num/10;
console.info("_textfiled.alpha:" + this._textfiled.alpha);
if(num>=10)
Laya.timer.clear(this,onFadeIn);
}
}
}
/**
* 淡出效果
* @param text
* @param speed
*/
public fadeOut(textVo:TextVo,speed:number = 30):void
{
this._textVo = textVo;
if(this._textVo && this._textVo.lableVo && this._textVo.lableVo.length)
{
this.renderText(1);
var num:number = 10;
Laya.timer.loop(speed,this,onFadeOut);
function onFadeOut():void
{
num--;
this._textfiled.alpha = num/10;
console.info("_textfiled.alpha:" + this._textfiled.alpha);
if(num<=0)
Laya.timer.clear(this,onFadeOut);
}
}
}
/**
* 渲染文字
* @param alpha
* @returns
*/
private renderText(alpha:number = 1):void
{
if(!this._textVo.lableVo||this._textVo.lableVo.length==0)
return;
if(!this._textBox)
{
this._textBox = new Laya.Box();
this.addChild(this._textBox);
this._textBox.size(this._fontWHs[0],this._fontWHs[1]);
this._textBox.graphics.drawRect(0,0,this._fontWHs[0],this._fontWHs[1],"#000000");
}
//创建文本
if(this._textfiled)
{
this._textfiled.graphics.clear();
}else
{
this._textfiled = new Laya.Label();
this._textBox.addChild(this._textfiled);
}
this._textfiled.alpha = alpha;//设置透明度
//记录绘制的文字数据
this._textDrawDatas = [];
var tempTextX:number =0;//文本临时X轴信息
var tempTextY:number = 0;//文本临时Y轴信息
var lineWrapInt:number = 0;//折行次数
for(var i:number = 0,sz:number =this._textVo.lableVo.length;i<sz;i++ )
{
//[文字内容|文字颜色|文字字号大小|文字是否显示下划线|文字是否显示]
var fontInfo:FontInfo = this._textVo.lableVo[i];
var words:Array<Laya.HTMLChar> = this.getWords(fontInfo.fontSize,fontInfo.fontText);
var temTextArr:Array<any> = this.getDanTextMaxWidth((words));//当前文本的总宽度和单个文字的宽度信息
var textWidth:number = temTextArr[0];//当前文本的最大宽度值
var currentTextWidth:number = temTextArr[1];//当前文字的宽度信息
var textHeight2:number = this.getDanTextMaxHeight((words));//用于竖排高度排版
if(!fontInfo.isVisible)
continue;//隐藏就忽略,继续下个文字处理
if(!fontInfo.isLineWrap)
{
this.onDrawTextLine(this._textfiled,words,tempTextX,tempTextY,fontInfo);
if(this._textVo.lableVo.length == 1 && this._textVo.align.indexOf("vertical")== -1)
{
this._textMaxHeight = this._textAutoWarpInt * (fontInfo.fontSize + this._textVo.leading);//横排
}
}
if(fontInfo.isLineWrap)
{
//折行
lineWrapInt +=1;
if(this._textVo.align.indexOf("vertical")== -1)
{
//横向折行,X轴坐标清0
tempTextY = tempTextY + fontInfo.fontSize + this._textVo.leading;
this.onDrawTextLine(this._textfiled,(words as Array<any>),0,tempTextY,fontInfo);
tempTextX = textWidth;
//记录文本最大的高度,用于布局跑排版
this._textMaxHeight = tempTextY + fontInfo.fontSize + this._textVo.leading+0;// 5 是差值,左下的时候下划线看不到,临时减去10的差值,显示下划线,后面差下这个问题
}else
{
//竖向折行,Y轴坐标清0
if(this._textVo.align == ComplexStyleText.VERTICAL_RIGHT)
{
tempTextX = tempTextX - currentTextWidth - this._textVo.wordSpace;
}else
{
tempTextX = tempTextX + currentTextWidth + this._textVo.wordSpace;
}
this.onDrawTextLine(this._textfiled,(words as Array<any>),tempTextX,0,fontInfo);
//记录文本最大的高度,用于布局跑排版
this._textMaxHeight = tempTextY + this._textVo.leading + 10;// 10 是差值,左下的时候下划线看不到,临时减去10的差值,显示下划线,后面差下这个问题
tempTextY = textHeight2;//记录折行时文本的高度
}
}else
{
if(this._textVo.align.indexOf("vertical")!= -1)
{
tempTextY += textHeight2;
if(fontInfo.isLineWrap)
tempTextX += textWidth;//竖向排版,有折行的情况下才能改变X轴位置
}else
{
tempTextX += textWidth;
}
}
//初始化文本的宽度信息
if(!this._textDrawWidths[lineWrapInt])
{
this._textDrawWidths[lineWrapInt] = 0;
}
//竖排计算高度
if(this._textVo.align.indexOf("vertical")!= -1)
{
if(!this._textDrawHeights[lineWrapInt])
{
this._textDrawHeights[lineWrapInt] = 0;
}
this._textDrawHeights[lineWrapInt] += textHeight2;
if(this._textVo.lableVo.length == 1)
{
//竖排根据高度自动折行,需要重新算宽度,用于对齐排版
currentTextWidth = this._textAutoWarpInt * (currentTextWidth +this._textVo.wordSpace);
}
//最大宽度计算
if(fontInfo.isLineWrap)
{
this._textDrawWidths[lineWrapInt] += currentTextWidth;
}
if(this._textDrawWidths[lineWrapInt]==0)
this._textDrawWidths[lineWrapInt] = currentTextWidth;//按上次记录的信息排版
}else
{
this._textDrawWidths[lineWrapInt] += textWidth;
}
}
//绘制文字数据
this.onRepaint();
}
private _textIndex:number = 0;
/**
* 绘制文字数据
*/
private onRepaint():void
{
this._textIndex = 0;
this._printerTextWords = [];
for(var i:number = 0,sz:number = this._textDrawDatas.length;i<sz;i++)
{
var textData:Array<any> = this._textDrawDatas[i];//数据里包括了文字数据和下划线数据
var drawTextData:Array<any> = textData[0];//绘制文字的数据
var drawTextLineData:Array<any> = textData[1];//文字下划线数据
var textStartX:number = drawTextData[1];//绘制文本的X轴起始点
var textStartY:number = drawTextData[2];//绘制文本的Y轴起始点
var lineStartX:number = 0;//绘制下划线的X轴起始点
var lineStartY:number = 0;//绘制下划线的Y轴起始点
var isWordWarp:Boolean = drawTextData[5];//是否折行
if(this._textVo.align == ComplexStyleText.ALIGN_LEFT || this._textVo.align == ComplexStyleText.VERTICAL_LEFT)
{
//横排居左
this.paintLeft(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY,isWordWarp);
}else if(this._textVo.align == ComplexStyleText.ALIGN_RIGHT || this._textVo.align == ComplexStyleText.VERTICAL_RIGHT)
{
//横排居右
this.paintRight(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY,isWordWarp);
}else if(this._textVo.align == ComplexStyleText.ALIGN_CENTER || this._textVo.align == ComplexStyleText.VERTICAL_CENTER)
{
//横排居中
this.paintMiddle(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY,isWordWarp);
}
}
}
/**
* 居中文字排版
* @param textData
*/
private paintMiddle(drawTextData:Array<any>,drawTextLineData:Array<any>,textStartX:number,textStartY:number,lineStartX:number,lineStartY:number,isWordWarp:Boolean = false):void
{
if(isWordWarp)
this._textIndex++;
var textMaxHeight:number = this._textVo.align.indexOf("vertical") == -1 ? this._textMaxHeight : this.getCurTextMaxheight;
if(this._textVo.valign == ComplexStyleText.VALIGN_TOP)
{
//居中上
textStartX = textStartX + (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
lineStartX = (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_MIDDLE)
{
//居中中
textStartX = textStartX + (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
lineStartX = (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
textStartY = textStartY + (this._fontWHs[1] -textMaxHeight)/2;
lineStartY = (this._fontWHs[1] -textMaxHeight)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_BOTTOM)
{
//居中下
textStartX = textStartX + (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
lineStartX = (this._fontWHs[0] - this.getCurTextMaxWidth)/2;
textStartY = textStartY + this._fontWHs[1] -textMaxHeight;
lineStartY = this._fontWHs[1] -textMaxHeight;
}
this.paintDrawText(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY);
}
/**
* 右对齐文字排版
* @param textData
*/
private paintRight(drawTextData:Array<any>,drawTextLineData:Array<any>,textStartX:number,textStartY:number,lineStartX:number,lineStartY:number,isWordWarp:Boolean = false):void
{
//居右上
if(isWordWarp)
this._textIndex++;
var textMaxHeight:number = this._textVo.align.indexOf("vertical") == -1 ? this._textMaxHeight : this.getCurTextMaxheight;
if(this._textVo.valign == ComplexStyleText.VALIGN_TOP)
{
//居右上
textStartX = textStartX +this._fontWHs[0] - this.getCurTextMaxWidth;
lineStartX = this._fontWHs[0] - this.getCurTextMaxWidth;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_MIDDLE)
{
//居右中
textStartX = textStartX +this._fontWHs[0] - this.getCurTextMaxWidth;
lineStartX = this._fontWHs[0] - this.getCurTextMaxWidth;
textStartY = textStartY + (this._fontWHs[1] - textMaxHeight)/2;
lineStartY = (this._fontWHs[1] - textMaxHeight)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_BOTTOM)
{
//居右下
textStartX = textStartX +this._fontWHs[0] - this.getCurTextMaxWidth;
lineStartX = this._fontWHs[0] - this.getCurTextMaxWidth;
textStartY = textStartY + this._fontWHs[1] - textMaxHeight;
lineStartY = this._fontWHs[1] - textMaxHeight;
}
this.paintDrawText(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY);
}
/**
* 左对齐文字排版
*/
private paintLeft(drawTextData:Array<any>,drawTextLineData:Array<any>,textStartX:number,textStartY:number,lineStartX:number,lineStartY:number,isWordWarp:Boolean = false):void
{
if(isWordWarp)
this._textIndex++;
var textMaxHeight:number = this._textVo.align.indexOf("vertical") == -1 ? this._textMaxHeight : this.getCurTextMaxheight;
if(this._textVo.valign == ComplexStyleText.VALIGN_MIDDLE)
{
//居左中
textStartY = textStartY + (this._fontWHs[1] - textMaxHeight)/2;
lineStartY = (this._fontWHs[1] - textMaxHeight)/2;
}else if(this._textVo.valign == ComplexStyleText.VALIGN_BOTTOM)
{
//竖排居左
textStartY = textStartY + this._fontWHs[1] - textMaxHeight;
lineStartY = this._fontWHs[1] - textMaxHeight;
}
this.paintDrawText(drawTextData,drawTextLineData,textStartX,textStartY,lineStartX,lineStartY);
}
/**
* 获取当前绘制文字的最大宽度,用于横向水平排版
* @return
*/
private get getCurTextMaxWidth():number
{
var width:number = 0;
for(var i:number = 0,sz:number = this._textDrawWidths.length;i<sz;i++)
{
if(this._textVo.align == ComplexStyleText.VERTICAL_CENTER)
{
//竖排居中排版需要计算文本的总宽度
width += this._textDrawWidths[i];
}else
{
if(width < this._textDrawWidths[i])
width = this._textDrawWidths[i];
}
}
return width;
}
/**
* 获得当前绘制文字的最大高度值,用于竖向排版
* @return
*/
private get getCurTextMaxheight():number
{
var height:number = 0;
for(var i:number = 0,sz:number = this._textDrawHeights.length;i<sz;i++)
{
if(height < this._textDrawHeights[i])
height = this._textDrawHeights[i];
}
return height;
}
/**
* 绘制文字和下划线排版
* @param drawTextData
* @param drawTextLineData
* @param textStartX
* @param textStartY
* @param lineStartX
* @param lineStartY
*/
private paintDrawText(
drawTextData:Array<any>,
drawTextLineData,
textStartX:number = 0,
textStartY:number = 0,
lineStartX:number = 0,
lineStartY:number = 0
):void
{
if(this._isPrinter)
{
//这里存在对象数据深度拷贝的问题,暂时区分渲染类型
//存储文字数据,用于做打字效果
var tempArr:Array<any> =drawTextData[0];
for(var i:number = 0,sz:number = tempArr.length;i<sz;i++)
{
var htmlchar:Laya.HTMLChar = tempArr[i];
var tempX:number = htmlchar.x;
var tempY:number = htmlchar.y;
htmlchar.x += textStartX;
htmlchar.y += textStartY;
this._printerTextWords.push([[htmlchar],0,0,drawTextData[3],drawTextData[4]]);
}
}else
{
this._textfiled.graphics.fillWords(drawTextData[0],textStartX,textStartY,drawTextData[3],drawTextData[4]);
if(drawTextLineData)
{
this._textfiled.graphics.drawLine(
drawTextLineData[0]+lineStartX, //起始X位置
drawTextLineData[1]+lineStartY, //起始Y位置
drawTextLineData[2]+lineStartX, //结束X位置
drawTextLineData[3]+lineStartY, //结束Y位置
drawTextLineData[4], //绘制下划线颜色
drawTextLineData[5]); //线条宽度
}
}
}
/**打字机所需的文字信息**/
private _printerTextWords:Array<any> = [];
/**
*
* @param words
* @param tempTextX
* @param tempTextY
* @param specialInfo
*
*/
private onDrawTextLine(textfiled:Laya.Label,words:Array<any>,tempTextX:number,tempTextY:number,fontlInfo:FontInfo):void
{
var textData:Array<any> = [];
var font:string = fontlInfo.fontSize + "px " + this._textVo.font;
textData.push([(words as Array<any>),tempTextX,tempTextY,font,fontlInfo.fontColor,fontlInfo.isLineWrap]);
if(fontlInfo.isUnderLine)
{
//带下划线效果
var lastIndex:number = words.length - 1;
var lastWords:Laya.HTMLChar = words[lastIndex];
var lineY:number = lastWords.y + lastWords.height + tempTextY;
var tempLineY:number = 2;//微调下划线距离文字的间距
if(lastWords.y == words[0].y)
{
textData.push([
tempTextX + words[0].x, //起始X位置
lineY+tempLineY, //起始Y位置
tempTextX + lastWords.x + lastWords.width+tempLineY, //结束X位置
lineY+tempLineY, //结束Y位置
fontlInfo.fontColor, //绘制下划线颜色
2
]);
}else
{
//带下划线折行,暂时不处理,后面考虑
}
}
this._textDrawDatas.push(textData);//储存当前需要绘制的文字数据
}
/**文字自动换行记录折行数量**/
private _textAutoWarpInt:number = 1;
/**
* 获取文字的htmlchar信息
* @param fontSize 文字字号
* @param text 绘制的文字内容
* @return
*/
private getWords(fontSize:number,text:string):Array<Laya.HTMLChar>
{
var words:Array<Laya.HTMLChar> = new Array<Laya.HTMLChar>();
var size:any;
var style:Object = {};
style["font"] = fontSize + "px " + this._textVo.font;
style["fontSize"] = fontSize;
var fontStr:string = style["font"];
this._textAutoWarpInt = 1;
for (var i:number = 0, n:number = text.length; i < n; i++) {
size = Laya.Browser.measureText(text.charAt(i), fontStr);
words[i] = Laya.HTMLChar.create().setData(text.charAt(i), size.width, size.height || style["fontSize"], style);
var word:Laya.HTMLChar = words[i];
var wordOld:Laya.HTMLChar = words[i-1];
//横排
if(wordOld)
{
if(this._textVo.align.indexOf("vertical")== -1)
{
//横排
var tempX:number = wordOld.x + wordOld.width + this._textVo.wordSpace;//这里没有考虑自动换行,如果考虑这里需要根据设置的宽度处理下就行
if((tempX + fontSize) >= this._fontWHs[0])
{
//单行文字自动换行处理
tempX = 0;
this._textAutoWarpInt += 1;
}
word.x = tempX;
//单行文字自动换行处理,重新计算高度
if(this._textAutoWarpInt!= 1)
word.y = (this._textAutoWarpInt -1) * (fontSize + this._textVo.leading);
}else
{
//竖排
var tempWordY:number = wordOld.y + wordOld.height + this._textVo.leading;//这里是有自己折行的考虑
if(tempWordY + word.height > this._fontWHs[1])
{
this._textAutoWarpInt +=1;
tempWordY = 0;//当前这个文字的高度超出总高度,需要自动换行
}
word.y = tempWordY;
//这里需要处理文字竖排的情况,根据父容器的高度做,竖排居左,竖排居中,竖排居右的排版
if(this._textVo.align == ComplexStyleText.VERTICAL_RIGHT)
{
//竖排居右
if(this._textAutoWarpInt != 1)
{
//折行需要重新计算X的位置
word.x = -(this._textAutoWarpInt -1) * (wordOld.width + this._textVo.wordSpace);
}else
{
if(word.x != wordOld.x)
word.x = wordOld.x - wordOld.width - this._textVo.wordSpace;
else
word.x = wordOld.x;
}
}else
{
if(this._textAutoWarpInt != 1)
{
word.x = (this._textAutoWarpInt -1) * (wordOld.width + this._textVo.wordSpace);
}else
{
//折行需要重新计算X的位置
if(word.x != wordOld.x)
word.x = wordOld.x + wordOld.width + this._textVo.wordSpace;
else
word.x = wordOld.x;
}
}
}
}
}
return words;
}
/**
* 获取单个文本的总宽度信息
* @param words
* @return
*/
public getDanTextMaxWidth(words:Array<any>):Array<any>
{
var width:number = 0;
var wordOldX:number = 0;
var charWidth:number = 0;
for(var i:number = 0,sz:number = words.length;i<sz;i++)
{
var word:Laya.HTMLChar= words[i];
//竖排考虑
if(this._textVo.align.indexOf("vertical")!= -1 && word.x <= wordOldX)
{
charWidth = word.width;
return [word.width,charWidth];//这里考虑自动折行的情况
}
width += word.width + this._textVo.wordSpace;
wordOldX = word.x;
charWidth = word.width;
}
return [width,charWidth];
}
/**
* 获取单个文本的总高度信息
* @param words
* @return
*/
public getDanTextMaxHeight(words:Array<any>):number
{
var height:number = 0;
var wordOldY:number = 0;
for(var i:number = 0,sz:number = words.length;i<sz;i++)
{
var word:Laya.HTMLChar= words[i];
if(word.y < wordOldY)
return height;//这里考虑自动折行的情况
height += word.height + this._textVo.leading;
wordOldY = word.y;
}
return height;
}
/**
* 销毁方法
*
*/
public dispose():void
{
if(this._textfiled)
{
this._textfiled.graphics.clear();
this._textfiled.removeSelf();
}
if(this._textBox)
this._textBox.removeSelf();
this._textBox = null;
this._textfiled = null;
this._textDrawDatas = null;
this._textDrawWidths = null;
this._textDrawHeights = null;
this._fontWHs = null;
}
}
export class FontInfo
{
/**文本信息**/
public fontText:string;
/**文本颜色**/
public fontColor:string;
/**文本字号**/
public fontSize:number;
/**是否显示下划线**/
public isUnderLine:Boolean;
/**是否折行**/
public isLineWrap:Boolean;
/**是否显示**/
public isVisible:Boolean;
constructor(data:Array<any>)
{
this.fontText = data[0];
this.fontColor = data[1];
this.fontSize = parseInt(data[2]);
this.isUnderLine = parseInt(data[3]) ? true : false;
this.isLineWrap = parseInt(data[4]) ? true : false;
this.isVisible =parseInt(data[5]) ? true : false;
}
}
export class TextVo
{
/**展示文字vo,FontInfo对象**/
public lableVo:Array<FontInfo>;
/**设置行间距,默认0像素**/
public leading:number = 0;
/**设置字幕类的坐标,格式:[x,y]**/
public posArr:Array<number>;
/**设置字幕类的尺寸,格式:[宽,高]**/
public textSize:Array<number>;
/**设置文字字间距,默认5像素**/
public wordSpace:number=5;
/**设置字体,默认:Arial***/
public font:string ="Arial";
/**垂直,默认居上**/
public valign:string = ComplexStyleText.VALIGN_TOP;
/**水平,默认居左**/
public align:string = ComplexStyleText.VERTICAL_LEFT;
/**功能类型:
* 0:打字机效果
* 1:淡出效果
* 2:淡入效果
* 3:直接渲染
* **/
public type:number = 3;
}
import { ComplexStyleText, TextVo } from "./ComplexStyleText";
export module TextUtil
{
export function ComplexText(textVo:TextVo):ComplexStyleText
{
var text:ComplexStyleText = new ComplexStyleText();
if(textVo && textVo.posArr.length)
text.pos(textVo.posArr[0],textVo.posArr[1]);
if(textVo && textVo.textSize&& textVo.textSize.length)
text.setSize(textVo.textSize[0],textVo.textSize[1]);//设置字幕类的尺寸
switch (textVo.type) {
case 0://打字机效果
text.typewriter(textVo);
break;
case 1://淡出效果
text.fadeOut(textVo);
break;
case 2://淡入效果
text.fadeIn(textVo);
break;
default://直接渲染
text.onShowText(textVo);
break;
}
return text;
}
}
哈哈,你还真有心啊,这么长的代码都粘贴