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 { LayerGroupHalo } from '@/plugin/fx/halo';
|
||||||
import { FloorViewport } from './preset/viewport';
|
import { FloorViewport } from './preset/viewport';
|
||||||
import { Container } from './container';
|
import { Container } from './container';
|
||||||
|
import { PopText } from '@/plugin/fx/pop';
|
||||||
|
|
||||||
let main: MotaRenderer;
|
let main: MotaRenderer;
|
||||||
|
|
||||||
@ -22,13 +23,16 @@ Mota.require('var', 'loading').once('coreInit', () => {
|
|||||||
|
|
||||||
const mapDraw = new Container();
|
const mapDraw = new Container();
|
||||||
const layer = new LayerGroup();
|
const layer = new LayerGroup();
|
||||||
|
const pop = new PopText('static');
|
||||||
mapDraw.id = 'map-draw';
|
mapDraw.id = 'map-draw';
|
||||||
layer.id = 'layer-main';
|
layer.id = 'layer-main';
|
||||||
|
pop.id = 'pop-main';
|
||||||
|
|
||||||
mapDraw.setHD(true);
|
mapDraw.setHD(true);
|
||||||
mapDraw.setAntiAliasing(false);
|
mapDraw.setAntiAliasing(false);
|
||||||
mapDraw.size(core._PX_, core._PY_);
|
mapDraw.size(core._PX_, core._PY_);
|
||||||
|
|
||||||
|
pop.setZIndex(80);
|
||||||
['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => {
|
['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => {
|
||||||
layer.addLayer(v as FloorLayer);
|
layer.addLayer(v as FloorLayer);
|
||||||
});
|
});
|
||||||
@ -56,6 +60,7 @@ Mota.require('var', 'loading').once('coreInit', () => {
|
|||||||
|
|
||||||
render.appendChild(mapDraw);
|
render.appendChild(mapDraw);
|
||||||
mapDraw.appendChild(layer);
|
mapDraw.appendChild(layer);
|
||||||
|
layer.appendChild(pop);
|
||||||
console.log(render);
|
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