Skip to content

Commit 65df686

Browse files
Merge pull request #876 from OpenWebGAL/dev
4.5.18
2 parents 23e98d9 + 1826529 commit 65df686

43 files changed

Lines changed: 463 additions & 122 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/pr-check.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ jobs:
2727
- name: Install
2828
run: npm install yarn -g && yarn install
2929

30+
# 运行 parser 测试
31+
- name: Parser Test
32+
run: yarn parser:test --run
33+
3034
# 生成静态文件
3135
- name: Build
3236
run: yarn build && cd ./packages/webgal && touch dist/.nojekyll

packages/parser/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webgal-parser",
3-
"version": "4.5.17",
3+
"version": "4.5.18",
44
"description": "WebGAL script parser",
55
"scripts": {
66
"test": "vitest",

packages/parser/src/interface/sceneInterface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export interface ISentence {
7373
args: Array<arg>; // 参数列表
7474
sentenceAssets: Array<IAsset>; // 语句携带的资源列表
7575
subScene: Array<string>; // 语句包含子场景列表
76+
inlineComment: string; // 行内注释
7677
}
7778

7879
/**

packages/parser/src/scriptParser/scriptParser.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const scriptParser = (
4949
args: [{ key: 'next', value: true }], // 参数列表
5050
sentenceAssets: [], // 语句携带的资源列表
5151
subScene: [], // 语句携带的子场景
52+
inlineComment: '', // 行内注释
5253
};
5354
}
5455
// 截取命令
@@ -102,6 +103,7 @@ export const scriptParser = (
102103
args.push(e);
103104
}
104105
}
106+
105107
content = contentParser(newSentenceRaw.trim(), command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
106108
sentenceAssets = assetsScanner(command, content, args); // 扫描语句携带资源
107109
subScene = subSceneScanner(command, content); // 扫描语句携带子场景
@@ -112,5 +114,6 @@ export const scriptParser = (
112114
args: args, // 参数列表
113115
sentenceAssets: sentenceAssets, // 语句携带的资源列表
114116
subScene: subScene, // 语句携带的子场景
117+
inlineComment: sentenceComment.trim(), // 行内注释
115118
};
116119
};

packages/parser/test/parser.test.ts

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ test("label", async () => {
2424
{ key: "next", value: true }
2525
],
2626
sentenceAssets: [],
27-
subScene: []
27+
subScene: [],
28+
inlineComment: ""
2829
};
2930
expect(result.sentenceList).toContainEqual(expectSentenceItem);
3031
});
@@ -49,7 +50,8 @@ test("args", async () => {
4950
{ key: "next", value: true }
5051
],
5152
sentenceAssets: [{ name: "m2.png", url: 'm2.png', type: fileType.figure, lineNumber: 0 }],
52-
subScene: []
53+
subScene: [],
54+
inlineComment: ""
5355
};
5456
expect(result.sentenceList).toContainEqual(expectSentenceItem);
5557
});
@@ -71,7 +73,8 @@ test("choose", async () => {
7173
content: "",
7274
args: [],
7375
sentenceAssets: [],
74-
subScene: []
76+
subScene: [],
77+
inlineComment: ""
7578
};
7679
expect(result.sentenceList).toContainEqual(expectSentenceItem);
7780
});
@@ -98,7 +101,8 @@ test("long-script", async () => {
98101
{ key: "next", value: true }
99102
],
100103
sentenceAssets: [],
101-
subScene: []
104+
subScene: [],
105+
inlineComment: ""
102106
};
103107
expect(result.sentenceList).toContainEqual(expectSentenceItem);
104108
});
@@ -120,7 +124,8 @@ test("var", async () => {
120124
content: "a=1?",
121125
args: [{ key: 'speaker', value: 'WebGAL' }, { key: 'when', value: "a==1" }],
122126
sentenceAssets: [],
123-
subScene: []
127+
subScene: [],
128+
inlineComment: ""
124129
};
125130
expect(result.sentenceList).toContainEqual(expectSentenceItem);
126131
});
@@ -185,14 +190,16 @@ test("say statement", async () => {
185190
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
186191

187192
const result = parser.parse(`say:123 -speaker=xx;`, 'test', 'test');
188-
expect(result.sentenceList).toContainEqual({
193+
const expectSentenceItem: ISentence = {
189194
command: commandType.say,
190195
commandRaw: "say",
191196
content: "123",
192197
args: [{ key: 'speaker', value: 'xx' }],
193198
sentenceAssets: [],
194-
subScene: []
195-
});
199+
subScene: [],
200+
inlineComment: ""
201+
};
202+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
196203
});
197204

198205
test("wait command", async () => {
@@ -202,14 +209,16 @@ test("wait command", async () => {
202209
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
203210

204211
const result = parser.parse(`wait:1000;`, 'test', 'test');
205-
expect(result.sentenceList).toContainEqual({
212+
const expectSentenceItem: ISentence = {
206213
command: commandType.wait,
207214
commandRaw: "wait",
208215
content: "1000",
209216
args: [],
210217
sentenceAssets: [],
211-
subScene: []
212-
});
218+
subScene: [],
219+
inlineComment: ""
220+
};
221+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
213222
});
214223

215224
test("changeFigure with duration and animation args", async () => {
@@ -219,7 +228,7 @@ test("changeFigure with duration and animation args", async () => {
219228
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
220229

221230
const result = parser.parse(`changeFigure:stand.webp -duration=1000 -enter=fadeIn -exit=fadeOut;`, 'test', 'test');
222-
expect(result.sentenceList).toContainEqual({
231+
const expectSentenceItem: ISentence = {
223232
command: commandType.changeFigure,
224233
commandRaw: "changeFigure",
225234
content: "stand.webp",
@@ -229,8 +238,10 @@ test("changeFigure with duration and animation args", async () => {
229238
{ key: 'exit', value: 'fadeOut' }
230239
],
231240
sentenceAssets: [{ name: "stand.webp", url: 'stand.webp', type: fileType.figure, lineNumber: 0 }],
232-
subScene: []
233-
});
241+
subScene: [],
242+
inlineComment: ""
243+
};
244+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
234245
});
235246

236247
test("changeBg with animation parameters", async () => {
@@ -240,7 +251,7 @@ test("changeBg with animation parameters", async () => {
240251
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
241252

242253
const result = parser.parse(`changeBg:background.jpg -duration=2000 -enter=slideIn -transform={"alpha":0.8};`, 'test', 'test');
243-
expect(result.sentenceList).toContainEqual({
254+
const expectSentenceItem: ISentence = {
244255
command: commandType.changeBg,
245256
commandRaw: "changeBg",
246257
content: "background.jpg",
@@ -250,6 +261,65 @@ test("changeBg with animation parameters", async () => {
250261
{ key: 'transform', value: '{"alpha":0.8}' }
251262
],
252263
sentenceAssets: [{ name: "background.jpg", url: 'background.jpg', type: fileType.background, lineNumber: 0 }],
253-
subScene: []
254-
});
264+
subScene: [],
265+
inlineComment: ""
266+
};
267+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
268+
});
269+
270+
test("inline comment is preserved on normal statement", async () => {
271+
const parser = new SceneParser((assetList) => {
272+
}, (fileName, assetType) => {
273+
return fileName;
274+
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
275+
276+
const result = parser.parse(`say:123 -speaker=xx; // this is an inline comment`, 'test', 'test');
277+
const expectSentenceItem: ISentence = {
278+
command: commandType.say,
279+
commandRaw: "say",
280+
content: "123",
281+
args: [{ key: 'speaker', value: 'xx' }],
282+
sentenceAssets: [],
283+
subScene: [],
284+
inlineComment: "// this is an inline comment"
285+
};
286+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
287+
});
288+
289+
test("escaped semicolon is preserved in content and inline comment is preserved", async () => {
290+
const parser = new SceneParser((assetList) => {
291+
}, (fileName, assetType) => {
292+
return fileName;
293+
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
294+
295+
const result = parser.parse(String.raw`say:price\;100;comment-part`, 'test', 'test');
296+
const expectSentenceItem: ISentence = {
297+
command: commandType.say,
298+
commandRaw: "say",
299+
content: "price;100",
300+
args: [],
301+
sentenceAssets: [],
302+
subScene: [],
303+
inlineComment: "comment-part"
304+
};
305+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
306+
});
307+
308+
test("comment-only line keeps comment in content", async () => {
309+
const parser = new SceneParser((assetList) => {
310+
}, (fileName, assetType) => {
311+
return fileName;
312+
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
313+
314+
const result = parser.parse(`; only comment here`, 'test', 'test');
315+
const expectSentenceItem: ISentence = {
316+
command: commandType.comment,
317+
commandRaw: "comment",
318+
content: "only comment here",
319+
args: [{ key: 'next', value: true }],
320+
sentenceAssets: [],
321+
subScene: [],
322+
inlineComment: ""
323+
};
324+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
255325
});

packages/webgal/index.html

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
<link rel="manifest" href="/manifest.json" />
88
<title>WebGAL</title>
99
<style>
10+
body {
11+
background: black;
12+
}
13+
1014
.html-body__effect-background {
1115
height: 100vh;
1216
width: 100vw;
@@ -17,6 +21,20 @@
1721
position: absolute;
1822
top: 0;
1923
left: 0;
24+
background-color: black;
25+
}
26+
27+
.html-body__effect-background-overlay {
28+
height: 100%;
29+
width: 100%;
30+
background-position: center;
31+
background-repeat: no-repeat;
32+
background-size: cover;
33+
position: absolute;
34+
top: 0;
35+
left: 0;
36+
background-color: black;
37+
opacity: 0;
2038
}
2139

2240
.html-body__title-enter {
@@ -115,7 +133,9 @@
115133
</head>
116134
<body>
117135
<!-- 背景模糊 -->
118-
<div class="html-body__effect-background"></div>
136+
<div id="ebg" class="html-body__effect-background">
137+
<div id="ebgOverlay" class="html-body__effect-background-overlay"></div>
138+
</div>
119139
<!-- 落地页 -->
120140
<div class="html-body__title-enter">
121141
<div class="title-enter__initial-background"></div>

packages/webgal/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webgal-engine",
3-
"version": "4.5.17",
3+
"version": "4.5.18",
44
"scripts": {
55
"dev": "vite --host --port 3000",
66
"build": "cross-env NODE_ENV=production tsc && vite build --base=./",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"name":"Default Template",
3-
"webgal-version":"4.5.17"
3+
"webgal-version":"4.5.18"
44
}

packages/webgal/src/Core/Modules/animationFunctions.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
DEFAULT_FIG_IN_DURATION,
1414
DEFAULT_FIG_OUT_DURATION,
1515
} from '../constants';
16+
import { stageActions } from '@/store/stageReducer';
1617

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

31-
PixiStage.assignTransform(newEffect, effect);
32+
PixiStage.assignTransform(newEffect, effect, false);
3233
newEffect.duration = effect.duration;
3334
newEffect.ease = effect.ease;
3435
return newEffect;
@@ -90,19 +91,23 @@ export function getEnterExitAnimation(
9091
if (isBg) {
9192
duration = DEFAULT_BG_OUT_DURATION;
9293
}
93-
duration =
94-
webgalStore.getState().stage.animationSettings.find((setting) => setting.target + '-off' === target)
95-
?.exitDuration ?? duration;
94+
const animationSettings = webgalStore
95+
.getState()
96+
.stage.animationSettings.find((setting) => setting.target === target);
97+
duration = animationSettings?.exitDuration ?? duration;
9698
// 走默认动画
9799
let animation: IAnimationObject | null = generateUniversalSoftOffAnimationObj(realTarget ?? target, duration);
98-
const animationName = webgalStore
99-
.getState()
100-
.stage.animationSettings.find((setting) => setting.target + '-off' === target)?.exitAnimationName;
100+
const animationName = animationSettings?.exitAnimationName;
101101
if (animationName) {
102102
logger.debug('取代默认退出动画', target);
103103
animation = getAnimationObject(animationName, realTarget ?? target, getAnimateDuration(animationName), false);
104104
duration = getAnimateDuration(animationName);
105105
}
106+
if (animationSettings) {
107+
// 退出动画拿完后,删了这个设定
108+
webgalStore.dispatch(stageActions.removeAnimationSettingsByTargetOff(target));
109+
logger.debug('删除退出动画设定', target);
110+
}
106111
return { duration, animation };
107112
}
108113
}

packages/webgal/src/Core/Modules/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export class Events {
1111
public userInteractNext = formEvent('__NEXT');
1212
public fullscreenDbClick = formEvent('fullscreen-dbclick');
1313
public styleUpdate = formEvent('style-update');
14+
public afterStyleUpdate = formEvent('after-style-update');
1415
}
1516

1617
const eventBus = mitt();

0 commit comments

Comments
 (0)