本帖最后由 大当家 于 2023-7-6 13:35 编辑
还在为排行榜显示不全玩家名字而苦恼吗?还在为不同语言而导致文本长度过长而疯狂调大小吗?下面推出文字滚动组件,解决你的烦恼!!!
先展示一下效果吧!!!
上代码:
- 将你的文本UI组件放置在一个canvas容器下,并将他们的大小和位置重叠在一起。
- 导入如下代码:
enum EScrollerStatue {
/**停止状态 */
Stop = 1,
/**开始滚动 */
Start = 2,
/**滚动中 */
Rolling = 3,
}
// 原始对象接口
interface ITextBlock {
set text(msg: string);
}
export class TextScrollerDecorator implements ITextBlock {
/**可见长度 */
private _maxWidth: number = 0;
/**字体的最大长度 */
private _textWidth: number = 150;
private _canUpdate: boolean = false;
/**文字开始滚动时,停留几秒 1000 = 1s */
private _startCdTime: number = 1.8;
/**文字滚动到结尾时,停留几秒 */
private _endCdTime: number = 2;
private _time: number = 0;
private _tempPos: Type.Vector2;
private _statue: EScrollerStatue = EScrollerStatue.Start;
/**滚动速度 */
private _speed: number = 100;
constructor(private _canvas: UI.Canvas, private _textBlock: UI.TextBlock) {
this._maxWidth = this._canvas.size.x;
//父容器溢出隐藏
this._canvas.clipEnable = true;
this._textBlock.autoAdjust = false;
//文本不裁剪
this._textBlock.textHorizontalLayout = UI.UITextHorizontalLayout.NoClipping;
//水平左对齐
this._textBlock.textJustification = UI.TextJustify.Left;
this.extendText(this._textBlock.text);
}
public set text(msg: string) {
this._textBlock.text = msg;
this.extendText(msg);
}
private extendText(msg: string) {
//计算字体的最大长度
this._textWidth = RichText.caculateStringWidth(this._textBlock.text, this._textBlock.fontSize);
this.canUpdate = this._textWidth > this._maxWidth;
const size = this._textBlock.size;
size.x = this._textWidth;
this._textBlock.size = size;
}
public set canUpdate(canUpdate: boolean) {
this.reset();
if (canUpdate) {
TimeUtil.onEnterFrame.add(this._update, this)
} else {
TimeUtil.onEnterFrame.remove(this._update, this)
}
}
private reset() {
this._textBlock.position = Type.Vector2.zero;
this._tempPos = Type.Vector2.zero;
this._time = 0;
this._statue = EScrollerStatue.Start;
// console.log(this._statue)
}
public get canUpdate(): boolean {
return this._canUpdate;
}
private _update(dt: number) {
switch (this._statue) {
case EScrollerStatue.Start:
this.startRoll(dt);
break;
case EScrollerStatue.Rolling:
this.rolling(dt);
break;
case EScrollerStatue.Stop:
this.endRoll(dt);
break;
}
}
/**开始滚动 */
private startRoll(dt: number) {
this._time += dt;
if (this._time < this._startCdTime) return;
this._time = 0;
this._statue = EScrollerStatue.Rolling;
}
/**滚动中 */
private rolling(dt: number) {
this._tempPos.x -= this._speed * dt;
if (Math.abs(this._tempPos.x) > this._textWidth - this._maxWidth) {
this._statue = EScrollerStatue.Stop;
}
this._textBlock.position = this._tempPos;
}
private endRoll(dt: number) {
this._time += dt;
if (this._time < this._endCdTime) return;
this.reset()
}
/**停止滚动 */
public stopScroller() {
this.canUpdate = false;
}
/**设置滚动速度 */
public set speed(speed: number) {
this._speed = speed;
}
/**设置开始暂停的CD时间 */
public set startCdTime(time: number) {
this._startCdTime = time;
}
/**设置结束后暂停的CD时间 */
public set endCdTime(time: number) {
this._endCdTime = time;
}
}
namespace RichText {
/*
* @Author: pengcheng.zhang
* @Date: 2022-11-30 17:44:54
* @Last Modified by: pengcheng.zhang
* @Last Modified time: 2022-11-30 19:37:24
*/
const FontDefinition = {
'originSize': 24,
"32": { 'char': '空格', 'width': 8, xoffset: 0 },
"33": { 'char': '!', 'width': 8, xoffset: 0 },
"34": { 'char': '"', 'width': 10.667, xoffset: 0 },
"35": { 'char': '#', 'width': 18.667, xoffset: 0 },
"36": { 'char': '$', 'width': 18.667, xoffset: 0 },
"37": { 'char': '%', 'width': 24, xoffset: 0 },
"38": { 'char': '&', 'width': 18.667, xoffset: 0 },
"39": { 'char': '\'', 'width': 8, xoffset: 0 },
"40": { 'char': '(', 'width': 10.667, xoffset: 0 },
"41": { 'char': ')', 'width': 10.667, xoffset: 0 },
"42": { 'char': '*', 'width': 13.333, xoffset: 0 },
"43": { 'char': '+', 'width': 18.667, xoffset: 0 },
"44": { 'char': ',', 'width': 5.333, xoffset: 0 },
"45": { 'char': '-', 'width': 13.333, xoffset: 0 },
"46": { 'char': '.', 'width': 8, xoffset: 0 },
"47": { 'char': '/', 'width': 13.333, xoffset: 0 },
"48": { 'char': '0', 'width': 18.667, xoffset: 0 },
"49": { 'char': '1', 'width': 18.667, xoffset: 0 },
"50": { 'char': '2', 'width': 18.667, xoffset: 0 },
"51": { 'char': '3', 'width': 18.667, xoffset: 0 },
"52": { 'char': '4', 'width': 18.667, xoffset: 0 },
"53": { 'char': '5', 'width': 18.667, xoffset: 0 },
"54": { 'char': '6', 'width': 18.667, xoffset: 0 },
"55": { 'char': '7', 'width': 18.667, xoffset: 0 },
"56": { 'char': '8', 'width': 18.667, xoffset: 0 },
"57": { 'char': '9', 'width': 18.667, xoffset: 0 },
"65": { 'char': "A", 'width': 21.333, xoffset: 0 },
"66": { 'char': "B", 'width': 21.333, xoffset: 0 },
"67": { 'char': "C", 'width': 21.333, xoffset: 0 },
"68": { 'char': "D", 'width': 21.333, xoffset: 0 },
"69": { 'char': "E", 'width': 18.667, xoffset: 0 },
"70": { 'char': "F", 'width': 18.667, xoffset: 0 },
"71": { 'char': "G", 'width': 21.333, xoffset: 0 },
"72": { 'char': "H", 'width': 21.333, xoffset: 0 },
"73": { 'char': "I", 'width': 8, xoffset: 0 },
"74": { 'char': "J", 'width': 18.667, xoffset: 0 },
"75": { 'char': "K", 'width': 21.333, xoffset: 0 },
"76": { 'char': "L", 'width': 18.667, xoffset: 0 },
"77": { 'char': "M", 'width': 26.667, xoffset: 0 },
"78": { 'char': "N", 'width': 21.333, xoffset: 0 },
"79": { 'char': "O", 'width': 21.333, xoffset: 0 },
"80": { 'char': "P", 'width': 21.333, xoffset: 0 },
"81": { 'char': "Q", 'width': 21.333, xoffset: 0 },
"82": { 'char': "R", 'width': 21.333, xoffset: 0 },
"83": { 'char': "S", 'width': 18.667, xoffset: 0 },
"84": { 'char': "T", 'width': 18.667, xoffset: 0 },
"85": { 'char': "U", 'width': 21.333, xoffset: 0 },
"86": { 'char': "V", 'width': 21.333, xoffset: 0 },
"87": { 'char': "W", 'width': 26.667, xoffset: 0 },
"88": { 'char': "X", 'width': 21.333, xoffset: 0 },
"89": { 'char': "Y", 'width': 21.333, xoffset: 0 },
"90": { 'char': "Z", 'width': 18.667, xoffset: 0 },
"91": { 'char': "[", 'width': 8.667, xoffset: 0 },
"92": { 'char': "\\", 'width': 13.333, xoffset: 0 },
"93": { 'char': "]", 'width': 8.667, xoffset: 0 },
"94": { 'char': "^", 'width': 13.333, xoffset: 0 },
"95": { 'char': "_", 'width': 13.333, xoffset: 0 },
"96": { 'char': "`", 'width': 10.667, xoffset: 0 },
"97": { 'char': 'a', 'width': 18.667, xoffset: 0 },
"98": { 'char': 'b', 'width': 18.667, xoffset: 0 },
"99": { 'char': 'c', 'width': 18.667, xoffset: 0 },
"100": { 'char': 'd', 'width': 18.667, xoffset: 0 },
"101": { 'char': 'e', 'width': 16, xoffset: 0 },
"102": { 'char': 'f', 'width': 10.667, xoffset: 1 },
"103": { 'char': 'g', 'width': 18.667, xoffset: 0 },
"104": { 'char': 'h', 'width': 18.667, xoffset: 0 },
"105": { 'char': 'i', 'width': 8, xoffset: 0 },
"106": { 'char': 'j', 'width': 8, xoffset: 0 },
"107": { 'char': 'k', 'width': 16, xoffset: 0 },
"108": { 'char': 'l', 'width': 8, xoffset: 0 },
"109": { 'char': 'm', 'width': 26.667, xoffset: 0 },
"110": { 'char': 'n', 'width': 18.667, xoffset: 0 },
"111": { 'char': 'o', 'width': 18.667, xoffset: 0 },
"112": { 'char': 'p', 'width': 18.667, xoffset: 0 },
"113": { 'char': 'q', 'width': 18.667, xoffset: 0 },
"114": { 'char': 'r', 'width': 10.667, xoffset: 0 },
"115": { 'char': 's', 'width': 16, xoffset: 0 },
"116": { 'char': 't', 'width': 10.667, xoffset: 0 },
"117": { 'char': 'u', 'width': 18.667, xoffset: 0 },
"118": { 'char': 'v', 'width': 16, xoffset: 0 },
"119": { 'char': 'w', 'width': 24, xoffset: 0 },
"120": { 'char': 'x', 'width': 16, xoffset: 0 },
"121": { 'char': 'y', 'width': 16, xoffset: 0 },
"122": { 'char': 'z', 'width': 16, xoffset: 0 },
"123": { 'char': '{', 'width': 10.667, xoffset: 0 },
"124": { 'char': '|', 'width': 8, xoffset: 0 },
"125": { 'char': '}', 'width': 10.667, xoffset: 0 },
"126": { 'char': '~', 'width': 21.333, xoffset: 0 },
}
export function caculateStringWidth(str: string, fontSize: number) {
let length = 0
for (let i = 0; i < str.length; ++i) {
let unicode = str.charCodeAt(i)
if (unicode < 127) {
if (FontDefinition[unicode] != undefined) {
length += (FontDefinition[unicode].width + FontDefinition[unicode].xoffset) * fontSize / FontDefinition.originSize
}
} else {
length += 32 * fontSize / FontDefinition.originSize
}
}
return length
}
}
- new TextScrollerDecorator(canvas, TextBlock)。两个参数分别为刚刚UI上的canvas和TextBlock组件。
可以不用重新赋新的文本内容哟。创建TextScrollerDecorator对象后,会自动读取文本组件的文字内容哟!!!
可运行工程文件:
scrollerText.zip
(53.92 KB, 下载次数: 83)
|
|