refactor slideshow code to its component and added Miku & miku background
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 1m42s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 1m42s
This commit is contained in:
BIN
nginx/vue/public/img/miku/miku1.gif
Normal file
BIN
nginx/vue/public/img/miku/miku1.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
BIN
nginx/vue/public/img/miku/miku2.gif
Normal file
BIN
nginx/vue/public/img/miku/miku2.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
BIN
nginx/vue/public/img/miku/miku2.png
Normal file
BIN
nginx/vue/public/img/miku/miku2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
68
nginx/vue/src/components/util/Slideshow.vue
Normal file
68
nginx/vue/src/components/util/Slideshow.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, computed, onMounted, onUnmounted } from "vue";
|
||||||
|
import Header from "@/components/text/Header.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
images: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
interval: {
|
||||||
|
type: Number,
|
||||||
|
default: 10000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentIndex = ref(0);
|
||||||
|
const currentComment = computed(() => props.images[currentIndex.value].comment);
|
||||||
|
const currentUrl = computed(() => props.images[currentIndex.value].url);
|
||||||
|
|
||||||
|
let nextId;
|
||||||
|
|
||||||
|
function nextImage() {
|
||||||
|
clearTimeout(nextId);
|
||||||
|
currentIndex.value = (currentIndex.value + 1) % props.images.length;
|
||||||
|
nextId = setTimeout(nextImage, props.interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextId = setTimeout(nextImage, props.interval);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearTimeout(nextId);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Transition name="fade" mode="out-in">
|
||||||
|
<div class="image-viewer" @click="nextImage" :key="currentIndex">
|
||||||
|
<Header v-if="currentComment">
|
||||||
|
{{ currentComment }}
|
||||||
|
</Header>
|
||||||
|
<img :src="currentUrl" alt="Image Viewer" />
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.image-viewer {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.5s ease;
|
||||||
|
}
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,76 +1,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, onUnmounted } from "vue";
|
import Slideshow from "@/components/util/Slideshow.vue";
|
||||||
import { Transition } from "vue";
|
|
||||||
import Header from "@/components/text/Header.vue";
|
|
||||||
|
|
||||||
const images = [
|
const images = [
|
||||||
{ url: "/img/memes/pidgeon.gif", comment: "鸟" },
|
{ url: "/img/memes/pidgeon.gif", comment: "鸟" },
|
||||||
// { url: "/img/memes/no_slip.png" },
|
// { url: "/img/memes/no_slip.png" },
|
||||||
//{ url: "/img/memes/epic.jpeg" },
|
// { url: "/img/memes/epic.jpeg" },
|
||||||
// { url: "/img/bedroom/img2.png", comment: "办公桌" },
|
// { url: "/img/bedroom/img2.png", comment: "办公桌" },
|
||||||
// { url: "/img/bedroom/img1.png", comment: "床" },
|
// { url: "/img/bedroom/img1.png", comment: "床" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const currentIndex = ref(0);
|
|
||||||
const currentComment = computed(() => images[currentIndex.value].comment);
|
|
||||||
const currentUrl = computed(() => images[currentIndex.value].url);
|
|
||||||
|
|
||||||
let nextId;
|
|
||||||
|
|
||||||
function nextImage() {
|
|
||||||
clearTimeout(nextId);
|
|
||||||
currentIndex.value = (currentIndex.value + 1) % images.length;
|
|
||||||
nextId = setTimeout(nextImage, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function nextRandomImage() {
|
|
||||||
clearTimeout(nextId);
|
|
||||||
let newIndex;
|
|
||||||
do {
|
|
||||||
newIndex = Math.floor(Math.random() * images.length);
|
|
||||||
} while (newIndex === currentIndex.value);
|
|
||||||
currentIndex.value = newIndex;
|
|
||||||
nextId = setTimeout(nextImage, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextId = setTimeout(nextImage, 10000);
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
clearTimeout(nextId);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Transition name="fade" mode="out-in">
|
<Slideshow :images="images" />
|
||||||
<div class="image-viewer" @click="nextImage" :key="currentIndex">
|
|
||||||
<Header v-if="currentComment">
|
|
||||||
{{ currentComment }}
|
|
||||||
</Header>
|
|
||||||
<img :src="currentUrl" alt="Image Viewer" />
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.image-viewer {
|
|
||||||
width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-enter-active,
|
|
||||||
.fade-leave-active {
|
|
||||||
transition: opacity 0.5s ease;
|
|
||||||
}
|
|
||||||
.fade-enter-from,
|
|
||||||
.fade-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import CommitHistory from "@/components/util/CommitHistory.vue";
|
|||||||
import Intro from "./Intro.vue";
|
import Intro from "./Intro.vue";
|
||||||
import Intro2 from "./Intro2.vue";
|
import Intro2 from "./Intro2.vue";
|
||||||
import BadApple from "./BadApple.vue";
|
import BadApple from "./BadApple.vue";
|
||||||
|
import Miku from "./Miku.vue";
|
||||||
import Stamps from "./Stamps.vue";
|
import Stamps from "./Stamps.vue";
|
||||||
import Listening from "./Listening.vue";
|
import Listening from "./Listening.vue";
|
||||||
import Links from "./Links.vue";
|
import Links from "./Links.vue";
|
||||||
@@ -21,9 +22,14 @@ import Consumption from "./Consumption.vue";
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="halftone justify-center flex flex-row w-full h-full">
|
<main class="bg-random justify-center flex flex-row w-full h-full">
|
||||||
<div class="h-fit flex flex-row">
|
<div class="h-fit flex flex-row">
|
||||||
<div class="a4page-portrait homeGrid relative bdr-1">
|
<div
|
||||||
|
class="sidebar border-children background-children place-content-between flex-1 flex flex-col m-10 w-60"
|
||||||
|
>
|
||||||
|
<Miku/>
|
||||||
|
</div>
|
||||||
|
<div class="a4page-portrait homeGrid relative background-children border-children bdr-1">
|
||||||
<!-- <Intro class="intro" /> -->
|
<!-- <Intro class="intro" /> -->
|
||||||
<Intro2 class="intro" />
|
<Intro2 class="intro" />
|
||||||
<!-- <BadApple class="intro" /> -->
|
<!-- <BadApple class="intro" /> -->
|
||||||
@@ -37,18 +43,18 @@ import Consumption from "./Consumption.vue";
|
|||||||
<Gym class="gym" />
|
<Gym class="gym" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="sidebar border-quaternary place-content-between flex-1 flex flex-col m-10 w-60"
|
class="sidebar place-content-between flex-1 flex flex-col m-10 w-60"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col flex-1 gap-2">
|
<div class="flex flex-col background-children border-children flex-1 gap-2">
|
||||||
<Time
|
<Time
|
||||||
class="bg-bg_primary border-primary border text-center"
|
class="text-center"
|
||||||
/>
|
/>
|
||||||
<Timer class="border-primary border bg-bg_primary" />
|
<Timer/>
|
||||||
<Radio
|
<Radio
|
||||||
class="border-primary border bg-bg_primary text-center"
|
class="text-center"
|
||||||
/>
|
/>
|
||||||
<CommitHistory
|
<CommitHistory
|
||||||
class="border-primary border bg-bg_primary text-center"
|
class=" text-center"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- <Elle class="flex-1" /> -->
|
<!-- <Elle class="flex-1" /> -->
|
||||||
@@ -67,9 +73,11 @@ import Consumption from "./Consumption.vue";
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.homeGrid > * {
|
.border-children > * {
|
||||||
border: 2px solid var(--quaternary);
|
border: 2px solid var(--quaternary);
|
||||||
border-color: var(--quaternary);
|
}
|
||||||
|
|
||||||
|
.background-children > * {
|
||||||
background-color: var(--bg_primary);
|
background-color: var(--bg_primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +88,7 @@ import Consumption from "./Consumption.vue";
|
|||||||
grid-template-rows: repeat(10, 1fr);
|
grid-template-rows: repeat(10, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 850px) {
|
@media (max-width: 850px) {
|
||||||
.homeGrid {
|
.homeGrid {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -140,4 +149,10 @@ import Consumption from "./Consumption.vue";
|
|||||||
grid-column: span 3;
|
grid-column: span 3;
|
||||||
grid-row: span 2;
|
grid-row: span 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-random {
|
||||||
|
background-color: var(--bg_primary);
|
||||||
|
background-image: url("/img/miku/miku2.gif");
|
||||||
|
background-size: 10px 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
13
nginx/vue/src/views/home/Miku.vue
Normal file
13
nginx/vue/src/views/home/Miku.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<script setup>
|
||||||
|
import Slideshow from "@/components/util/Slideshow.vue";
|
||||||
|
|
||||||
|
const images = [
|
||||||
|
{ url: "/img/miku/miku1.gif" },
|
||||||
|
{ url: "/img/miku/miku2.gif" },
|
||||||
|
// { url: "/img/miku/miku2.png" },
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Slideshow class="p-5" :images="images" :interval="10000" />
|
||||||
|
</template>
|
||||||
Reference in New Issue
Block a user