代码
这个没有什么原理性的东西,直接贴上代码【位置、颜色等需要自行扩展】
/**
*
* @file Toast.ts
* @author dream
* @description 模拟安卓吐司效果
*
*/
import { BlockInputEvents, Canvas, color, director, ImageAsset, Label, Layers, Node, Sprite, SpriteFrame, Texture2D, tween, UIOpacity, UITransform, v3, view } from "cc";
/**
* 位置
*/
export enum Gravity {
BOTTOM,
}
export class Toast {
static readonly LENGTH_SHORT: number = 2; // 短时间吐司
static readonly LENGTH_LONG: number = 3.5; // 长时间吐司
private static pNode: Node | null = null;
private bgNode: Node;
private textNode: Node;
private node: Node;
private text: string = '';
private time: number = 1;
private textSize: number = 20;
private gravity: Gravity = Gravity.BOTTOM;
private constructor(node: Node | null) {
if (null == node) {
this.node = this.getPNode();
} else {
this.node = node;
}
this.bgNode = new Node();
this.bgNode.layer = Layers.Enum.UI_2D;
this.bgNode.addComponent(BlockInputEvents);
let sprite = this.bgNode.addComponent(Sprite);
sprite.type = Sprite.Type.SLICED;
let imageObj = new Image();
imageObj.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAQMAAABIeJ9nAAAAA1BMVEX///+nxBvIAAAACklEQVQI12MAAgAABAABINItbwAAAABJRU5ErkJggg==";
let textureObj = new Texture2D();
textureObj.image = new ImageAsset(imageObj);
let sf = new SpriteFrame();
sf.texture = textureObj;
sprite.spriteFrame = sf;
sprite.color = color(0, 0, 0, 200);
this.bgNode.active = false;
this.textNode = new Node('Text');
this.textNode.layer = Layers.Enum.UI_2D;
let uiTransform = this.textNode.addComponent(UITransform);
uiTransform.width = this.node.getComponent(UITransform)!.width;
let label = this.textNode.addComponent(Label);
label.horizontalAlign = Label.HorizontalAlign.CENTER;
label.verticalAlign = Label.VerticalAlign.CENTER;
this.textSize = 20;
this.textNode.parent = this.bgNode;
this.bgNode.parent = this.node;
}
/**
* 生成吐司
* @param node
* @param text
* @param time
* @returns
*/
static makeText(node: Node | null, text: string, time: number) {
let toast = new Toast(node);
toast.text = text;
toast.time = time;
return toast;
}
/**
* 显示吐司
*/
show() {
this.setOverFlow();
this.bgNode.active = true;
let uiOpacity = this.bgNode.getComponent(UIOpacity);
if (null == uiOpacity) {
uiOpacity = this.bgNode.addComponent(UIOpacity);
}
tween(uiOpacity)
.delay(this.time)
.to(0.3, { opacity: 0 })
.call(() => {
this.bgNode.destroy();
})
.start();
}
/**
* 设置文字
* @param text 文字
* @returns
*/
setText(text: string): Toast {
this.text = text;
let label = this.textNode.getComponent(Label)!;
label.string = this.text;
return this;
}
/**
* 设置文字大小
* @param textSize 文字大小
* @returns
*/
setTextSize(textSize: number): Toast {
this.textSize = textSize;
let label = this.textNode.getComponent(Label)!;
label.fontSize = this.textSize;
return this;
}
/**
* 设置时间
* @param time 时间
* @returns
*/
setTime(time: number) {
this.time = time;
return this;
}
/**
* 设置位置
* @param gravity 位置
* @returns
*/
setGravity(gravity: Gravity): Toast {
this.gravity = gravity;
return this;
}
private setPosition() {
let uiTransform = this.node.getComponent(UITransform)!;
let bgUITransform = this.bgNode.getComponent(UITransform)!;
if (Gravity.BOTTOM === this.gravity) {
let y = -uiTransform.height / 2 + bgUITransform.height / 2 + 64;
this.bgNode.position = v3(0, y, 0);
}
}
private setOverFlow() {
let maxLength = this.node.getComponent(UITransform)!.width / 2;
let label = this.textNode.getComponent(Label)!;
let fontLength = this.text.length * label.fontSize;
let uiTransform = this.textNode.getComponent(UITransform)!;
if (fontLength > maxLength) {
uiTransform.width = maxLength;
label.overflow = Label.Overflow.RESIZE_HEIGHT;
} else {
uiTransform.width = fontLength;
label.overflow = Label.Overflow.NONE;
}
let bgUITransform = this.bgNode.getComponent(UITransform)!;
bgUITransform.width = uiTransform.width + label.fontSize * 4;
bgUITransform.height = uiTransform.height;
this.setPosition();
}
private getPNode(): Node {
if (null == Toast.pNode || !Toast.pNode.isValid) {
Toast.pNode = new Node('Toast');
let transform = Toast.pNode.addComponent(UITransform);
Toast.pNode.layer = Layers.Enum.UI_2D;
Toast.pNode.addComponent(Canvas);
director.getScene()?.addChild(Toast.pNode);
let size = view.getVisibleSize();
transform.contentSize = size;
transform.width = size.width;
transform.height = size.height;
Toast.pNode.position = v3(size.width / 2, size.height / 2, 0);
}
return Toast.pNode;
}
}
系列文章
- CocosCreator简易开源框架SCL之白皮书
- CocosCreator开源框架SCL之弹框管理
- CocosCreator开源框架SCL之本地化存储
- CososCreator开源框架SCL之屏幕适配
该框架开发的小游戏:翻棋子游戏
- 如需2.x版本,请看CCCLibs仓库该仓库并没有整理,请自行参考
有任何建议或者疑问,可以关注作者公众号