Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e77a256
feat: add ebg fading
HardyNLee Dec 29, 2025
122f22c
fix: set logo background opaque when fade in
ChangeSuger Jan 3, 2026
f7fc5e0
feat: preload template style files
HardyNLee Jan 4, 2026
0547dc5
refactor: use promise all to load style files
HardyNLee Jan 5, 2026
9b24bb6
Merge pull request #824 from ChangeSuger/fix/logo
MakinoharaShoko Jan 5, 2026
17d43f2
lint and add a todo check
MakinoharaShoko Jan 5, 2026
0162551
Merge pull request #825 from HardyNLee/feat/preload-style
MakinoharaShoko Jan 5, 2026
75f9683
Merge pull request #818 from HardyNLee/feat/ebg-fading
MakinoharaShoko Jan 5, 2026
903e316
feat: support conditional logic for string in -when command
ChangeSuger Jan 6, 2026
e591cd9
add a trim to var name
MakinoharaShoko Jan 7, 2026
65dd43e
Merge pull request #826 from ChangeSuger/feat/when-enhance
MakinoharaShoko Jan 7, 2026
f147480
fix: 修复 changeBg 与 changeFigure 的 exit 设置不能正常生效的问题
ChangeSuger Jan 11, 2026
3f1611b
feat: 应用退出动画后删除退出动画设定;立绘关闭时不设定动画
MakinoharaShoko Jan 14, 2026
f61529d
fix: init config data when clear all data
ChangeSuger Jan 14, 2026
520d054
Update packages/webgal/src/store/userDataReducer.ts
ChangeSuger Jan 14, 2026
9d0a964
Merge pull request #827 from ChangeSuger/fix/exit-animation
MakinoharaShoko Jan 17, 2026
b7382cf
feat: use global store to storage game config init
ChangeSuger Jan 17, 2026
6456087
fix: sentence save end-of-line comment
xiaoxustudio Jan 18, 2026
a42e102
fix: resume alpha filter
HardyNLee Jan 15, 2026
3ce6e38
chore: write to variable
xiaoxustudio Jan 18, 2026
f159ed6
Merge pull request #832 from HardyNLee/fix/resume-alpha-filter
MakinoharaShoko Jan 18, 2026
c6c6663
Merge pull request #828 from ChangeSuger/fix/config-data-clear
MakinoharaShoko Jan 18, 2026
2441914
Merge pull request #834 from xiaoxustudio/fix/sentence-line-comment
MakinoharaShoko Jan 18, 2026
b76453d
feat: preserve inline comment in ISentence
HardyNLee Jan 20, 2026
2d9495b
fix: update appreciation data properly
HardyNLee Jan 20, 2026
0319b8d
Merge pull request #836 from HardyNLee/feat/parser-inline-comment
MakinoharaShoko Jan 20, 2026
7bcbd5d
update parser version
MakinoharaShoko Jan 20, 2026
298dead
fix: failed to modify source transform
HardyNLee Jan 20, 2026
5d963eb
Merge pull request #838 from HardyNLee/fix/read-only-source
MakinoharaShoko Jan 25, 2026
624db78
feat: add blend mode argument
HardyNLee Jan 25, 2026
0e108a9
fix: ensure live2d blink focus in state is full
HardyNLee Jan 26, 2026
ee8c6fe
Merge pull request #844 from HardyNLee/feat/figure-blend-mode
MakinoharaShoko Jan 27, 2026
b543d54
Merge pull request #839 from HardyNLee/fix/appreciation-data
MakinoharaShoko Jan 31, 2026
d0bfe83
Merge pull request #845 from HardyNLee/fix/full-blink-focus
MakinoharaShoko Jan 31, 2026
e0ab2e4
fix: voice volume #843
MakinoharaShoko Jan 31, 2026
92f7543
Merge pull request #850 from OpenWebGAL/fix-say-volume
MakinoharaShoko Feb 1, 2026
c251412
feat: 添加引擎描述文件和版本自动同步机制
A-kirami Feb 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/parser/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webgal-parser",
"version": "4.5.17",
"version": "4.5.18",
"description": "WebGAL script parser",
"scripts": {
"test": "vitest",
Expand Down
1 change: 1 addition & 0 deletions packages/parser/src/interface/sceneInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export interface ISentence {
args: Array<arg>; // 参数列表
sentenceAssets: Array<IAsset>; // 语句携带的资源列表
subScene: Array<string>; // 语句包含子场景列表
inlineComment: string; // 行内注释
}

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/parser/src/scriptParser/scriptParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const scriptParser = (
args: [{ key: 'next', value: true }], // 参数列表
sentenceAssets: [], // 语句携带的资源列表
subScene: [], // 语句携带的子场景
inlineComment: '', // 行内注释
};
}
// 截取命令
Expand Down Expand Up @@ -102,6 +103,7 @@ export const scriptParser = (
args.push(e);
}
}

content = contentParser(newSentenceRaw.trim(), command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
sentenceAssets = assetsScanner(command, content, args); // 扫描语句携带资源
subScene = subSceneScanner(command, content); // 扫描语句携带子场景
Expand All @@ -112,5 +114,6 @@ export const scriptParser = (
args: args, // 参数列表
sentenceAssets: sentenceAssets, // 语句携带的资源列表
subScene: subScene, // 语句携带的子场景
inlineComment: sentenceComment.trim(), // 行内注释
};
};
22 changes: 21 additions & 1 deletion packages/webgal/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
<link rel="manifest" href="/manifest.json" />
<title>WebGAL</title>
<style>
body {
background: black;
}

.html-body__effect-background {
height: 100vh;
width: 100vw;
Expand All @@ -17,6 +21,20 @@
position: absolute;
top: 0;
left: 0;
background-color: black;
}

.html-body__effect-background-overlay {
height: 100%;
width: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: absolute;
top: 0;
left: 0;
background-color: black;
opacity: 0;
}

.html-body__title-enter {
Expand Down Expand Up @@ -115,7 +133,9 @@
</head>
<body>
<!-- 背景模糊 -->
<div class="html-body__effect-background"></div>
<div id="ebg" class="html-body__effect-background">
<div id="ebgOverlay" class="html-body__effect-background-overlay"></div>
</div>
<!-- 落地页 -->
<div class="html-body__title-enter">
<div class="title-enter__initial-background"></div>
Expand Down
2 changes: 1 addition & 1 deletion packages/webgal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "4.5.17",
"scripts": {
"dev": "vite --host --port 3000",
"build": "cross-env NODE_ENV=production tsc && vite build --base=./",
"build": "node scripts/update-engine-version.js && cross-env NODE_ENV=production tsc && vite build --base=./",
"preview": "vite preview",
"lint": "eslint src/** --fix",
"prepublishOnly": "npm run build"
Expand Down
25 changes: 25 additions & 0 deletions packages/webgal/public/webgal-engine.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "WebGAL",
"version": "4.5.17",
"type": "official",
"webgalVersion": "4.5.17",
"description": "界面美观、功能强大、易于开发的全新网页端视觉小说引擎",
"descriptions": {
"en": "A brand new web Visual Novel engine with a beautiful interface, powerful features, and easy development",
"ja": "美しいインターフェース、強力な機能、簡単な開発を備えた全く新しいウェブビジュアルノベルエンジン"
},
"author": {
"name": "Mahiru",
"email": "[email protected]"
},
"license": "MPL-2.0",
"icon": "icons/icon-512.png",
"urls": {
"homepage": "https://openwebgal.com",
"repository": "https://github.com/OpenWebGAL/WebGAL",
"bugs": "https://github.com/OpenWebGAL/WebGAL/issues",
"documentation": "https://docs.openwebgal.com",
"demo": "https://demo.openwebgal.com",
"discord": "https://discord.gg/kPrQkJttJy"
}
}
42 changes: 42 additions & 0 deletions packages/webgal/scripts/update-engine-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env node

/**
* 自动更新 webgal-engine.json 中的版本号
* 从 package.json 读取版本号并同步到 webgal-engine.json
*/

const fs = require('fs');
const path = require('path');

// 文件路径
const packageJsonPath = path.resolve(__dirname, '../package.json');
const engineJsonPath = path.resolve(__dirname, '../public/webgal-engine.json');

try {
// 读取 package.json
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
const version = packageJson.version;

if (!version) {
console.error('❌ 错误: package.json 中未找到版本号');
process.exit(1);
}

// 读取 webgal-engine.json
const engineJson = JSON.parse(fs.readFileSync(engineJsonPath, 'utf-8'));

// 更新版本号
const oldVersion = engineJson.version;
engineJson.version = version;
engineJson.webgalVersion = version;

// 写回文件(保持格式化)
fs.writeFileSync(engineJsonPath, JSON.stringify(engineJson, null, 2) + '\n', 'utf-8');

console.log('✅ 成功更新引擎描述文件版本号');
console.log(` ${oldVersion} → ${version}`);
console.log(` 文件: ${path.relative(process.cwd(), engineJsonPath)}`);
} catch (error) {
console.error('❌ 更新版本号失败:', error.message);
process.exit(1);
}
12 changes: 8 additions & 4 deletions packages/webgal/src/Core/Modules/animationFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
DEFAULT_FIG_IN_DURATION,
DEFAULT_FIG_OUT_DURATION,
} from '../constants';
import { stageActions } from '@/store/stageReducer';

// eslint-disable-next-line max-params
export function getAnimationObject(animationName: string, target: string, duration: number, writeDefault: boolean) {
Expand All @@ -28,7 +29,7 @@ export function getAnimationObject(animationName: string, target: string, durati
newEffect = cloneDeep({ ...baseTransform, duration: 0, ease: '' });
}

PixiStage.assignTransform(newEffect, effect);
PixiStage.assignTransform(newEffect, effect, false);
newEffect.duration = effect.duration;
newEffect.ease = effect.ease;
return newEffect;
Expand Down Expand Up @@ -91,17 +92,20 @@ export function getEnterExitAnimation(
duration = DEFAULT_BG_OUT_DURATION;
}
duration =
webgalStore.getState().stage.animationSettings.find((setting) => setting.target + '-off' === target)
?.exitDuration ?? duration;
webgalStore.getState().stage.animationSettings.find((setting) => setting.target === target)?.exitDuration ??
duration;
// 走默认动画
let animation: IAnimationObject | null = generateUniversalSoftOffAnimationObj(realTarget ?? target, duration);
const animationName = webgalStore
.getState()
.stage.animationSettings.find((setting) => setting.target + '-off' === target)?.exitAnimationName;
.stage.animationSettings.find((setting) => setting.target === target)?.exitAnimationName;
if (animationName) {
logger.debug('取代默认退出动画', target);
animation = getAnimationObject(animationName, realTarget ?? target, getAnimateDuration(animationName), false);
duration = getAnimateDuration(animationName);
// 退出动画拿完后,删了这个设定
webgalStore.dispatch(stageActions.removeAnimationSettingsByTargetOff(target));
logger.debug('删除退出动画设定', target);
}
return { duration, animation };
}
Expand Down
1 change: 1 addition & 0 deletions packages/webgal/src/Core/Modules/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class Events {
public userInteractNext = formEvent('__NEXT');
public fullscreenDbClick = formEvent('fullscreen-dbclick');
public styleUpdate = formEvent('style-update');
public afterStyleUpdate = formEvent('after-style-update');
}

const eventBus = mitt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ export const whenChecker = (whenValue: string | undefined): boolean => {
// 先把变量解析出来
const valExpArr = whenValue.split(/([+\-*\/()><!]|>=|<=|==|&&|\|\||!=)/g);
const valExp = valExpArr
.map((e) => {
.map((_e) => {
const e = _e.trim();
if (e.match(/[a-zA-Z]/)) {
if (e.match(/true/) || e.match(/false/)) {
if (e.match(/^(true|false)$/)) {
return e;
}
return getValueFromStateElseKey(e, true);
return getValueFromStateElseKey(e, true, true);
} else return e;
})
.reduce((pre, curr) => pre + curr, '');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export interface ISentence {
args: Array<arg>; // 参数列表
sentenceAssets: Array<IAsset>; // 语句携带的资源列表
subScene: Array<string>; // 语句包含子场景列表
inlineComment: string; // 行内注释
}

/**
Expand Down
15 changes: 14 additions & 1 deletion packages/webgal/src/Core/controller/stage/pixi/PixiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ window.PIXI = PIXI;
INSTALLED.push(GifResource);

export default class PixiStage {
public static assignTransform<T extends ITransform>(target: T, source?: ITransform) {
public static assignTransform<T extends ITransform>(target: T, source?: ITransform, convertAlpha = true) {
if (!source) return;
const targetScale = target.scale;
const targetPosition = target.position;
Expand All @@ -76,6 +76,13 @@ export default class PixiStage {
Object.assign(target, source);
target.scale = targetScale;
target.position = targetPosition;
if (convertAlpha) {
const sourceAlpha = source.alpha;
if (sourceAlpha !== undefined) {
target.alpha = 1;
(target as any).alphaFilterVal = sourceAlpha;
}
}
}

/**
Expand Down Expand Up @@ -561,6 +568,9 @@ export default class PixiStage {
if (metadata.zIndex) {
thisFigureContainer.zIndex = metadata.zIndex;
}
if (metadata.blendMode) {
thisFigureContainer.blendMode = metadata.blendMode;
}
}
// 挂载
this.figureContainer.addChild(thisFigureContainer);
Expand Down Expand Up @@ -657,6 +667,9 @@ export default class PixiStage {
if (metadata.zIndex) {
thisFigureContainer.zIndex = metadata.zIndex;
}
if (metadata.blendMode) {
thisFigureContainer.blendMode = metadata.blendMode;
}
}
// 挂载
this.figureContainer.addChild(thisFigureContainer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { BevelFilter } from '@/Core/controller/stage/pixi/shaders/BevelFilter';
import * as PIXI from 'pixi.js';
import { BlurFilter } from '@pixi/filter-blur';
import { INIT_RAD, RadiusAlphaFilter } from '@/Core/controller/stage/pixi/shaders/RadiusAlphaFilter';
import { logger } from '@/Core/util/logger';

/**
* Filter configuration for creation and default state detection.
Expand Down Expand Up @@ -333,11 +334,54 @@ export class WebGALPixiContainer extends PIXI.Container {

private baseX = 0;
private baseY = 0;
private alphaFilter = new PIXI.filters.AlphaFilter(1);

public constructor() {
super();
this.addInternalFilterInstance(this.alphaFilter);
}

public get alphaFilterVal(): number {
return this.alphaFilter.alpha;
}
public set alphaFilterVal(v: number) {
this.alphaFilter.alpha = v;
}

public get blendMode(): string {
switch (this.alphaFilter.blendMode) {
case PIXI.BLEND_MODES.NORMAL:
return 'normal';
case PIXI.BLEND_MODES.ADD:
return 'add';
case PIXI.BLEND_MODES.MULTIPLY:
return 'multiply';
case PIXI.BLEND_MODES.SCREEN:
return 'screen';
default:
logger.warn(`Unknown blend mode: ${this.alphaFilter.blendMode}, returning normal.`);
return 'normal';
}
}
public set blendMode(v: string) {
switch (v) {
case 'normal':
this.alphaFilter.blendMode = PIXI.BLEND_MODES.NORMAL;
break;
case 'add':
this.alphaFilter.blendMode = PIXI.BLEND_MODES.ADD;
break;
case 'multiply':
this.alphaFilter.blendMode = PIXI.BLEND_MODES.MULTIPLY;
break;
case 'screen':
this.alphaFilter.blendMode = PIXI.BLEND_MODES.SCREEN;
break;
default:
logger.warn(`Unknown blend mode: ${v}, setting to normal.`);
this.alphaFilter.blendMode = PIXI.BLEND_MODES.NORMAL;
}
}
public removeFilterByName(filterName: string) {
const filter = this.containerFilters.get(filterName);
if (!filter || !this.filters) return;
Expand Down Expand Up @@ -622,6 +666,10 @@ export class WebGALPixiContainer extends PIXI.Container {
let insertIndex = this.filters.length;
for (let i = 0; i < this.filters.length; i++) {
const currentFilter = this.filters[i]!;
if (currentFilter === this.alphaFilter) {
insertIndex = i;
break;
}
const currentName = this.filterToName.get(currentFilter);
if (currentName) {
const currentPriority = FILTER_CONFIGS[currentName]?.priority ?? 0;
Expand Down Expand Up @@ -651,4 +699,12 @@ export class WebGALPixiContainer extends PIXI.Container {
this.insertFilterWithPriority(filterName, inst);
return inst;
}

private addInternalFilterInstance(filter: PIXI.Filter): void {
if (!this.filters) {
this.filters = [filter];
} else {
this.filters.push(filter);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ export function generateTimelineObj(
targetKey: string,
duration: number,
): IAnimationObject {
for (const segment of timeline) {
// Alpha 现在直接使用原生属性,无需转换为 alphaFilterVal
}
const target = WebGAL.gameplay.pixiStage!.getStageObjByKey(targetKey);
let currentDelay = 0;
const values = [];
Expand Down
Loading