2023-02-05 18:17:10 +08:00
|
|
|
|
/// <reference path="../types/core.d.ts" />
|
2022-12-29 12:02:48 +08:00
|
|
|
|
import { message } from 'ant-design-vue';
|
|
|
|
|
import { MessageApi } from 'ant-design-vue/lib/message';
|
2022-11-16 23:01:23 +08:00
|
|
|
|
import { isNil } from 'lodash';
|
2022-11-21 20:00:34 +08:00
|
|
|
|
import { Animation, TimingFn } from 'mutate-animate';
|
|
|
|
|
import { ComputedRef, ref } from 'vue';
|
2022-11-19 18:15:42 +08:00
|
|
|
|
import { EVENT_KEY_CODE_MAP } from './keyCodes';
|
2022-11-16 23:01:23 +08:00
|
|
|
|
|
2022-11-21 20:00:34 +08:00
|
|
|
|
type CanParseCss = keyof {
|
|
|
|
|
[P in keyof CSSStyleDeclaration as CSSStyleDeclaration[P] extends string
|
|
|
|
|
? P extends string
|
|
|
|
|
? P
|
|
|
|
|
: never
|
|
|
|
|
: never]: CSSStyleDeclaration[P];
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-16 23:01:23 +08:00
|
|
|
|
export default function init() {
|
2022-12-30 11:06:46 +08:00
|
|
|
|
return { has, getDamageColor, parseCss, tip };
|
2022-11-16 23:01:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 判定一个值是否不是undefined或null
|
|
|
|
|
* @param value 要判断的值
|
|
|
|
|
*/
|
|
|
|
|
export function has<T>(value: T): value is NonNullable<T> {
|
|
|
|
|
return !isNil(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据伤害大小获取颜色
|
|
|
|
|
* @param damage 伤害大小
|
|
|
|
|
*/
|
2022-12-27 23:31:14 +08:00
|
|
|
|
export function getDamageColor(damage: number): Color {
|
2022-11-16 23:01:23 +08:00
|
|
|
|
if (typeof damage !== 'number') return '#f00';
|
|
|
|
|
if (damage === 0) return '#2f2';
|
|
|
|
|
if (damage < 0) return '#7f7';
|
|
|
|
|
if (damage < core.status.hero.hp / 3) return '#fff';
|
|
|
|
|
if (damage < (core.status.hero.hp * 2) / 3) return '#ff4';
|
2022-12-30 14:14:28 +08:00
|
|
|
|
if (damage < core.status.hero.hp) return '#f93';
|
|
|
|
|
return '#f22';
|
2022-11-16 23:01:23 +08:00
|
|
|
|
}
|
2022-11-19 11:30:14 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 设置画布的长宽
|
|
|
|
|
* @param canvas 画布
|
|
|
|
|
* @param w 宽度
|
|
|
|
|
* @param h 高度
|
|
|
|
|
*/
|
|
|
|
|
export function setCanvasSize(
|
|
|
|
|
canvas: HTMLCanvasElement,
|
|
|
|
|
w: number,
|
|
|
|
|
h: number
|
|
|
|
|
): void {
|
|
|
|
|
canvas.width = w;
|
|
|
|
|
canvas.height = h;
|
|
|
|
|
canvas.style.width = `${w}px`;
|
|
|
|
|
canvas.style.height = `${h}px`;
|
|
|
|
|
}
|
2022-11-19 18:15:42 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取事件中的keycode对应的键
|
|
|
|
|
* @param key 要获取的键
|
|
|
|
|
*/
|
|
|
|
|
export function keycode(key: number) {
|
|
|
|
|
return EVENT_KEY_CODE_MAP[key];
|
|
|
|
|
}
|
2022-11-21 20:00:34 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解析css字符串为CSSStyleDeclaration对象
|
|
|
|
|
* @param css 要解析的css字符串
|
|
|
|
|
*/
|
|
|
|
|
export function parseCss(css: string): Partial<Record<CanParseCss, string>> {
|
2023-02-05 18:17:10 +08:00
|
|
|
|
const str = css.replace(/[\n\s\t]*/g, '').replace(/;*/g, ';');
|
2022-11-21 20:00:34 +08:00
|
|
|
|
const styles = str.split(';');
|
|
|
|
|
const res: Partial<Record<CanParseCss, string>> = {};
|
|
|
|
|
|
|
|
|
|
for (const one of styles) {
|
|
|
|
|
const [key, data] = one.split(':');
|
2022-11-30 16:42:44 +08:00
|
|
|
|
const cssKey = key.replace(/\-([a-z])/g, (str, $1) =>
|
2022-11-21 20:00:34 +08:00
|
|
|
|
$1.toUpperCase()
|
|
|
|
|
) as CanParseCss;
|
|
|
|
|
res[cssKey] = data;
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 使用打字机效果显示一段文字
|
|
|
|
|
* @param str 要打出的字符串
|
2022-11-30 16:42:44 +08:00
|
|
|
|
* @param time 打出总用时,默认1秒,当第四个参数是true时,该项为每个字的平均时间
|
2022-11-21 20:00:34 +08:00
|
|
|
|
* @param timing 打出时的速率曲线,默认为线性变化
|
2022-11-30 16:42:44 +08:00
|
|
|
|
* @param avr 是否将第二个参数视为每个字的平均时间
|
2022-11-21 20:00:34 +08:00
|
|
|
|
* @returns 文字的响应式变量
|
|
|
|
|
*/
|
|
|
|
|
export function type(
|
|
|
|
|
str: string,
|
|
|
|
|
time: number = 1000,
|
2022-11-30 16:42:44 +08:00
|
|
|
|
timing: TimingFn = n => n,
|
|
|
|
|
avr: boolean = false
|
2022-11-21 20:00:34 +08:00
|
|
|
|
): Ref<string> {
|
|
|
|
|
const toShow = eval('`' + str + '`') as string;
|
2022-11-30 16:42:44 +08:00
|
|
|
|
if (typeof toShow !== 'string') {
|
|
|
|
|
throw new TypeError('Error str type in typing!');
|
|
|
|
|
}
|
2022-12-29 00:26:12 +08:00
|
|
|
|
if (toShow.startsWith('!!html')) return ref(toShow);
|
2022-11-30 16:42:44 +08:00
|
|
|
|
if (avr) time *= toShow.length;
|
2022-11-21 20:00:34 +08:00
|
|
|
|
const ani = new Animation();
|
|
|
|
|
const content = ref('');
|
|
|
|
|
const all = toShow.length;
|
|
|
|
|
|
|
|
|
|
const fn = (time: number) => {
|
|
|
|
|
if (!has(time)) return;
|
|
|
|
|
const now = ani.x;
|
|
|
|
|
content.value = toShow.slice(0, Math.floor(now));
|
|
|
|
|
if (Math.floor(now) === all) {
|
|
|
|
|
ani.ticker.destroy();
|
2022-11-30 16:42:44 +08:00
|
|
|
|
content.value = toShow;
|
2022-11-21 20:00:34 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ani.ticker.add(fn);
|
|
|
|
|
|
|
|
|
|
ani.mode(timing).time(time).move(all, 0);
|
|
|
|
|
|
2022-12-31 19:49:43 +08:00
|
|
|
|
setTimeout(() => ani.ticker.destroy(), time + 100);
|
|
|
|
|
|
2022-11-21 20:00:34 +08:00
|
|
|
|
return content;
|
|
|
|
|
}
|
2022-12-29 12:02:48 +08:00
|
|
|
|
|
|
|
|
|
export function tip(
|
|
|
|
|
type: Exclude<keyof MessageApi, 'open' | 'config' | 'destroy'>,
|
|
|
|
|
text: string
|
|
|
|
|
) {
|
|
|
|
|
message[type]({
|
|
|
|
|
content: text,
|
|
|
|
|
class: 'antdv-message'
|
|
|
|
|
});
|
|
|
|
|
}
|
2022-12-30 23:28:27 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 设置文字分段换行等
|
|
|
|
|
* @param str 文字
|
|
|
|
|
*/
|
|
|
|
|
export function splitText(str: string[]) {
|
|
|
|
|
return str
|
|
|
|
|
.map((v, i, a) => {
|
|
|
|
|
if (/^\d+\./.test(v)) return `${' '.repeat(12)}${v}`;
|
|
|
|
|
else if (
|
|
|
|
|
(has(a[i - 1]) && v !== '<br>' && a[i - 1] === '<br>') ||
|
|
|
|
|
i === 0
|
|
|
|
|
) {
|
|
|
|
|
return `${' '.repeat(8)}${v}`;
|
|
|
|
|
} else return v;
|
|
|
|
|
})
|
|
|
|
|
.join('');
|
|
|
|
|
}
|
2023-01-15 20:09:02 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 在下一帧执行某个函数
|
|
|
|
|
* @param cb 执行的函数
|
|
|
|
|
*/
|
|
|
|
|
export function nextFrame(cb: (time: number) => void) {
|
|
|
|
|
requestAnimationFrame(() => {
|
|
|
|
|
requestAnimationFrame(cb);
|
|
|
|
|
});
|
|
|
|
|
}
|
2023-01-23 14:38:50 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载一个画布对应的图片
|
|
|
|
|
* @param canvas 画布
|
|
|
|
|
* @param name 图片名称
|
|
|
|
|
*/
|
|
|
|
|
export function downloadCanvasImage(
|
|
|
|
|
canvas: HTMLCanvasElement,
|
|
|
|
|
name: string
|
|
|
|
|
): void {
|
|
|
|
|
const data = canvas.toDataURL('image/png');
|
|
|
|
|
download(data, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载一个文件
|
|
|
|
|
* @param content 下载的内容
|
|
|
|
|
* @param name 文件名称
|
|
|
|
|
*/
|
|
|
|
|
export function download(content: string, name: string) {
|
|
|
|
|
const a = document.createElement('a');
|
|
|
|
|
a.download = `${name}.png`;
|
|
|
|
|
a.href = content;
|
|
|
|
|
document.body.appendChild(a);
|
|
|
|
|
a.click();
|
|
|
|
|
document.body.removeChild(a);
|
|
|
|
|
}
|