first
This commit is contained in:
114
extensions/app/assets/manager/ui/comp/UIMgrLoading.ts
Normal file
114
extensions/app/assets/manager/ui/comp/UIMgrLoading.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import { Component, Graphics, Node, Size, UITransform, _decorator } from 'cc';
|
||||
const { ccclass, property, requireComponent } = _decorator;
|
||||
|
||||
@ccclass('UIMgrLoading')
|
||||
@requireComponent(UITransform)
|
||||
export default class UIMgrLoading extends Component {
|
||||
@property(Node)
|
||||
private loading: Node;
|
||||
|
||||
@property({ tooltip: '动画的尺寸' })
|
||||
private size: Size = new Size(60, 60);
|
||||
|
||||
@property({ tooltip: '等待几秒后开始动画' })
|
||||
private delay = 0;
|
||||
|
||||
private progress = 0;
|
||||
private ringScale = 1;
|
||||
private reverse = false;
|
||||
|
||||
private angleSpeed = 120;
|
||||
private ringSpeed = 0.02;
|
||||
|
||||
private inited = false;
|
||||
private drawing = false;
|
||||
private timedown = 0;
|
||||
|
||||
init() {
|
||||
if (this.inited) return;
|
||||
this.inited = true;
|
||||
|
||||
this.progress = 0;
|
||||
this.ringScale = 1;
|
||||
this.loading.angle = 0;
|
||||
this.reverse = false;
|
||||
|
||||
this.drawing = false;
|
||||
this.timedown = this.delay;
|
||||
this.loading.getComponent(Graphics).clear();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.inited = false;
|
||||
this.drawing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 需要重写
|
||||
*/
|
||||
private onDraw() {
|
||||
const graphics = this.loading.getComponent(Graphics);
|
||||
const uiTransform = this.loading.getComponent(UITransform);
|
||||
|
||||
const centerX = this.size.width * (0.5 - uiTransform.anchorX);
|
||||
const centerY = this.size.height * (0.5 - uiTransform.anchorY);
|
||||
|
||||
const r = Math.min(this.size.width / 2, this.size.height / 2);
|
||||
|
||||
const allPI = Math.PI;
|
||||
const offst = 0;
|
||||
|
||||
graphics.clear();
|
||||
if (this.reverse) {
|
||||
const start = 0.5 * Math.PI + offst;
|
||||
const end = 0.5 * Math.PI + this.progress * 2 * allPI + offst;
|
||||
graphics.arc(centerX, centerY, r, start, end, true);
|
||||
} else {
|
||||
const start = 0.5 * Math.PI - offst;
|
||||
const end = 0.5 * Math.PI - this.progress * 2 * allPI - offst;
|
||||
graphics.arc(centerX, centerY, r, start, end, false);
|
||||
}
|
||||
graphics.stroke();
|
||||
}
|
||||
|
||||
protected update(dt: number): void {
|
||||
if (!this.inited) return;
|
||||
|
||||
// 倒计时
|
||||
if (!this.drawing) {
|
||||
if (this.timedown > 0) {
|
||||
this.timedown -= dt;
|
||||
}
|
||||
if (this.timedown <= 0) {
|
||||
this.drawing = true;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 旋转
|
||||
this.loading.angle -= this.angleSpeed * dt;
|
||||
if (this.loading.angle >= 360 || this.loading.angle <= -360) {
|
||||
this.loading.angle = this.loading.angle % 360;
|
||||
}
|
||||
|
||||
// 进度
|
||||
if (this.ringScale > 0) {
|
||||
this.progress = Math.min(1, this.progress + this.ringSpeed * this.ringScale);
|
||||
|
||||
if (this.progress == 1) {
|
||||
this.ringScale = -1;
|
||||
this.reverse = !this.reverse;
|
||||
}
|
||||
} else {
|
||||
this.progress = Math.max(0, this.progress + this.ringSpeed * this.ringScale);
|
||||
|
||||
if (this.progress == 0) {
|
||||
this.ringScale = 1;
|
||||
this.reverse = !this.reverse;
|
||||
}
|
||||
}
|
||||
|
||||
this.onDraw();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "4a8e5697-ae78-4a4a-8d08-17acc6823a27",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
167
extensions/app/assets/manager/ui/comp/UIMgrShade.ts
Normal file
167
extensions/app/assets/manager/ui/comp/UIMgrShade.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
import { Camera, Color, Component, Director, Material, RenderTexture, Sprite, SpriteFrame, UIOpacity, UITransform, _decorator, director } from 'cc';
|
||||
import Core from '../../../Core';
|
||||
const { ccclass, property, requireComponent } = _decorator;
|
||||
|
||||
@ccclass('UIMgrShade')
|
||||
@requireComponent(Sprite)
|
||||
@requireComponent(UIOpacity)
|
||||
export default class UIMgrShade extends Component {
|
||||
@property(Material)
|
||||
private blurMaterial: Material = null;
|
||||
|
||||
@property(SpriteFrame)
|
||||
private shadeFrame: SpriteFrame = null;
|
||||
|
||||
@property
|
||||
private _delay = 0;
|
||||
@property
|
||||
get delay() { return this._delay; }
|
||||
set delay(v) { this._delay = Math.max(v, 0); }
|
||||
|
||||
@property
|
||||
private _begin = 0;
|
||||
@property
|
||||
get begin() { return this._begin; }
|
||||
set begin(v) { if (v >= 0 && v <= 255) this._begin = v; }
|
||||
|
||||
@property
|
||||
private _end = 255;
|
||||
@property
|
||||
get end() { return this._end; }
|
||||
set end(v) { if (v >= 0 && v <= 255) this._end = v; }
|
||||
|
||||
@property
|
||||
private _speed = 10;
|
||||
@property
|
||||
get speed() {
|
||||
if (this.begin == this.end) {
|
||||
return 0;
|
||||
} else if (this.begin > this.end) {
|
||||
return this._speed > 0 ? -this._speed : this._speed;
|
||||
} else {
|
||||
return this._speed >= 0 ? this._speed : -this._speed;
|
||||
}
|
||||
}
|
||||
set speed(v) { this._speed = v; }
|
||||
|
||||
private get sprite() {
|
||||
return this.node.getComponent(Sprite);
|
||||
}
|
||||
private get opacity() {
|
||||
return this.node.getComponent(UIOpacity);
|
||||
}
|
||||
|
||||
private inited = false;
|
||||
private drawing = false;
|
||||
private timedown = 0;
|
||||
|
||||
private blurFrame: SpriteFrame = null;
|
||||
|
||||
init(delay: number, begin: number, end: number, speed: number, blur: boolean) {
|
||||
if (blur) {
|
||||
director.targetOff(this);
|
||||
this.inited = false;
|
||||
this.drawing = false;
|
||||
|
||||
this.sprite.color = Color.WHITE;
|
||||
this.sprite.customMaterial = null;
|
||||
this.sprite.spriteFrame = this.blurFrame;
|
||||
if (this.blurFrame) this.blurFrame.flipUVY = false;
|
||||
|
||||
let count = 0;
|
||||
const cameras = director.getScene().getComponentsInChildren(Camera);
|
||||
director.on(Director.EVENT_BEFORE_RENDER, () => {
|
||||
count++;
|
||||
|
||||
const renderTexture = new RenderTexture();
|
||||
const size = this.node.getComponent(UITransform);
|
||||
renderTexture.reset({ width: size.width / 2, height: size.height / 2 });
|
||||
renderTexture.addRef();
|
||||
|
||||
Core.inst.manager.ui.screenshot(renderTexture, {
|
||||
cameraList: cameras
|
||||
});
|
||||
|
||||
if (count === 1) {
|
||||
this.blurFrame = new SpriteFrame();
|
||||
this.blurFrame?.texture?.decRef();
|
||||
this.blurFrame.texture = renderTexture;
|
||||
this.blurFrame.flipUVY = true;
|
||||
this.sprite.spriteFrame = this.blurFrame;
|
||||
this.sprite.customMaterial = this.blurMaterial;
|
||||
this.blurMaterial.setProperty('blurLevel', 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (count === 5) {
|
||||
director.targetOff(this);
|
||||
this.sprite.spriteFrame.flipUVY = false;
|
||||
this.sprite.customMaterial = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.blurFrame?.texture?.decRef();
|
||||
this.blurFrame.texture = renderTexture;
|
||||
this.blurFrame.flipUVY = true;
|
||||
this.sprite.spriteFrame = this.blurFrame;
|
||||
this.sprite.customMaterial = this.blurMaterial;
|
||||
this.blurMaterial.setProperty('blurLevel', count === 2 ? 3 : 1);
|
||||
}, this);
|
||||
} else {
|
||||
director.targetOff(this);
|
||||
this.sprite.spriteFrame = this.shadeFrame;
|
||||
this.sprite.color = Color.BLACK;
|
||||
this.sprite.customMaterial = null;
|
||||
}
|
||||
|
||||
this.delay = delay;
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
this.speed = speed;
|
||||
this.drawing = true;
|
||||
|
||||
if (this.inited) return;
|
||||
this.inited = true;
|
||||
this.timedown = this.delay;
|
||||
// 初始透明度
|
||||
this.opacity.opacity = this.timedown > 0 ? 0 : this.begin;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.inited = false;
|
||||
this.drawing = false;
|
||||
director.targetOff(this);
|
||||
this.blurFrame?.texture?.decRef();
|
||||
this.blurFrame?.destroy();
|
||||
this.blurFrame = null;
|
||||
this.sprite.spriteFrame = null;
|
||||
}
|
||||
|
||||
protected update(dt: number) {
|
||||
if (!this.inited) return;
|
||||
if (!this.drawing) return;
|
||||
|
||||
if (this.timedown > 0) {
|
||||
this.timedown -= dt;
|
||||
if (this.timedown > 0) return;
|
||||
// 初始透明度
|
||||
this.opacity.opacity = this.begin;
|
||||
}
|
||||
|
||||
const uiOpacity = this.opacity;
|
||||
if (this.speed > 0) {
|
||||
uiOpacity.opacity += this.speed * dt;
|
||||
if (uiOpacity.opacity > this.end) {
|
||||
uiOpacity.opacity = this.end;
|
||||
}
|
||||
} else if (this.speed < 0) {
|
||||
uiOpacity.opacity += this.speed * dt;
|
||||
if (uiOpacity.opacity < this.end) {
|
||||
uiOpacity.opacity = this.end;
|
||||
}
|
||||
}
|
||||
if (uiOpacity.opacity == this.end) {
|
||||
this.drawing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
extensions/app/assets/manager/ui/comp/UIMgrShade.ts.meta
Normal file
9
extensions/app/assets/manager/ui/comp/UIMgrShade.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d0295d9b-b01d-493c-9e31-5ed78e6c33ab",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
111
extensions/app/assets/manager/ui/comp/UIMgrToast.ts
Normal file
111
extensions/app/assets/manager/ui/comp/UIMgrToast.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { Component, NodePool, Prefab, Tween, UIOpacity, UITransform, _decorator, instantiate, tween, view } from 'cc';
|
||||
import UIMgrToastCell from './UIMgrToastCell';
|
||||
const { property, ccclass, requireComponent } = _decorator;
|
||||
|
||||
@ccclass('UIMgrToast')
|
||||
@requireComponent(UITransform)
|
||||
export default class UIMgrToast extends Component {
|
||||
@property(Prefab)
|
||||
private cell: Prefab = null;
|
||||
|
||||
/**每条信息显示几秒 */
|
||||
private lifeTime = 2;
|
||||
|
||||
/**消失时花费几秒渐隐 */
|
||||
private outTime = 0.2;
|
||||
|
||||
/**挤压基础速度 */
|
||||
private squeezeSpeed = 200;
|
||||
|
||||
/**节点缓存池子 */
|
||||
private pool = new NodePool();
|
||||
|
||||
add(data: {
|
||||
message: string,
|
||||
timeout?: number
|
||||
}) {
|
||||
const cell = this.pool.get() || instantiate(this.cell);
|
||||
cell.setPosition(0, 0, 0);
|
||||
cell.parent = this.node;
|
||||
cell.active = true;
|
||||
|
||||
cell.getComponent(UIMgrToastCell).init(data.message);
|
||||
|
||||
cell.getComponent(UIOpacity).opacity = 255;
|
||||
tween(cell.getComponent(UIOpacity))
|
||||
.delay(data.timeout || this.lifeTime)
|
||||
.to(this.outTime, { opacity: 0 })
|
||||
.call(() => {
|
||||
this.pool.put(cell);
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
clear() {
|
||||
const children = this.node.children;
|
||||
for (let index = children.length - 1; index >= 0; index--) {
|
||||
Tween.stopAllByTarget(children[index].getComponent(UIOpacity));
|
||||
children[index].destroy();
|
||||
}
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.node.children.length;
|
||||
}
|
||||
|
||||
protected onDestroy() {
|
||||
this.pool.clear();
|
||||
}
|
||||
|
||||
protected update(dt: number) {
|
||||
const children = this.node.children;
|
||||
for (let index = children.length - 1, recovery = false; index >= 0; index--) {
|
||||
const zero = index === children.length - 1;
|
||||
const curr = children[index];
|
||||
|
||||
// 直接触发回收逻辑
|
||||
if (recovery) {
|
||||
Tween.stopAllByTarget(curr.getComponent(UIOpacity));
|
||||
this.pool.put(curr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zero) {
|
||||
const currUT = curr.getComponent(UITransform);
|
||||
|
||||
const lastMaxY = 0 - currUT.height / 2;
|
||||
const currMinY = curr.position.y + lastMaxY;
|
||||
|
||||
if (currMinY > lastMaxY) {
|
||||
// 存在空隙
|
||||
const addLen = Math.max(-this.squeezeSpeed * dt * (children.length - index), lastMaxY - currMinY);
|
||||
curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z);
|
||||
}
|
||||
} else {
|
||||
const last = children[index + 1];
|
||||
const currUT = curr.getComponent(UITransform);
|
||||
const lastUT = last.getComponent(UITransform);
|
||||
|
||||
const currMinY = curr.position.y - currUT.height / 2 - 6;//6像素的间隔
|
||||
const lastMaxY = last.position.y + lastUT.height / 2;
|
||||
|
||||
if (currMinY < lastMaxY) {
|
||||
// 存在重叠
|
||||
const addLen = Math.min(this.squeezeSpeed * dt * (children.length - index - 1), lastMaxY - currMinY);
|
||||
curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z);
|
||||
const winSize = view.getVisibleSize();
|
||||
if (currMinY > winSize.height / 2) {
|
||||
// 触发回收逻辑
|
||||
recovery = true;
|
||||
Tween.stopAllByTarget(curr.getComponent(UIOpacity));
|
||||
this.pool.put(curr);
|
||||
}
|
||||
} else if (currMinY > lastMaxY) {
|
||||
// 存在空隙
|
||||
const addLen = Math.max(-this.squeezeSpeed * dt * (children.length - index), lastMaxY - currMinY);
|
||||
curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
extensions/app/assets/manager/ui/comp/UIMgrToast.ts.meta
Normal file
9
extensions/app/assets/manager/ui/comp/UIMgrToast.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "cde1528c-f66c-40f4-bdd2-27bf138ce1df",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
26
extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts
Normal file
26
extensions/app/assets/manager/ui/comp/UIMgrToastCell.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Component, Label, UIOpacity, UITransform, _decorator } from 'cc';
|
||||
const { ccclass, property, requireComponent } = _decorator;
|
||||
|
||||
@ccclass('UIMgrToastCell')
|
||||
@requireComponent(UIOpacity)
|
||||
@requireComponent(UITransform)
|
||||
export default class UIMgrToastCell extends Component {
|
||||
@property(Label)
|
||||
private title: Label = null;
|
||||
|
||||
init(title: string) {
|
||||
if (title.split('\n').find((v) => v.length > 30)) {
|
||||
this.title.overflow = Label.Overflow.RESIZE_HEIGHT;
|
||||
this.title.getComponent(UITransform).width = 600;
|
||||
} else {
|
||||
this.title.overflow = Label.Overflow.NONE;
|
||||
}
|
||||
this.title.string = title;
|
||||
this.title.updateRenderData(true);
|
||||
}
|
||||
|
||||
unuse() {
|
||||
this.title.string = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "6cc631d6-b08e-4ee3-8bde-e307c4288734",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
68
extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts
Normal file
68
extensions/app/assets/manager/ui/comp/UIMgrZOrder.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { _decorator, Component, Director, director, Node } from 'cc';
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
@ccclass('UIMgrZOrder')
|
||||
export default class UIMgrZOrder extends Component {
|
||||
private zOrder = false;
|
||||
private tempArr: Node[] = [];
|
||||
|
||||
protected onLoad() {
|
||||
this.checkUpdateZOrder();
|
||||
this.node.on(Node.EventType.CHILD_ADDED, this.onChildAdded, this);
|
||||
this.node.on(Node.EventType.CHILD_REMOVED, this.onChildRemoveed, this);
|
||||
if (Node.EventType.CHILDREN_ORDER_CHANGED) {
|
||||
this.node.on(Node.EventType.CHILDREN_ORDER_CHANGED, this.checkUpdateZOrder, this);
|
||||
} else {
|
||||
this.node.on(Node.EventType.SIBLING_ORDER_CHANGED, this.checkUpdateZOrder, this);
|
||||
}
|
||||
}
|
||||
|
||||
protected onDestroy() {
|
||||
director.off(Director.EVENT_AFTER_UPDATE, this.updateZOrder, this);
|
||||
this.node.off(Node.EventType.CHILD_ADDED, this.onChildAdded, this);
|
||||
this.node.off(Node.EventType.CHILD_REMOVED, this.onChildRemoveed, this);
|
||||
if (Node.EventType.CHILDREN_ORDER_CHANGED) {
|
||||
this.node.off(Node.EventType.CHILDREN_ORDER_CHANGED, this.checkUpdateZOrder, this);
|
||||
} else {
|
||||
this.node.off(Node.EventType.SIBLING_ORDER_CHANGED, this.checkUpdateZOrder, this);
|
||||
}
|
||||
}
|
||||
|
||||
private onChildAdded(child: Node) {
|
||||
this.checkUpdateZOrder();
|
||||
child.on(Node.EventType.TRANSFORM_CHANGED, this.checkUpdateZOrder, this);
|
||||
}
|
||||
|
||||
private onChildRemoveed(child: Node) {
|
||||
child.off(Node.EventType.TRANSFORM_CHANGED, this.checkUpdateZOrder, this);
|
||||
}
|
||||
|
||||
private checkUpdateZOrder() {
|
||||
if (this.zOrder) return;
|
||||
this.zOrder = true;
|
||||
director.once(Director.EVENT_AFTER_UPDATE, this.updateZOrder, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新节点树排序
|
||||
*/
|
||||
public updateZOrder() {
|
||||
if (!this.zOrder) return;
|
||||
Array.prototype.push.apply(this.tempArr, this.node.children);
|
||||
this.tempArr
|
||||
.sort((a, b) => {
|
||||
return (a.position.z - b.position.z)
|
||||
|| (a.getSiblingIndex() - b.getSiblingIndex());
|
||||
})
|
||||
.forEach((child, index) => {
|
||||
child.setSiblingIndex(index);
|
||||
});
|
||||
|
||||
// 一定要放到最后再设置false,
|
||||
// 避免更新过程中设置siblingIndex,
|
||||
// 导致无限重复调用
|
||||
this.zOrder = false;
|
||||
this.tempArr.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ad5cb510-639e-40c2-acdd-399ad00629b9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user