mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
Add presentation from CMP to website (#2453)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import Button from "./components/Button.vue";
|
||||
import GridSection from "./components/GridSection.vue";
|
||||
import PresentationCarousel from "./components/PresentationCarousel.vue";
|
||||
|
||||
const navLinks = [
|
||||
{
|
||||
@@ -93,6 +94,26 @@ const socialLinks = [
|
||||
label: "Discord",
|
||||
},
|
||||
];
|
||||
|
||||
const presentations = [
|
||||
{
|
||||
title: "Champs 2026 Talk",
|
||||
description:
|
||||
"Information on the Rubik Pi 3 and how to use Object Detection with PhotonVision.",
|
||||
slidedeckLink:
|
||||
"https://docs.google.com/presentation/d/1eCt9OmOISldCxsxp-aWAvT6YFkfdPzhbeEZn2ihcltA/edit?usp=sharing",
|
||||
},
|
||||
{
|
||||
title: "Champs 2024 Talk",
|
||||
description:
|
||||
"Watch our presentation from the 2024 FIRST Championship and learn how to get the most out of PhotonVision.",
|
||||
slidedeckLink:
|
||||
"https://docs.google.com/presentation/d/1Gh5InslM5p7aDxjzK8DHoEorpATOl-MQWWixY5GjGgs/edit#slide=id.p",
|
||||
codeLink: "https://github.com/PhotonVision/champs_2024",
|
||||
videoEmbedUrl:
|
||||
"https://www.youtube-nocookie.com/embed/iV2v7F_9GwE?si=4wgaT1IrZBpA71dF",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -268,57 +289,7 @@ const socialLinks = [
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
id="champs"
|
||||
class="flex flex-col lg:flex-row items-center justify-center relative py-16 px-8 md:px-16 lg:px-28 gap-12 bg-primary"
|
||||
>
|
||||
<header
|
||||
class="flex flex-col gap-6 justify-center items-center lg:items-start text-center lg:text-left"
|
||||
>
|
||||
<h2 class="text-4xl font-bold font-heading">Champs 2024 Talk</h2>
|
||||
<p class="text-zinc-200 text-lg max-w-md">
|
||||
Watch our presentation from the 2024 FIRST Championship and learn how
|
||||
to get the most out of PhotonVision.
|
||||
</p>
|
||||
<div class="flex gap-4">
|
||||
<Button
|
||||
href="https://docs.google.com/presentation/d/1Gh5InslM5p7aDxjzK8DHoEorpATOl-MQWWixY5GjGgs/edit#slide=id.p"
|
||||
variant="secondary"
|
||||
>
|
||||
Slide Deck
|
||||
</Button>
|
||||
<Button
|
||||
href="https://github.com/PhotonVision/champs_2024"
|
||||
variant="outline"
|
||||
>
|
||||
View Code
|
||||
</Button>
|
||||
</div>
|
||||
</header>
|
||||
<div class="flex-1 max-w-3xl w-full">
|
||||
<div
|
||||
class="relative rounded-xl overflow-hidden shadow-2xl border border-white/10"
|
||||
>
|
||||
<iframe
|
||||
src="https://www.youtube-nocookie.com/embed/iV2v7F_9GwE?si=4wgaT1IrZBpA71dF"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="
|
||||
accelerometer;
|
||||
autoplay;
|
||||
clipboard-write;
|
||||
encrypted-media;
|
||||
gyroscope;
|
||||
picture-in-picture;
|
||||
web-share;
|
||||
"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
class="w-full aspect-video"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<PresentationCarousel :slides="presentations" />
|
||||
|
||||
<GridSection
|
||||
id="foss"
|
||||
|
||||
63
website/src/components/PresentationCard.vue
Normal file
63
website/src/components/PresentationCard.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
import Button from "./Button.vue";
|
||||
|
||||
defineProps<{
|
||||
title: string;
|
||||
description: string;
|
||||
slidedeckLink: string;
|
||||
codeLink?: string;
|
||||
videoEmbedUrl?: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section
|
||||
id="champs"
|
||||
class="flex flex-col lg:flex-row items-center justify-center relative py-16 px-8 md:px-16 lg:px-28 gap-12 bg-primary"
|
||||
>
|
||||
<header
|
||||
class="flex flex-col gap-6 justify-center items-center lg:items-start text-center lg:text-left"
|
||||
>
|
||||
<h2 class="text-4xl font-bold font-heading">{{ title }}</h2>
|
||||
<p class="text-zinc-200 text-lg max-w-md">
|
||||
{{ description }}
|
||||
</p>
|
||||
<div class="flex gap-4">
|
||||
<Button :href="slidedeckLink" variant="secondary"> Slide Deck </Button>
|
||||
<Button v-if="codeLink" :href="codeLink" variant="outline">
|
||||
View Code
|
||||
</Button>
|
||||
</div>
|
||||
</header>
|
||||
<div class="flex-1 max-w-3xl w-full">
|
||||
<div
|
||||
class="relative rounded-xl overflow-hidden shadow-2xl border border-white/10"
|
||||
>
|
||||
<iframe
|
||||
v-if="videoEmbedUrl"
|
||||
:src="videoEmbedUrl"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="
|
||||
accelerometer;
|
||||
autoplay;
|
||||
clipboard-write;
|
||||
encrypted-media;
|
||||
gyroscope;
|
||||
picture-in-picture;
|
||||
web-share;
|
||||
"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
class="w-full aspect-video"
|
||||
></iframe>
|
||||
<div
|
||||
v-else
|
||||
class="w-full aspect-video bg-zinc-800/50 flex items-center justify-center"
|
||||
>
|
||||
<p class="text-2xl font-semibold text-zinc-400">Coming Soon!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
77
website/src/components/PresentationCarousel.vue
Normal file
77
website/src/components/PresentationCarousel.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import PresentationCard from "./PresentationCard.vue";
|
||||
|
||||
export interface PresentationCardData {
|
||||
title: string;
|
||||
description: string;
|
||||
slidedeckLink: string;
|
||||
codeLink?: string;
|
||||
videoEmbedUrl?: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
slides: PresentationCardData[];
|
||||
}>();
|
||||
|
||||
const currentSlide = ref(0);
|
||||
|
||||
const previousSlide = () => {
|
||||
if (currentSlide.value > 0) {
|
||||
currentSlide.value--;
|
||||
} else {
|
||||
currentSlide.value = props.slides.length - 1;
|
||||
}
|
||||
};
|
||||
|
||||
const nextSlide = () => {
|
||||
if (currentSlide.value < props.slides.length - 1) {
|
||||
currentSlide.value++;
|
||||
} else {
|
||||
currentSlide.value = 0;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="relative w-full bg-zinc-900">
|
||||
<div class="relative">
|
||||
<!-- Carousel slides -->
|
||||
<div class="overflow-hidden">
|
||||
<PresentationCard
|
||||
:key="currentSlide"
|
||||
:title="props.slides[currentSlide].title"
|
||||
:description="props.slides[currentSlide].description"
|
||||
:slidedeckLink="props.slides[currentSlide].slidedeckLink"
|
||||
:codeLink="props.slides[currentSlide].codeLink"
|
||||
:videoEmbedUrl="props.slides[currentSlide].videoEmbedUrl"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Side navigation arrows -->
|
||||
<button
|
||||
v-if="props.slides.length > 1"
|
||||
@click="previousSlide"
|
||||
:class="[
|
||||
'absolute left-8 top-1/2 -translate-y-1/2 p-4 transition-all duration-300 text-4xl z-10',
|
||||
'text-brand-yellow/70 hover:text-brand-yellow cursor-pointer',
|
||||
]"
|
||||
aria-label="Previous slide"
|
||||
>
|
||||
<i class="fa-solid fa-chevron-left"></i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-if="props.slides.length > 1"
|
||||
@click="nextSlide"
|
||||
:class="[
|
||||
'absolute right-8 top-1/2 -translate-y-1/2 p-4 transition-all duration-300 text-4xl z-10',
|
||||
'text-brand-yellow/70 hover:text-brand-yellow cursor-pointer',
|
||||
]"
|
||||
aria-label="Next slide"
|
||||
>
|
||||
<i class="fa-solid fa-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user