mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 12:49:25 +08:00
feat: 文字弹出
This commit is contained in:
parent
597333adf7
commit
ae5a8f6363
@ -11,6 +11,7 @@ import { LayerGroupPortal } from '@/plugin/fx/portal';
|
||||
import { LayerGroupHalo } from '@/plugin/fx/halo';
|
||||
import { FloorViewport } from './preset/viewport';
|
||||
import { Container } from './container';
|
||||
import { PopText } from '@/plugin/fx/pop';
|
||||
|
||||
let main: MotaRenderer;
|
||||
|
||||
@ -22,13 +23,16 @@ Mota.require('var', 'loading').once('coreInit', () => {
|
||||
|
||||
const mapDraw = new Container();
|
||||
const layer = new LayerGroup();
|
||||
const pop = new PopText('static');
|
||||
mapDraw.id = 'map-draw';
|
||||
layer.id = 'layer-main';
|
||||
pop.id = 'pop-main';
|
||||
|
||||
mapDraw.setHD(true);
|
||||
mapDraw.setAntiAliasing(false);
|
||||
mapDraw.size(core._PX_, core._PY_);
|
||||
|
||||
pop.setZIndex(80);
|
||||
['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => {
|
||||
layer.addLayer(v as FloorLayer);
|
||||
});
|
||||
@ -56,6 +60,7 @@ Mota.require('var', 'loading').once('coreInit', () => {
|
||||
|
||||
render.appendChild(mapDraw);
|
||||
mapDraw.appendChild(layer);
|
||||
layer.appendChild(pop);
|
||||
console.log(render);
|
||||
});
|
||||
|
||||
|
96
src/plugin/fx/pop.ts
Normal file
96
src/plugin/fx/pop.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
|
||||
import { RenderItem, RenderItemPosition } from '@/core/render/item';
|
||||
import { Transform } from '@/core/render/transform';
|
||||
import { TimingFn } from 'mutate-animate';
|
||||
|
||||
interface PopData {
|
||||
cx: number;
|
||||
cy: number;
|
||||
path: TimingFn<2>;
|
||||
text: string;
|
||||
time: number;
|
||||
start: number;
|
||||
color: CanvasStyle;
|
||||
}
|
||||
|
||||
function parabola(input: number): [number, number] {
|
||||
const x = input * 100;
|
||||
return [x, x ** 2 / 20 - 3 * x];
|
||||
}
|
||||
|
||||
export class PopText extends RenderItem {
|
||||
private popList: Set<PopData> = new Set();
|
||||
|
||||
private delegation: number = 0;
|
||||
|
||||
constructor(type: RenderItemPosition) {
|
||||
super(type, false);
|
||||
this.delegation = this.delegateTicker(() => {
|
||||
if (this.popList.size > 0) this.update();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个弹出文字
|
||||
* @param text 要显示的文字
|
||||
* @param time 持续时长
|
||||
* @param cx 中心点,也就是从哪弹出的
|
||||
* @param cy 中心点,也就是从哪弹出的
|
||||
* @param path 自定义路径,不填表示默认的抛物线路径
|
||||
*/
|
||||
addPop(
|
||||
text: string,
|
||||
time: number,
|
||||
cx: number,
|
||||
cy: number,
|
||||
color: CanvasStyle,
|
||||
path?: TimingFn<2>
|
||||
) {
|
||||
this.popList.add({
|
||||
text,
|
||||
time,
|
||||
cx,
|
||||
cy,
|
||||
color,
|
||||
path: path ?? parabola,
|
||||
start: Date.now()
|
||||
});
|
||||
this.update();
|
||||
}
|
||||
|
||||
protected render(
|
||||
canvas: MotaOffscreenCanvas2D,
|
||||
transform: Transform
|
||||
): void {
|
||||
const ctx = canvas.ctx;
|
||||
const toDelete = new Set<PopData>();
|
||||
const now = Date.now();
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.font = '22px Verdana';
|
||||
ctx.lineWidth = 3;
|
||||
this.popList.forEach(v => {
|
||||
const { cx, cy, path, text, color, time, start } = v;
|
||||
const dt = now - start;
|
||||
const progress = dt / time;
|
||||
if (progress >= 1) {
|
||||
toDelete.add(v);
|
||||
return;
|
||||
}
|
||||
const [x, y] = path(progress);
|
||||
const dx = cx + x;
|
||||
const dy = cy + y;
|
||||
ctx.globalAlpha = Math.min(1, 2 - progress * 2);
|
||||
ctx.fillStyle = color;
|
||||
ctx.strokeText(text, dx, dy);
|
||||
ctx.fillText(text, dx, dy);
|
||||
});
|
||||
toDelete.forEach(v => {
|
||||
this.popList.delete(v);
|
||||
});
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
super.destroy();
|
||||
this.removeTicker(this.delegation);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user