You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

468 lines
12 KiB
TypeScript

const oneMinuteSeconds = 60
const onehourSeconds = oneMinuteSeconds * 60
const oneDaySeconds = onehourSeconds * 24
let forbiddenWords: string[] = undefined
export class Utils {
//是否空值
public static isNull(o: any): boolean {
let type = Object.prototype.toString.call(o);
return ("[object Null]" === type || "[object Undefined]" === type);
}
//是否字符串
public static isString(o: any): boolean {
return ("[object String]" === Object.prototype.toString.call(o));
}
//是否数字
public static isNumber(o: any): boolean {
return ("[object Number]" === Object.prototype.toString.call(o));
}
//是否数组
public static isArray(o: any): boolean {
return ("[object Array]" === Object.prototype.toString.call(o));
}
//是否字典
public static isObject(o: any): boolean {
return ("[object Object]" === Object.prototype.toString.call(o));
}
//是否方法
public static isFunction(o: any): boolean {
return ("[object Function]" === Object.prototype.toString.call(o));
}
//继承
public static inherit(base: Function, obj: Function) {
for (let key in base.prototype) {
obj.prototype[key] = base.prototype[key];
}
return obj;
}
//继承
public static queryUrl(url: string) {
let querys = {};
let index = url.indexOf("?")
cc.log(index)
if (index >= 0) {
let strs = url.substr(index + 1).split("&")
for (let i = 0, len = strs.length; i < len; i++) {
if (strs[i].indexOf("=") > 0) {
let params = strs[i].split("=");
if (params[0].trim() != "") {
querys[params[0]] = params[1];
}
}
}
}
return querys;
}
// 将base64字符串转换成图片
public static getSpritFrameFromBase64(base64: string): cc.SpriteFrame {
base64 = "data:image/jpeg;base64," + base64;
let img = new Image();
img.src = base64;
let texture = new cc.Texture2D();
texture.initWithElement(img);
texture.handleLoadedTexture();
return new cc.SpriteFrame(texture);
}
//生成uuid
public static uuid(length: number) {
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
let uuid = [], i = 0;
let radix = chars.length;
if (length > 0) {
// Compact form
for (i = 0; i < length; i++) uuid[i] = chars[0 | Math.random() * radix];
} else {
// rfc4122, version 4 form
let r: number = 0;
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random() * 16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
}
//复制文本
public static onCopyText(copyText: string): boolean {
if (cc.sys.isBrowser) {
let input = document.createElement("input");
input.setAttribute("readonly", "readonly");
input.setAttribute("value", copyText);
input.style.position = "absolute";
input.style.left = "-9999px";
input.style.fontSize = "12pt"; // Prevent zooming on iOS
document.body.appendChild(input);
input.select();
input.setSelectionRange(0, 128);
let success = false;
try {
if (document.execCommand("Copy")) {
success = true;
}
} catch (e) {
console.log(e)
}
document.body.removeChild(input);
return success;
} else {
// if (Common.OpenFunction.COPYTEXT) {
// if (cc.sys.os == cc.sys.OS_ANDROID) {
// jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "JavaCopy", "(Ljava/lang/String;)V", copyText);
// return true
// }
// else if (cc.sys.os == cc.sys.OS_IOS) {
// let IOS_API = "AppController";
// jsb.reflection.callStaticMethod(IOS_API, "JavaCopy:", copyText);
// return true
// }
// }
}
return false
}
//复制文本
public static getCopyText(): string {
let copyText = ""
// if (Common.OpenFunction.COPYTEXT) {
// if (cc.sys.os == cc.sys.OS_ANDROID) {
// copyText = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getDuplicateContent", "()Ljava/lang/String;");
// }
// else if (cc.sys.os == cc.sys.OS_IOS) {
// let IOS_API = "AppController";
// copyText = jsb.reflection.callStaticMethod(IOS_API, "getDuplicateContent:", "");
// }
// }
return copyText
}
/**
* 尋找當前scrollView滑動百分比
* @param scrollView
*/
public static judgeScrollPercent(scrollView: cc.ScrollView) {
const offset = scrollView.getScrollOffset()
const maxOffset = scrollView.getMaxScrollOffset()
const offsetArray = [offset.x, offset.y]
const maxOffsetArray = [maxOffset.x, maxOffset.y, maxOffset.y]
const index = maxOffsetArray.indexOf(Math.max(...maxOffsetArray))
offsetArray[index] = Math.abs(offsetArray[index])
offsetArray[index] = offsetArray[index] < 0 ? 0 : offsetArray[index]
offsetArray[index] = offsetArray[index] > maxOffsetArray[index] ? maxOffsetArray[index] : offsetArray[index]
return offsetArray[index] / maxOffsetArray[index]
}
/**
* 轉換錢幣
*/
public static moneyUnitConvert(money: number) {
if (money < 1000) {
return money + ''
} else {
return money / 1000 + 'K'
}
}
/**
* 三位一撇
*/
public static numberWithCommas(number: number) {
let parts = number.toFixed(2).split('.')
let decimal = parts[1].slice();
for (let i = parts[1].length - 1; i >= 0; i--) {
if (parts[1][i] != '0') {
break;
}
else {
decimal = decimal.substr(0, i);
}
}
parts[1] = decimal;
return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',') + (parts[1] ? '.' + parts[1] : '')
}
/**
* 無條件捨去
*/
public static roundDown(number: number) {
return Number(String(number).split(".")[0])
}
public static deepClone(data: any) {
if (data === undefined || data === null) {
return data
}
return JSON.parse(JSON.stringify(data || {}))
}
/**
* 閃爍動畫
* @param node 閃爍節點
* @param duration 間隔
* @param repeat 重複次數(-1為無限)
* @param callBack 回調函式
*/
public static blink(node: cc.Node, duration: number, repeat = 0, endShow: boolean = true, callBack?: Function) {
// cc.log(`blick duration:${duration} repeat:${repeat}`);
node.active = true
cc.Tween.stopAllByTarget(node)
node.opacity = 0;
const show = endShow ? 255 : 0;
let action = cc.tween()
.to(duration, { opacity: 0 }, { easing: 'quadIn' })
.to(duration, { opacity: 255 }, { easing: 'quadOut' })
cc.tween(node).repeat(repeat, action).call(() => { node.opacity = show; callBack && callBack() }).start();
}
public static currencyFilter(value: number) {
if (value < 1000) {
return `${value}`
}
value = value - (value % 100)
return `${value / 1000}K`
}
public static getCanvasInParent(node: cc.Node): cc.Canvas {
if (!node) {
return undefined
}
let canvas = undefined
let parent = node.parent
while (!canvas) {
if (!parent) {
break
}
canvas = parent.getComponent(cc.Canvas)
parent = parent.parent
}
return canvas
}
public static clamp(val: number, min: number, max: number): number {
return val < min ? min : (val > max ? max : val)
}
public static copyString(str: string) {
const el = document.createElement('textarea')
el.value = str
el.setAttribute('readonly', '')
// el.style.contain = 'strict';
el.style.position = 'absolute'
el.style.left = '-9999px'
el.style.fontSize = '12pt' // Prevent zooming on iOS
const selection = getSelection()
let originalRange = null
if (selection.rangeCount > 0) {
originalRange = selection.getRangeAt(0)
}
document.body.appendChild(el)
el.select()
el.selectionStart = 0
el.selectionEnd = str.length
let success = false
try {
success = document.execCommand('copy')
} catch (err) { }
document.body.removeChild(el)
if (originalRange) {
selection.removeAllRanges()
selection.addRange(originalRange)
}
if (success) {
console.log('复制成功')
} else {
console.log('复制失败')
}
return success
}
public static setButtonInteractable(button: cc.Button, value: boolean) {
if (!button) {
return
}
button.interactable = value
}
public static changeNodeParent(node, parent) {
if (!node) {
cc.error("changeNodeParent node is null");
return;
}
if (!parent) {
cc.error("changeNodeParent parent is null");
return;
}
let pos = node.parent.convertToWorldSpaceAR(node.getPosition());
let changePos = parent.convertToNodeSpaceAR(pos);
node.parent = parent;
node.setPosition(changePos);
}
public static tweenNumberLabel(label: cc.Label, num: number, suffix: string = '') {
const currentNum = Number(label.string.replace(/,/g, '').replace(suffix, ''))
if (!Utils.isNumber(currentNum)) {
console.warn('label is not number:', label.string)
return
}
if (currentNum >= num) {
label.string = Utils.numberWithCommas(num) + suffix
return
}
const plusNum = num - currentNum
const betweenTime = 0.01
const count = 80
let currentCount = 0
label.unscheduleAllCallbacks()
label.schedule(
() => {
if (!label) {
return
}
currentCount += 1
label.string = Utils.numberWithCommas(Math.round(currentNum + (plusNum / count) * currentCount)) + suffix
if (currentCount === count) {
label.string = Utils.numberWithCommas(num) + suffix
}
},
betweenTime,
count - 1
)
}
public static tweenSpriteFillrange(sprite: cc.Sprite, percent: number) {
// cc.log("tweenSpriteFillrange ", percent)
let changeTotal = percent - sprite.fillRange;
const count = 80;
const betweenTime = 0.01
let per = changeTotal / count;
let curRange = sprite.fillRange;
sprite.unscheduleAllCallbacks();
sprite.schedule(() => {
curRange += per;
sprite.fillRange = curRange;
}, betweenTime, count - 1);
}
// 計算字符長度 (英文數字當成1 其他當成2)
public static countMultiLangStrLength(str: string): number {
const originalSize = str.length
const digitNLetter = str.replace(/[^a-zA-Z0-9]/g, '')
const englishSize = digitNLetter.length
const otherLength = (originalSize - digitNLetter.length) * 2
return englishSize + otherLength
}
public static formatNickname(str: string, maxLen = 6) {
let len = Utils.countMultiLangStrLength(str);
let subLen = len;
while (subLen > maxLen) {
str = str.substr(0, str.length - 1);
subLen = Utils.countMultiLangStrLength(str);
}
return len > 6 ? (str + "...") : str;
}
/**
* 數字換行(奇數上排數字大於下排, 偶數對半)
* @param numStr 欲轉換數字
* @param limitNum 幾位後要換行
*/
public static convertChipStr(numStr: string, limitNum: number = 3) {
const len = numStr.length
if (len > limitNum) {
const sliceLen = Math.ceil(len * 0.5)
return `${numStr.slice(0, sliceLen)}\n${numStr.slice(sliceLen)}`
} else {
return numStr
}
}
/** 發送訊息提示 */
public static showSendLog(eventName: string, message?: any) {
if (CC_DEBUG) {
message = message || {};
const time = this.convertTimestamp(new Date().getTime());
let data = JSON.parse(JSON.stringify(message)); // Deep Copy
console.log("%s %c %s", time, "background: Green; color: White;", "發送 " + eventName + " ", data);
}
}
/** 回傳訊息提示 */
public static showResponseLog(eventName: string, message?: any) {
if (CC_DEBUG) {
message = message || {};
const time = this.convertTimestamp(new Date().getTime());
let data = JSON.parse(JSON.stringify(message)); // Deep Copy
console.log("%s %c %s", time, "background: Green; color: White;", "回應 " + eventName + " ", data);
}
}
/** 廣播訊息提示 */
public static showPushLog(eventName: string, message: any) {
if (CC_DEBUG) {
message = message || {};
const time = this.convertTimestamp(new Date().getTime());
let data = JSON.parse(JSON.stringify(message)); // Deep Copy
console.log("%s %c %s", time, "background: Blue; color: White;", "廣播 " + eventName + " ", data);
}
}
private static convertTimestamp(value: number): string {
const t = new Date(value);
// const yyyy = t.getFullYear();
// const MM = t.getMonth() < 9 ? "0" + (t.getMonth()+1):t.getMonth()+1;
// const DD = t.getDate() < 10 ? "0" + t.getDate() : t.getDate();
const hh = t.getHours() < 10 ? "0" + t.getHours() : t.getHours();
const mm = t.getMinutes() < 10 ? "0" + t.getMinutes() : t.getMinutes()
const ss = t.getSeconds() < 10 ? "0" + t.getSeconds() : t.getSeconds()
return `${hh}:${mm}:${ss}`;
}
}