feat: add image loading

This commit is contained in:
KUN1007 2023-11-10 14:27:52 +08:00
parent 36d9d22986
commit 8da2b2af81
5 changed files with 258 additions and 35 deletions

View file

@ -0,0 +1,101 @@
<script setup lang="ts"></script>
<template>
<div class="lds-roller">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</template>
<style lang="scss" scoped>
.lds-roller {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.lds-roller div {
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
transform-origin: 40px 40px;
}
.lds-roller div:after {
content: ' ';
display: block;
position: absolute;
width: 7px;
height: 7px;
border-radius: 50%;
background: #fff;
margin: -4px 0 0 -4px;
}
.lds-roller div:nth-child(1) {
animation-delay: -0.036s;
}
.lds-roller div:nth-child(1):after {
top: 63px;
left: 63px;
}
.lds-roller div:nth-child(2) {
animation-delay: -0.072s;
}
.lds-roller div:nth-child(2):after {
top: 68px;
left: 56px;
}
.lds-roller div:nth-child(3) {
animation-delay: -0.108s;
}
.lds-roller div:nth-child(3):after {
top: 71px;
left: 48px;
}
.lds-roller div:nth-child(4) {
animation-delay: -0.144s;
}
.lds-roller div:nth-child(4):after {
top: 72px;
left: 40px;
}
.lds-roller div:nth-child(5) {
animation-delay: -0.18s;
}
.lds-roller div:nth-child(5):after {
top: 71px;
left: 32px;
}
.lds-roller div:nth-child(6) {
animation-delay: -0.216s;
}
.lds-roller div:nth-child(6):after {
top: 68px;
left: 24px;
}
.lds-roller div:nth-child(7) {
animation-delay: -0.252s;
}
.lds-roller div:nth-child(7):after {
top: 63px;
left: 17px;
}
.lds-roller div:nth-child(8) {
animation-delay: -0.288s;
}
.lds-roller div:nth-child(8):after {
top: 56px;
left: 12px;
}
@keyframes lds-roller {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

View file

@ -0,0 +1,68 @@
<script setup lang="ts"></script>
<template>
<span class="loader"></span>
</template>
<style lang="scss" scoped>
.loader {
width: 0;
height: 4.8px;
display: inline-block;
position: relative;
background: #fff;
box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
box-sizing: border-box;
animation: animFw 8s linear infinite;
}
.loader::after,
.loader::before {
content: '';
width: 10px;
height: 1px;
background: #fff;
position: absolute;
top: 9px;
right: -2px;
opacity: 0;
transform: rotate(-45deg) translateX(0px);
box-sizing: border-box;
animation: coli1 0.3s linear infinite;
}
.loader::before {
top: -4px;
transform: rotate(45deg);
animation: coli2 0.3s linear infinite;
}
@keyframes animFw {
0% {
width: 0;
}
100% {
width: 100%;
}
}
@keyframes coli1 {
0% {
transform: rotate(-45deg) translateX(0px);
opacity: 0.7;
}
100% {
transform: rotate(-45deg) translateX(-45px);
opacity: 0;
}
}
@keyframes coli2 {
0% {
transform: rotate(45deg) translateX(0px);
opacity: 1;
}
100% {
transform: rotate(45deg) translateX(-45px);
opacity: 0.7;
}
}
</style>

View file

@ -2,6 +2,8 @@
import { useLoliDataURL } from '@/hooks/useLoli' import { useLoliDataURL } from '@/hooks/useLoli'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import LoliSkeleton from '@/components/skeleton/settings-panel/LoliSkeleton.vue'
const loliData = ref({ const loliData = ref({
loliBodyLeft: '', loliBodyLeft: '',
loliBodyTop: '', loliBodyTop: '',
@ -20,15 +22,20 @@ const loliData = ref({
face: '', face: '',
}) })
const reGetLoli = async () => (loliData.value = await useLoliDataURL()) const reGetLoli = async () => {
await new Promise((res) => setTimeout(res, 2000))
loliData.value = await useLoliDataURL()
}
onMounted(async () => { onMounted(async () => {
await new Promise((res) => setTimeout(res, 2000))
loliData.value = await useLoliDataURL() loliData.value = await useLoliDataURL()
}) })
</script> </script>
<template> <template>
<div class="loli" @click="reGetLoli"> <div class="loli-container">
<div class="loli" @click="reGetLoli" v-if="loliData.body">
<img <img
class="body" class="body"
:src="loliData.body" :src="loliData.body"
@ -60,16 +67,22 @@ onMounted(async () => {
:style="{ left: loliData.loliFaceLeft, top: loliData.loliFaceTop }" :style="{ left: loliData.loliFaceLeft, top: loliData.loliFaceTop }"
/> />
</div> </div>
<LoliSkeleton v-if="!loliData.body" />
</div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.loli-container {
top: -270px;
left: 130px;
}
.loli { .loli {
cursor: pointer; cursor: pointer;
width: 0; width: 0;
position: absolute; position: absolute;
z-index: 9999; z-index: 9999;
top: -270px;
left: 130px;
} }
.body { .body {
position: absolute; position: absolute;

View file

@ -27,13 +27,14 @@ const numberSkeleton = computed(() => (props.number ? props.number : 1))
height: 100%; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
margin-top: 7px;
} }
.container { .container {
background-color: var(--kungalgame-trans-white-5); background-color: var(--kungalgame-trans-white-5);
border-radius: 3px; border-radius: 3px;
margin: 0 auto; margin: 0 auto;
padding: 10px; padding: 12px;
width: 100%; width: 100%;
display: flex; display: flex;

View file

@ -0,0 +1,40 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue'
</script>
<template>
<div class="skeleton">
<ul>
<li><Icon icon="line-md:image" /></li>
</ul>
</div>
</template>
<style lang="scss" scoped>
.skeleton {
position: absolute;
top: 320px;
left: 140px;
width: 309px;
height: 600px;
display: flex;
justify-content: center;
}
ul {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
li {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 77px;
color: var(--kungalgame-blue-4);
}
}
</style>