Skip to content

Commit

Permalink
feat: new feature for video backgrounds in screens (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
liana-p committed Jul 20, 2023
1 parent b4e3d17 commit fa646e4
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 4 deletions.
13 changes: 13 additions & 0 deletions docs/features/viewport.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ screens: data/screens.yaml
- `background` : This is the id of an image loaded by the engine. Images are defined in the `images` section of the config
- `buttons`: This is an array of ids of interactive buttons that exist in the screen.

### Video backgrounds

Backgrounds can use video files instead of static images if you want to have animated backgrounds. To do this, you need to add a `video` property to the background config:

```yaml
screens:
my_video_screen:
background: img/backgrounds/some_path_video.mp4
video:
loop: true # Optional, default is true
muted: false # Optional, default is false
```

## Buttons config

```yaml
Expand Down
4 changes: 4 additions & 0 deletions packages/narrat/examples/games/default/data/screens.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ screens:
- tester
- parkButton
- shopButton
# video:
# background: img/backgrounds/path_video.mp4
# video:
# loop: true
45 changes: 42 additions & 3 deletions packages/narrat/src/components/screen-layer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,26 @@
<div
class="viewport-layer"
:id="`viewport-layer-${currentScreen}`"
:style="layerStyle"
:style="containerStyle"
v-if="inGame"
>
<video
class="viewport-layer-background"
:id="`viewport-layer-background-${currentScreen}`"
:style="videoStyle"
v-if="video"
autoplay
:loop="video.loop === false ? false : true"
:muted="video.muted ? true : false"
>
<source :src="getAssetUrl(screenConfig.background)" />
</video>
<div
class="viewport-layer-background"
:id="`viewport-layer-background-${currentScreen}`"
:style="backgroundStyle"
v-else
></div>
<ViewportButton
v-for="button in screenButtons"
:key="button"
Expand All @@ -25,7 +42,7 @@
</template>

<script setup lang="ts">
import { getConfig, getImageUrl, getScreenConfig } from '@/config';
import { getAssetUrl, getConfig, getImageUrl, getScreenConfig } from '@/config';
import { computed, CSSProperties } from 'vue';
import { useMain } from '../stores/main-store';
import { useScreenObjects } from '@/stores/screen-objects-store';
Expand Down Expand Up @@ -85,7 +102,16 @@ const screenButtons = computed(() => {
return (screenConfig.value.buttons || []) as string[];
});
const layerStyle = computed<CSSProperties>(() => {
const video = computed(() => {
return screenConfig.value.video;
});
const containerStyle = computed<CSSProperties>(() => {
return {
width: `${layoutWidth.value}px`,
height: `${layoutHeight.value}px`,
};
});
const backgroundStyle = computed<CSSProperties>(() => {
let backgroundImage: string | undefined = `url(${getImageUrl(
screenConfig.value.background,
)})`;
Expand All @@ -94,6 +120,19 @@ const layerStyle = computed<CSSProperties>(() => {
}
return {
backgroundImage,
position: 'absolute',
left: 0,
top: 0,
width: `${layoutWidth.value}px`,
height: `${layoutHeight.value}px`,
};
});
const videoStyle = computed<CSSProperties>(() => {
return {
position: 'absolute',
left: 0,
top: 0,
width: `${layoutWidth.value}px`,
height: `${layoutHeight.value}px`,
};
Expand Down
7 changes: 7 additions & 0 deletions packages/narrat/src/config/screens-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ export const InlineButtonConfigSchema = Type.Intersect([
]);
export type InlineButtonConfig = Static<typeof InlineButtonConfigSchema>;

export const VideoConfigSchema = Type.Object({
muted: Type.Optional(Type.Boolean()),
loop: Type.Optional(Type.Boolean()),
});
export type VideoConfig = Static<typeof VideoConfigSchema>;

export const ScreenConfigSchema = Type.Object({
background: Type.String(),
video: Type.Optional(VideoConfigSchema),
buttons: Type.Optional(
Type.Array(Type.Union([Type.String(), InlineButtonConfigSchema])),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ main:
// jump test_arrays
// set_screen map 0 fade 1000
set_screen map
// set_screen video
"Hello world"
// jump quest_demo

Expand Down
6 changes: 5 additions & 1 deletion packages/narrat/src/utils/images-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ export async function loadImages(config: Config): Promise<HTMLImageElement[]> {
// Find other images to load from config
for (const key in config.screens.screens) {
const screen = config.screens.screens[key];
if (screen.background && !config.images[screen.background]) {
if (
screen.background &&
!config.images[screen.background] &&
!screen.video
) {
addImage(screen.background, screen.background);
}
if (screen.buttons) {
Expand Down

0 comments on commit fa646e4

Please sign in to comment.