| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- """把 UI 动效预设编译成 Cocos TypeScript(cc.tween)。
- 纯本地、无需 API。生成一个 TweenPresets.ts,运行时按 presetId 调用即可。
- """
- import os
- PRESETS = {
- "scale_bounce": """ scale_bounce(node: Node, p: any = {}) {
- const s = node.scale.clone();
- return tween(node)
- .to(0.09, { scale: new Vec3(s.x * 0.9, s.y * 0.9, 1) })
- .to(0.12, { scale: new Vec3(s.x * 1.05, s.y * 1.05, 1) }, { easing: 'backOut' })
- .to(0.08, { scale: s });
- }""",
- "elastic_in": """ elastic_in(node: Node, p: any = {}) {
- node.setScale(0, 0, 1);
- const uo = node.getComponent(UIOpacity); if (uo) uo.opacity = 0;
- return tween(node)
- .to(0.4, { scale: new Vec3(1, 1, 1) }, { easing: 'elasticOut' })
- .call(() => { if (uo) uo.opacity = 255; });
- }""",
- "fade_slide_in": """ fade_slide_in(node: Node, p: any = {}) {
- const dy = p.dy ?? 40;
- const end = node.position.clone();
- node.setPosition(end.x, end.y - dy, end.z);
- const uo = node.getComponent(UIOpacity);
- if (uo) { uo.opacity = 0; tween(uo).to(0.3, { opacity: 255 }).start(); }
- return tween(node).to(0.3, { position: end }, { easing: 'cubicOut' });
- }""",
- "number_roll": """ number_roll(node: Node, p: any = {}) {
- const label = node.getComponent(Label)!;
- const from = p.from ?? 0, to = p.to ?? 0, dur = p.dur ?? 0.8;
- const o = { v: from };
- return tween(o).to(dur, { v: to }, {
- easing: 'cubicOut',
- onUpdate: () => { label.string = Math.floor(o.v).toString(); },
- });
- }""",
- "pulse": """ pulse(node: Node, p: any = {}) {
- const s = node.scale.clone();
- return tween(node).repeatForever(
- tween(node)
- .to(0.6, { scale: new Vec3(s.x * 1.06, s.y * 1.06, 1) }, { easing: 'sineInOut' })
- .to(0.6, { scale: s }, { easing: 'sineInOut' })
- );
- }""",
- }
- HEADER = """// 自动生成 by anim_studio —— UI 动效预设库
- // 用法: TweenPresets.play('scale_bounce', node, { ... }).start();
- import { tween, Tween, Node, Vec3, UIOpacity, Label } from 'cc';
- class _TweenPresets {
- play(id: string, node: Node, p: any = {}): Tween<any> {
- const fn = (this as any)[id];
- if (!fn) { console.warn('[TweenPresets] 未知预设: ' + id); return tween(node); }
- return fn.call(this, node, p);
- }
- """
- FOOTER = "}\n\nexport const TweenPresets = new _TweenPresets();\n"
- def build_tweens(used_presets, out_dir):
- """生成 TweenPresets.ts。used_presets 为 manifest 用到的预设名列表(去重)。"""
- # 总是输出全部预设库(多几个不碍事),并校验用到的是否都存在
- missing = [p for p in used_presets if p not in PRESETS]
- body = "\n\n".join(PRESETS[k] for k in PRESETS)
- code = HEADER + "\n" + body + "\n" + FOOTER
- os.makedirs(out_dir, exist_ok=True)
- path = os.path.join(out_dir, "TweenPresets.ts")
- with open(path, "w", encoding="utf-8") as f:
- f.write(code)
- return path, missing
|