refactor: 继续删除一些无用的东西

This commit is contained in:
unanmed 2024-10-04 12:06:43 +08:00
parent ecfc042688
commit fe1579e1dc
6 changed files with 2 additions and 568 deletions

View File

@ -1,496 +0,0 @@
import {
TimingFn,
linear,
bezierPath,
Animation,
hyper,
power,
sleep
} from 'mutate-animate';
import { has } from '../utils';
interface AnimatedPathShadow {
offsetX: number | TimingFn;
offsetY: number | TimingFn;
blur: number | TimingFn;
color: string | TimingFn<4>;
}
type AnimatedPathShadowEntry = [
keyof AnimatedPathShadow,
ValueOf<AnimatedPathShadow>
][];
type AnimatedPathFilterKey =
| 'blur'
| 'brightness'
| 'contrast'
| 'grayscale'
| 'hueRotate'
| 'opacity'
| 'saturate'
| 'sepia';
type AnimatedPathFilter = Record<AnimatedPathFilterKey, number | TimingFn>;
interface Path {
path: TimingFn<2>;
length: number;
}
export default function init() {
return { AnimatedPath, pathTest: test };
}
export class AnimatedPath {
/** 不同线条间是否连接起来,不连接的话中间可能会有短暂的中断 */
join: boolean = true;
/** 路径信息 */
linePath: Path[] = [];
/** 绘制画布 */
ctx: CanvasRenderingContext2D;
private dashStatus: number = 0;
private dashLength: number = 0;
private dashMode: (number | TimingFn)[] = [];
private lineWidth: number | TimingFn = 1;
private lineColor: string | TimingFn<4> = '#fff';
private lineShadow: Partial<AnimatedPathShadow> = {};
private lineFilter: Partial<AnimatedPathFilter> = {};
private pathClose: boolean = false;
constructor(ctx: CanvasRenderingContext2D) {
this.ctx = ctx;
}
/**
* 线
* @param mode 线
*
* input线
* @example path.dash([5, 10]); // 表示绘制时会先绘制5像素的实线之后10像素不绘制然后再绘制5像素实线以此类推。
* @example path.dash([5, (input) => Math.round(input * 10)]);
* // 表示绘制时先绘制5像素的实线然后会有一段不绘制不绘制的长度是动画完成度乘10以此类推。
*/
dash(mode: (number | TimingFn)[]): this {
const res = mode.slice();
if (mode.length % 2 === 1) res.push(...mode);
this.dashMode = mode;
return this;
}
/**
* 线
* @param width 线
* input
* @example path.width(2); // 设置线条宽度为2像素
* @example path.width((input) => input * 5); // 设置线条宽度为动画完成度的5倍
*/
width(width: number | TimingFn): this {
this.lineWidth = width;
return this;
}
/**
* 线
* @param color css颜色字符串或函数线
* input4rgba值
* @example path.color('#fff'); // 设置线条为白色
* @example path.color((input) => [input * 100, input * 50, input * 255, input * 0.8]);
* // 设置颜色的红色值为动画完成度的100倍绿色为动画完成度的50倍蓝色为动画完成度的255倍不透明度为动画完成度的0.8倍
*/
color(color: string | TimingFn<4>): this {
this.lineColor = color;
return this;
}
/**
* 线
* @param shadow offsetX(), offsetY(), blur(), color()
* color可传入字符串或函数
* ```ts
* path.shadow({
* offsetX: 3, // 横向偏移量为3
* offsetY: input => input * 10, // 纵向偏移量为动画完成度的10倍
* color: '#0008', // 颜色为半透明的黑色
* blur: 4 // 虚化程度为4
* })
* ```
*/
shadow(shadow: Partial<AnimatedPathShadow>): this {
this.lineShadow = shadow;
return this;
}
/**
* 线
* @param filter
* 1. `blur`:
* 2. `brightness`: `0-Infinity`
* 3. `contrast`: `0-Infinity`
* 4. `grayscale`: `0-100`
* 5. `hueRotate`: `0-360`
* 6. `invert`: `0-100`
* 7. `opacity`: `0-100`
* 8. `saturate`: `0-Infinity`
* 9. `sepia`: (怀)`0-100`
*
* ```ts
* path.filter({
* blur: 3, // 虚化程度为3
* contrast: input => 100 + input * 50 // 对比度增加动画完成度的50倍
* })
* ```
*/
filter(filter: Partial<AnimatedPathFilter>): this {
this.lineFilter = filter;
return this;
}
/**
*
*/
clear(): this {
this.linePath = [];
return this;
}
/**
* 线
* @param x1
* @param y1
* @param x2
* @param y2
* @returns
*/
line(x1: number, y1: number, x2: number, y2: number): this {
const dx = x2 - x1;
const dy = y2 - y1;
this.add(x => [x1 + dx * x, y1 + dy * x], Math.sqrt(dx ** 2 + dy ** 2));
return this;
}
/**
*
* @param x
* @param y
* @param r
* @param start 0
* @param end
*/
circle(x: number, y: number, r: number, start: number, end: number): this {
const dt = end - start;
this.add(
input => [
x + r * Math.cos(dt * input + start),
y + r * Math.sin(dt * input + start)
],
r * dt
);
return this;
}
/**
*
* @param x
* @param y
* @param a
* @param b
* @param start
* @param end
*/
ellipse(
x: number,
y: number,
a: number,
b: number,
start: number,
end: number
): this {
const dt = end - start;
this.add(input => [
x + a * Math.cos(dt * input + start),
y + b * Math.sin(dt * input + start)
]);
return this;
}
/**
*
* @param x
* @param y
* @param w
* @param h
* @param lineWidth 线
*/
rect(
x: number,
y: number,
w: number,
h: number,
lineWidth: number = 0
): this {
const x2 = x + w;
const y2 = y + h;
this.line(x, y, x2, y)
.line(x2, y, x2, y2)
.line(x2, y2, x, y2)
.line(x, y2, x, y - lineWidth / 2);
return this;
}
/**
* 线
* @param point
*/
bezier(...point: [number, number][]): this {
if (point.length < 2) {
throw new Error(`The point number of bezier must larger than 2.`);
}
const start = point[0];
const end = point.at(-1)!;
const cps = point.slice(1, -1);
this.add(bezierPath(start, end, ...cps));
return this;
}
/**
*
* @param path
* @param length calLength进行计算
*
* @example path.add(input => [input * 100, (input * 100) ** 2]); // 添加一个抛物线路径
*/
add(path: TimingFn<2>, length: number = this.calLength(path)): this {
this.linePath.push({
path,
length
});
return this;
}
/**
*
* @param close
*/
close(close: boolean): this {
this.pathClose = close;
return this;
}
/**
* 线使
* @param path
* @returns
*/
calLength(path: TimingFn<2>): number {
let [lastX, lastY] = path(0);
let length = 0;
for (let i = 1; i <= 1000; i++) {
const [x, y] = path(i * 0.001);
length += Math.sqrt((x - lastX) ** 2 + (y - lastY) ** 2);
lastX = x;
lastY = y;
}
return length;
}
/**
* 使
*/
drawImmediate(): this {
const totalLength = this.linePath.reduce(
(pre, cur) => pre + cur.length,
0
);
let drawed = 0;
this.linePath.forEach(v => {
this.drawFrom(v.path, 0, 1, drawed, v.length);
drawed += v.length / totalLength;
});
return this;
}
/**
*
* @param time 0drawImmediate函数齿
* @param timing
*/
draw(time: number, timing: TimingFn = linear()): this {
const totalLength = this.linePath.reduce(
(pre, cur) => pre + cur.length,
0
);
const ratio = this.linePath.map(v => v.length / totalLength);
let drawed = 0;
let now = 0;
let nowEnd = ratio[0];
let lastComplete = 0;
this.ctx.beginPath();
this.ctx.moveTo(...this.linePath[0].path(0));
const findNext = (input: number) => {
if (input >= 1 || nowEnd > input) return [];
const skipped: number[] = [];
while (1) {
drawed += ratio[now];
now++;
nowEnd += ratio[now];
if (input < nowEnd) {
lastComplete = drawed;
break;
} else skipped.push(now);
}
return skipped;
};
const ani = new Animation();
ani.register('path', 0);
ani.mode(timing).time(time).absolute().apply('path', 1);
ani.all().then(() => {
ani.ticker.destroy();
if (this.pathClose) {
this.ctx.beginPath();
this.ctx.moveTo(...this.linePath.at(-1)!.path(0.999));
this.ctx.lineTo(...this.linePath[0].path(0.001));
this.ctx.stroke();
}
this.ctx.closePath();
});
ani.ticker.add(() => {
const complete = ani.value.path;
if (complete >= nowEnd) {
const d = nowEnd - drawed;
const from = (lastComplete - drawed) / d;
this.drawFrom(
this.linePath[now].path,
from,
1,
lastComplete,
ratio[now]
);
const skipped = findNext(complete);
skipped.forEach(v => {
const path = this.linePath[v];
this.drawFrom(path.path, 0, 1, lastComplete, ratio[v]);
});
}
const fn = this.linePath[now].path;
const d = nowEnd - drawed;
const from = (lastComplete - drawed) / d;
const to = (complete - drawed) / d;
this.drawFrom(fn, from, to, lastComplete, ratio[now]);
lastComplete = complete;
});
return this;
}
private drawFrom(
path: TimingFn<2>,
from: number,
to: number,
complete: number,
ratio: number,
length?: number
) {
const [fx, fy] = path(from);
const [tx, ty] = path(to);
const l =
length ?? Math.ceil(Math.sqrt((tx - fx) ** 2 + (ty - fy) ** 2));
const step = (to - from) / l;
const ctx = this.ctx;
let [lastX, lastY] = path(from);
for (let i = 1; i <= l; i++) {
this.handleFx(complete + (ratio * i * step) / l);
const [x, y] = path(from + step * i);
ctx.lineTo(x, y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
lastX = x;
lastY = y;
}
}
private handleFx(complete: number) {
const ctx = this.ctx;
const width =
typeof this.lineWidth === 'number'
? this.lineWidth
: this.lineWidth(complete);
ctx.lineWidth = width;
let color;
if (typeof this.lineColor === 'string') {
color = this.lineColor;
} else {
const c = this.lineColor(complete);
color = `rgba(${c[0]},${c[1]},${c[2]},${c[3]})`;
}
ctx.strokeStyle = color;
const shadow: Partial<
Record<keyof AnimatedPathShadow, string | number>
> = {};
for (const [key, value] of Object.entries(
this.lineShadow
) as AnimatedPathShadowEntry) {
if (typeof value === 'function') {
const n = value(complete);
if (typeof n === 'number') {
shadow[key as Exclude<keyof AnimatedPathShadow, 'color'>] =
n;
} else {
shadow.color = `rgba(${n[0]},${n[1]},${n[2]},${n[3]})`;
}
} else {
// @ts-ignore
shadow[key] = value;
}
}
if (has(shadow.blur)) ctx.shadowBlur = shadow.blur as number;
if (has(shadow.offsetX)) ctx.shadowOffsetX = shadow.offsetX as number;
if (has(shadow.offsetY)) ctx.shadowOffsetY = shadow.offsetY as number;
if (has(shadow.color)) ctx.shadowColor = shadow.color as string;
let filter = '';
for (const [key, value] of Object.entries(this.lineFilter) as [
AnimatedPathFilterKey,
number | TimingFn
][]) {
let v;
if (typeof value === 'number') {
v = value;
} else {
v = value(complete);
}
if (key === 'blur') filter += `blur(${v}px)`;
else filter += `${key}(${v}%)`;
}
ctx.filter = filter;
}
}
async function test() {
const ctx = core.createCanvas('test', 0, 0, 480, 480, 100);
ctx.canvas.style.backgroundColor = '#000d';
const path = new AnimatedPath(ctx);
path.color('#fff')
.width(2)
.rect(100, 100, 280, 280, 2)
.close(true)
.draw(1000, power(5, 'in-out'));
await sleep(1050);
path.clear()
.bezier([200, 200], [280, 200], [280, 280])
.bezier([280, 280], [200, 280], [200, 200])
.draw(1000, power(5, 'in-out'));
await sleep(1050);
path.clear()
.bezier([280, 200], [200, 200], [200, 280])
.bezier([200, 280], [280, 280], [280, 200])
.draw(1000, power(5, 'in-out'));
}

View File

@ -1,5 +1,5 @@
import { EnemyCollection, ensureFloorDamage } from '@/game/enemy/damage'; import { EnemyCollection, ensureFloorDamage } from '@/game/enemy/damage';
import { checkV2, formatDamage } from '../utils'; import { formatDamage } from '../utils';
export function init() { export function init() {
core.control.updateDamage = function ( core.control.updateDamage = function (

View File

@ -1,61 +0,0 @@
import { getEnemy } from '@/game/enemy/battle';
import { formatDamage } from '../utils';
export function init() {
core.maps._initDetachedBlock = function (
info: BlockInfo,
x: number,
y: number,
displayDamage: boolean = false
) {
let headCanvas = null,
bodyCanvas = '__body_' + x + '_' + y,
damageCanvas = null;
// head
if (!info.bigImage && info.height > 32) {
headCanvas = '__head_' + x + '_' + y;
core.createCanvas(headCanvas, 0, 0, 32, info.height - 32, 55);
}
// body
if (info.bigImage) {
var bigImageInfo = this._getBigImageInfo(
info.bigImage,
info.face,
info.posX
);
const { per_width, per_height } = bigImageInfo;
core.createCanvas(bodyCanvas, 0, 0, per_width, per_height, 35);
} else {
core.createCanvas(bodyCanvas, 0, 0, 32, 32, 35);
}
// 伤害
if (
info.cls.indexOf('enemy') == 0 &&
core.hasItem('book') &&
displayDamage
) {
const enemy = getEnemy(x, y);
const dam = enemy?.calDamage() ?? { damage: 0 };
const { damage, color } = formatDamage(dam.damage);
damageCanvas = '__damage_' + x + '_' + y;
const ctx = core.createCanvas(damageCanvas, 0, 0, 32, 32, 65);
ctx.textAlign = 'left';
ctx.font = '14px normal';
core.fillBoldText(ctx, damage, 1, 31, color as string);
if (core.flags.displayCritical) {
const critical = enemy?.calCritical(1) ?? [];
const atk = core.formatBigNumber(critical[0]?.delta, true);
const display = atk === '???' ? '?' : atk;
core.fillBoldText(ctx, display, 1, 21, '#FFFFFF');
}
}
return {
headCanvas,
bodyCanvas,
damageCanvas
};
};
}

View File

@ -3,7 +3,6 @@ import * as fiveLayer from './fiveLayer';
import * as itemDetail from './fx/itemDetail'; import * as itemDetail from './fx/itemDetail';
import * as replay from './replay'; import * as replay from './replay';
import * as ui from './ui'; import * as ui from './ui';
import * as rewrite from './fx/rewrite';
import * as loopMap from './loopMap'; import * as loopMap from './loopMap';
import * as removeMap from './removeMap'; import * as removeMap from './removeMap';
import * as shop from './shop'; import * as shop from './shop';
@ -27,7 +26,6 @@ Mota.Plugin.register('chase_g', chase);
Mota.Plugin.register('skill_g', skill); Mota.Plugin.register('skill_g', skill);
Mota.Plugin.register('towerBoss_g', towerBoss); Mota.Plugin.register('towerBoss_g', towerBoss);
Mota.Plugin.register('fiveLayer_g', fiveLayer, fiveLayer.init); Mota.Plugin.register('fiveLayer_g', fiveLayer, fiveLayer.init);
Mota.Plugin.register('rewrite_g', rewrite, rewrite.init);
Mota.Plugin.register('itemDetail_g', itemDetail, itemDetail.init); Mota.Plugin.register('itemDetail_g', itemDetail, itemDetail.init);
// Mota.Plugin.register('study_g', study); // Mota.Plugin.register('study_g', study);
Mota.Plugin.register('remainEnemy_g', remainEnemy); Mota.Plugin.register('remainEnemy_g', remainEnemy);

View File

@ -6,7 +6,6 @@ import { Ref, ref } from 'vue';
import { EVENT_KEY_CODE_MAP, KeyCode } from './keyCodes'; import { EVENT_KEY_CODE_MAP, KeyCode } from './keyCodes';
import axios from 'axios'; import axios from 'axios';
import { decompressFromBase64 } from 'lz-string'; import { decompressFromBase64 } from 'lz-string';
import { parseColor } from './webgl/utils';
import { Keyboard, KeyboardEmits } from '@/core/main/custom/keyboard'; import { Keyboard, KeyboardEmits } from '@/core/main/custom/keyboard';
import { fixedUi, mainUi } from '@/core/main/init/ui'; import { fixedUi, mainUi } from '@/core/main/init/ui';
import { isAssist } from '@/core/main/custom/hotkey'; import { isAssist } from '@/core/main/custom/hotkey';
@ -341,12 +340,6 @@ export function ensureArray<T>(arr: T): T extends any[] ? T : T[] {
return arr instanceof Array ? arr : [arr]; return arr instanceof Array ? arr : [arr];
} }
export function pColor(color: string) {
const arr = parseColor(color);
arr[3] ??= 1;
return `rgba(${arr.join(',')})` as Color;
}
/** /**
* *
* @param arr * @param arr

View File

@ -7,5 +7,5 @@
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"strict": true "strict": true
}, },
"include": ["vite.config.ts", "script/**/*.ts"] "include": ["vite.config.ts", "script/**/*.ts", "mota.config.ts"]
} }