From ec4d3fe9f931c27fd13a2910a1a875ebb03fb25f Mon Sep 17 00:00:00 2001 From: Ryan Coulson Date: Tue, 2 Apr 2024 16:48:46 -0400 Subject: [PATCH] add support for transitional background images --- ...000000-0000-0000-0000-000000000000_en.json | 8 ++ src/components/panels/dynamic-panel.vue | 14 ++- src/components/panels/image-panel.vue | 13 ++- src/components/panels/map-panel.vue | 16 +++- src/components/panels/panel.vue | 4 + src/components/panels/slideshow-panel.vue | 18 +++- src/components/panels/text-panel.vue | 11 ++- src/components/story/background-image.vue | 85 +++++++++++++++++++ src/components/story/slide.vue | 23 ++++- src/components/story/story-content.vue | 76 +++++++++++++---- src/definitions.ts | 1 + 11 files changed, 245 insertions(+), 24 deletions(-) create mode 100644 src/components/story/background-image.vue diff --git a/public/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000_en.json b/public/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000_en.json index cef9f3fb..81ae8523 100644 --- a/public/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000_en.json +++ b/public/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000_en.json @@ -11,6 +11,7 @@ "slides": [ { "title": "Overview", + "backgroundImage": "00000000-0000-0000-0000-000000000000/assets/en/GettyImages-516166467__1554821531978__w1920.jpg", "panel": [ { "title": "Overview", @@ -26,6 +27,7 @@ }, { "title": "Default RAMP4 Sample", + "backgroundImage": "00000000-0000-0000-0000-000000000000/assets/en/GettyImages-187242601__1554821467033__w1920.jpg", "panel": [ { "config": "00000000-0000-0000-0000-000000000000/ramp-config/test-ramp4.json", @@ -41,6 +43,7 @@ }, { "title": "Dynamic Panel Test", + "backgroundImage": "00000000-0000-0000-0000-000000000000/assets/en/GettyImages-516166467__1554821531978__w1920.jpg", "panel": [ { "title": "This Slide Is Dynamic!", @@ -127,6 +130,8 @@ }, { "title": "Video Panel", + "backgroundImage": "00000000-0000-0000-0000-000000000000/assets/en/GettyImages-516166467__1554821531978__w1920.jpg", + "panel": [ { "title": "Video Test for YoutTube content", @@ -174,6 +179,8 @@ }, { "title": "In-situ extraction", + "backgroundImage": "00000000-0000-0000-0000-000000000000/assets/en/GettyImages-187242601__1554821467033__w1920.jpg", + "panel": [ { "title": "In-situ extraction", @@ -203,6 +210,7 @@ }, { "title": "NPRI substances reported for oil sands mining facilities", + "backgroundImage": "00000000-0000-0000-0000-000000000000/assets/en/GettyImages-516166467__1554821531978__w1920.jpg", "panel": [ { "title": "NPRI substances reported for oil sands mining facilities", diff --git a/src/components/panels/dynamic-panel.vue b/src/components/panels/dynamic-panel.vue index 0020b5f6..b2315906 100644 --- a/src/components/panels/dynamic-panel.vue +++ b/src/components/panels/dynamic-panel.vue @@ -1,6 +1,9 @@ @@ -38,6 +39,9 @@ const props = defineProps({ slideIdx: { type: Number, default: 0 + }, + background: { + type: Boolean } }); @@ -76,7 +80,12 @@ onMounted((): void => { }); - diff --git a/src/components/story/slide.vue b/src/components/story/slide.vue index c03623e6..93e463b7 100644 --- a/src/components/story/slide.vue +++ b/src/components/story/slide.vue @@ -1,5 +1,5 @@ @@ -22,6 +23,7 @@ import Panel from '@storylines/components/panels/panel.vue'; const key = getCurrentInstance()?.vnode.key as string; +const emit = defineEmits(['slide-changed']); const props = defineProps({ config: { type: Object as PropType, @@ -35,13 +37,30 @@ const props = defineProps({ }, lang: { type: String + }, + background: { + type: Boolean } }); const defaultRatio = ref(false); +const slide = ref(); +const observer = ref(undefined); + onMounted(() => { const panels = props.config.panel; + + observer.value = new IntersectionObserver( + ([slide]) => { + // emit a `slide-changed` event when a new slide hits the middle of the screen. + if (slide.isIntersecting) { + emit('slide-changed', props.slideIdx); + } + }, + { rootMargin: '0px', threshold: 0.45 } + ); + // check if there is one text panel and one non-text panel in the slide and user did not specify a width in config if (panels.length == 2 && !panels[0]?.width && !panels[1]?.width) { const panelText1 = panels[0]?.type === PanelType.Text; @@ -52,6 +71,8 @@ onMounted(() => { defaultRatio.value = true; } } + + observer.value?.observe(slide.value as Element); }); /** diff --git a/src/components/story/story-content.vue b/src/components/story/story-content.vue index e33c763b..f126539c 100644 --- a/src/components/story/story-content.vue +++ b/src/components/story/story-content.vue @@ -21,22 +21,27 @@ v-else /> - -
- + + + +
+
+ +
@@ -52,12 +57,13 @@ import { ConfigFileStructure, StoryRampConfig } from '@storylines/definitions'; import ChapterMenu from './chapter-menu.vue'; import HorizontalMenu from './horizontal-menu.vue'; +import BackgroundImage from './background-image.vue'; import Slide from './slide.vue'; const route = useRoute(); const emit = defineEmits(['step']); -defineProps({ +const props = defineProps({ config: { type: Object as PropType, required: true @@ -79,6 +85,8 @@ defineProps({ const activeChapterIndex = ref(-1); const horizontalNavHeight = ref(0); +const backgroundImage = ref('none'); +const hasBackground = ref(false); // different from above; this considers animation time onMounted(() => { const hash = route?.hash.substring(1); @@ -90,8 +98,24 @@ onMounted(() => { el?.scrollIntoView(); }, 200); } + + // See if the first slide has a background image applied. If so, set it early to it appears as soon + // as you scroll down. + handleSlideChange(0); }); +const handleSlideChange = (event: number): void => { + const img = props.config.slides[event].backgroundImage; + backgroundImage.value = img ?? 'none'; +}; + +/** + * This event is fired when the background image actually switches backgrounds (after the animation). + */ +const handleBackgroundChange = (event: boolean): void => { + hasBackground.value = event; +}; + const stepEnter = ({ element }: { element: HTMLElement }): void => { activeChapterIndex.value = parseInt(element.dataset.chapterIndex || '-1'); emit('step', activeChapterIndex.value); @@ -103,6 +127,24 @@ const stepEnter = ({ element }: { element: HTMLElement }): void => {