valaxy-theme-hairy 0.0.9 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,17 +1,30 @@
1
1
  <script lang="ts" setup>
2
2
  import { useFrontmatter } from 'valaxy'
3
- import { computed } from 'vue'
3
+ import { computed, inject, nextTick, ref } from 'vue'
4
+ import { useRouter } from 'vue-router'
4
5
  import { toArr } from '../utils'
5
6
  import { useCurrentCategory } from '../hooks/useCategory'
6
7
 
7
8
  const frontmatter = useFrontmatter()
8
9
  const paths = computed(() => toArr(frontmatter.value.categories).filter(Boolean) as string[])
9
10
  const category = useCurrentCategory(paths)
10
- const posts = computed(() => category.value.posts || [])
11
+ const posts = computed(() => {
12
+ const result = category.value.posts || []
13
+ return result.sort((a, b) => (a.date || 1) > (b.date || 1) ? 1 : -1)
14
+ })
15
+ const router = useRouter()
16
+
17
+ const active = inject('HairyUserTab:active', ref(''))
11
18
 
12
19
  function isCurrent(title = '') {
13
20
  return frontmatter.value.title === title
14
21
  }
22
+
23
+ async function changePost(path = '') {
24
+ router.push(path)
25
+ await nextTick()
26
+ active.value = 'aside'
27
+ }
15
28
  </script>
16
29
 
17
30
  <template>
@@ -20,7 +33,7 @@ function isCurrent(title = '') {
20
33
  On this Series
21
34
  </div>
22
35
  <ul class="va-toc relative z-1">
23
- <a v-for="(item, index) of posts" :key="index" class="va-toc-item" @click="$router.push(item.path || '')">
36
+ <a v-for="(item, index) of posts" :key="index" class="va-toc-item" @click="changePost(item.path)">
24
37
  <a class="outline-link" :class="[isCurrent(item.title) && 'active']">{{ index + 1 }}.{{ item.title }}</a>
25
38
  </a>
26
39
  </ul>
@@ -13,6 +13,13 @@ const text = computed(() => {
13
13
  return props.post.text
14
14
  return props.post.excerpt
15
15
  })
16
+
17
+ const Blogs = {
18
+ name: 'Mao’s blog',
19
+ desc: '记录生活、持续学习。',
20
+ link: 'https://hairy.blog/',
21
+ thumbnail: 'https://user-images.githubusercontent.com/49724027/182444624-6228d153-94cb-461d-a5d8-be8535441fb6.png',
22
+ }
16
23
  </script>
17
24
 
18
25
  <template>
@@ -2,8 +2,8 @@
2
2
  import { computed, provide, useCssVars, useSlots } from 'vue'
3
3
  import { executeOverlay } from 'unoverlay-vue'
4
4
  import type { ImageViewerProps } from 'element-plus/es/components/image-viewer/index'
5
- import type { AtWillNumber } from '@hairy/libcore'
6
- import { atWillToUnit } from '@hairy/libcore'
5
+ import type { AtWillNumber } from '../utils'
6
+ import { atWillToUnit } from '../utils'
7
7
  import HairyImageViewer from './HairyImageViewer.vue'
8
8
 
9
9
  const props = withDefaults(defineProps<{
@@ -0,0 +1,61 @@
1
+ <script lang="ts" setup>
2
+ import { defineProps } from 'vue'
3
+ defineProps<{
4
+ links?: {
5
+ name: string
6
+ url: string
7
+ image: string
8
+ color: string
9
+ desc?: string
10
+ }[]
11
+ }>()
12
+ </script>
13
+
14
+ <template>
15
+ <div class="min-h-30vh">
16
+ <div class="links">
17
+ <div v-for="(item, index) in links" :key="index" class="link-block flex items-center py-0.5rem px-1rem rounded-lg" :style="{ '--block-color': item.color }">
18
+ <a :href="item.url" class="w-4rem h-4rem">
19
+ <HairyImage class="w-full h-full rounded-xl" :src="item.image" />
20
+ </a>
21
+ <div class="pl-1rem flex-1">
22
+ <a :href="item.url" class="font-bold text-lg title">
23
+ {{ item.name }}
24
+ </a>
25
+ <div class="max-w-180px text-sm my-0.5rem truncate">
26
+ {{ item.desc }}
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss" scoped>
35
+ .link-block {
36
+ border: 0.0625rem solid #f7f7f7;
37
+ box-shadow: 0 0.625rem 1.875rem -0.9375rem rgba(0,0,0,0.1);
38
+ --bg-color: var(--block-color, #666);
39
+ @apply transition-all;
40
+ .title {
41
+ color: var(--block-color);
42
+ }
43
+ }
44
+ .dark .link-block {
45
+ background: rgba($color: #989898, $alpha: 0.1);
46
+ }
47
+ .links .link-block:hover {
48
+ background-color: var(--bg-color);
49
+ box-shadow: 0 0.125rem 1.25rem var(--bg-color);
50
+ border-color: var(--bg-color);
51
+ .title {
52
+ color: #fff;
53
+ }
54
+ }
55
+
56
+ .links {
57
+ display: grid;
58
+ grid-template-columns: repeat(auto-fill, 300px);
59
+ gap: 24px;
60
+ }
61
+ </style>
@@ -1,24 +1,51 @@
1
1
  <script lang="ts" setup>
2
- import type { Ref } from 'vue'
3
- import { computed } from 'vue'
2
+ import { computed, defineProps, ref, withDefaults } from 'vue'
4
3
  import type { Post } from 'valaxy'
5
4
  import { usePostList } from 'valaxy'
5
+ import { usePostLayout } from '../hooks/usePostLayout'
6
6
 
7
7
  const props = withDefaults(defineProps<{
8
8
  type?: string
9
9
  posts?: Post[]
10
+ curPage?: number
11
+ pagination?: boolean
10
12
  }>(), {
13
+ curPage: 1,
14
+ pagination: false,
11
15
  })
16
+ const layout = usePostLayout()
12
17
 
13
- const routes = usePostList() as any as Ref<Post[]>
14
- const posts = computed(() => props.posts || routes.value)
18
+ const pageSize = ref(7)
19
+ const routes = usePostList({ type: props.type || '' })
20
+ const posts = computed<any[]>(() => props.posts || routes.value)
21
+ const pagePosts = computed(() => posts.value.slice((props.curPage - 1) * pageSize.value, props.curPage * pageSize.value))
22
+ const displayedPosts = computed(() => props.pagination ? pagePosts.value : posts.value)
15
23
  </script>
16
24
 
17
25
  <template>
18
- <ul class="divide-y divide-gray-200 dark:divide-gray-700">
19
- <Transition v-for="post, i in posts" :key="i" name="fade">
20
- <HairyArticleText :post="post" />
21
- </Transition>
22
- </ul>
26
+ <HairyPostImageList v-if="layout.includes('image')" :posts="displayedPosts" />
27
+ <HairyPostTextsList v-else :posts="displayedPosts" />
28
+ <ValaxyPagination v-if="pagination" :cur-page="curPage" :page-size="pageSize" :total="posts.length" />
23
29
  </template>
24
30
 
31
+ <style lang="scss">
32
+ .pagination {
33
+ font-size: 16px;
34
+ }
35
+
36
+ .pagination .prev.active,
37
+ .pagination .next.active,
38
+ .pagination .page-number.active {
39
+ font-weight: normal;
40
+ background: transparent;
41
+ color: var(--hy-c-primary);
42
+ cursor: default;
43
+ }
44
+
45
+ .pagination .prev:hover,
46
+ .pagination .next:hover,
47
+ .pagination .page-number:hover {
48
+ color: var(--va-c-bg);
49
+ background: rgba(143, 230, 213, 0.8);
50
+ }
51
+ </style>
@@ -0,0 +1,23 @@
1
+ <script lang="ts" setup>
2
+ import type { Ref } from 'vue'
3
+ import { computed } from 'vue'
4
+ import type { Post } from 'valaxy'
5
+ import { usePostList } from 'valaxy'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ type?: string
9
+ posts?: Post[]
10
+ }>(), {})
11
+
12
+ const routes = usePostList() as any as Ref<Post[]>
13
+ const posts = computed(() => props.posts || routes.value)
14
+ </script>
15
+
16
+ <template>
17
+ <ul class="divide-y divide-gray-200 dark:divide-gray-700">
18
+ <Transition v-for="post, i in posts" :key="i" name="fade">
19
+ <HairyArticleText :post="post" />
20
+ </Transition>
21
+ </ul>
22
+ </template>
23
+
@@ -1,8 +1,23 @@
1
1
  <script lang="ts" setup>
2
- import { useCategory, usePostList, useTag } from 'valaxy'
3
- const category = useCategory()
2
+ import { usePostList, useTag } from 'valaxy'
3
+ import { computed } from 'vue'
4
+ import { toArr } from '../utils'
4
5
  const posts = usePostList()
5
6
  const tags = useTag()
7
+
8
+ const total = computed(() => {
9
+ const categories = posts.value.map(v => toArr(v.categories || [])).filter(v => v.length)
10
+ const maps: string[] = []
11
+ for (const category of categories) {
12
+ let caches: string[] = []
13
+ for (const iterator of category) {
14
+ caches.push(iterator)
15
+ maps.push(caches.join('-'))
16
+ }
17
+ caches = []
18
+ }
19
+ return new Set(maps).size
20
+ })
6
21
  </script>
7
22
 
8
23
  <template>
@@ -11,7 +26,7 @@ const tags = useTag()
11
26
  文章
12
27
  </HairyUserStats>
13
28
  <div class="w-1px bg-gray bg-opacity-50" />
14
- <HairyUserStats :count="category.total" @click="$router.push('/categories/')">
29
+ <HairyUserStats :count="total" @click="$router.push('/categories/')">
15
30
  分类
16
31
  </HairyUserStats>
17
32
  <div class="w-1px bg-gray bg-opacity-50" />
@@ -2,9 +2,9 @@
2
2
  import { ElTabPane, ElTabs } from 'element-plus/es/components/tabs/index'
3
3
  import 'element-plus/es/components/tabs/style/index'
4
4
  import 'element-plus/es/components/tab-pane/style/index'
5
- import { ref } from 'vue'
6
-
5
+ import { provide, ref } from 'vue'
7
6
  const active = ref('aside')
7
+ provide('HairyUserTab:active', active)
8
8
  </script>
9
9
 
10
10
  <template>
@@ -27,17 +27,21 @@ export function useYearArchives() {
27
27
  const [year, month] = [days.format('YYYY'), days.format('MM')]
28
28
  if (!maps[year])
29
29
  maps[year] = {}
30
- if (!maps[year][month]) { maps[year][month] = { count: 1, posts: [post] } }
30
+ if (!maps[year][month]) { maps[year][month] = { count: 1, posts: [post as any] } }
31
31
  else {
32
32
  maps[year][month].count++
33
- maps[year][month].posts.push(post)
33
+ maps[year][month].posts.unshift(post as any)
34
34
  }
35
35
  }
36
36
  for (const [year, months] of Object.entries(maps)) {
37
37
  for (const [month, { count, posts }] of Object.entries(months))
38
- items.push({ year, month, count, posts })
38
+ items.unshift({ year, month, count, posts })
39
39
  }
40
- return items
40
+ return items.sort((a, b) => {
41
+ const aTime = `${a.year}-${a.month}`
42
+ const bTime = `${b.year}-${b.month}`
43
+ return bTime > aTime ? 1 : -1
44
+ })
41
45
  })
42
46
  return archives
43
47
  }
@@ -1,10 +1,13 @@
1
1
  import './loading.scss'
2
2
  import { ref } from 'vue'
3
+ import { fontFacePromise } from '../utils/fonts'
3
4
  import type { UserModule } from '..'
4
5
 
5
6
  export const install: UserModule = ({ router }) => {
6
7
  showFullLoading()
7
- router.afterEach(hideFullLoading)
8
+ router.afterEach(() => {
9
+ fontFacePromise.then(hideFullLoading)
10
+ })
8
11
  }
9
12
 
10
13
  export const isLoading = ref(false)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valaxy-theme-hairy",
3
- "version": "0.0.9",
3
+ "version": "0.0.13",
4
4
  "packageManager": "pnpm@7.5.0",
5
5
  "author": {
6
6
  "email": "wwu710632@gmail.com",
@@ -21,7 +21,6 @@
21
21
  "dependencies": {
22
22
  "@docsearch/css": "^3.1.1",
23
23
  "@docsearch/js": "^3.1.1",
24
- "@hairy/libcore": "^0.3.0",
25
24
  "@hairy/vue-use": "^1.2.0",
26
25
  "@iconify-json/ant-design": "^1.1.3",
27
26
  "@iconify-json/simple-icons": "^1.1.19",
@@ -33,7 +33,6 @@ const post = computed(() => months.value.flatMap(item => item.posts))
33
33
  {{ month }}月
34
34
  </HairyBreadcrumbItem>
35
35
  </HairyBreadcrumb>
36
-
37
36
  <el-timeline>
38
37
  <el-timeline-item
39
38
  v-for="(item, index) in post"
@@ -26,15 +26,21 @@ const posts = usePostList()
26
26
  size="large"
27
27
  >
28
28
  <div class="activity inline-flex items-center">
29
- <HairyLink @click="$router.push(getArchiveLink(activity.year))">
29
+ <HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year))">
30
30
  {{ activity.year }}
31
31
  </HairyLink>
32
- <span class="text-gray-5 text-size-5 mx-2">/</span>
33
- <HairyLink @click="$router.push(getArchiveLink(activity.year, activity.month))">
32
+ <span class="text-gray-5 mx-2">/</span>
33
+ <HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year, activity.month))">
34
34
  {{ activity.month }}
35
35
  </HairyLink>
36
36
  <span class="text-gray-5 text-size-5 ml-1">({{ activity.count }}篇)</span>
37
37
  </div>
38
+ <HairyTimelinePostItem v-for="(item, index) in activity.posts.slice(0, 2)" :key="index" :post="item" />
39
+ <div v-if="activity.posts.length > 2">
40
+ <HairyLink @click="$router.push(getArchiveLink(activity.year))">
41
+ ....
42
+ </HairyLink>
43
+ </div>
38
44
  </el-timeline-item>
39
45
  </el-timeline>
40
46
  </template>
@@ -22,18 +22,20 @@ const router = useRouter()
22
22
 
23
23
  const paths = computed(() => props.categories.split('/').filter(Boolean))
24
24
  const current = useCurrentCategory(paths)
25
-
26
25
  const posts = useCategoryPost(paths)
27
26
 
28
27
  const i18n = useI18n()
29
28
 
29
+ const s = '/'
30
+
30
31
  const getBreadcrumbPath = (index: number) => {
31
- if (paths.value[index] === paths.value[paths.value.length - 1])
32
+ const paths = props.categories.split('/').filter(Boolean)
33
+ if (paths[index] === paths[paths.length - 1])
32
34
  return ''
33
- return `/categories/${paths.value.slice(0, index)}`
35
+ return `/categories/${paths.slice(0, index + 1).join('/')}`
34
36
  }
35
37
  const displayCategory = (key: string) => {
36
- router.push({ path: `/categories/${[...paths.value, key].join('/')}` })
38
+ router.push({ path: `/categories/${[key, ...paths.value].reverse().join('/')}` })
37
39
  }
38
40
  </script>
39
41
 
@@ -45,10 +47,11 @@ const displayCategory = (key: string) => {
45
47
  <HairyBreadcrumbItem :to="paths.length && '/categories/' || ''">
46
48
  全部
47
49
  </HairyBreadcrumbItem>
48
- <HairyBreadcrumbItem v-for="(key, index) in paths" :key="key" :to="getBreadcrumbPath(index)">
50
+ <HairyBreadcrumbItem v-for="(key, index) in categories.split(s)" :key="key" :to="getBreadcrumbPath(index)">
49
51
  {{ i18n.t(key) }}
50
52
  </HairyBreadcrumbItem>
51
53
  </HairyBreadcrumb>
54
+
52
55
  <div class="grid__view dark:text-gray-3 flex-wrap">
53
56
  <template v-for="([key, item]) in current.children" :key="key">
54
57
  <div
package/pages/index.vue CHANGED
@@ -1,11 +1,5 @@
1
- <script lang="ts" setup>
2
- import { usePostLayout } from '../hooks/usePostLayout'
3
- const layout = usePostLayout()
4
- </script>
5
-
6
1
  <template>
7
- <HairyPostImageList v-if="layout.includes('image')" />
8
- <HairyPostList v-else />
2
+ <HairyPostList :pagination="true" />
9
3
  </template>
10
4
 
11
5
  <route lang="yaml">
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ defineProps<{ page: string }>()
3
+ </script>
4
+
5
+ <template>
6
+ <HairyPostList :pagination="true" :cur-page="parseInt(page)" />
7
+ </template>
8
+
9
+ <route lang="yaml">
10
+ meta:
11
+ layout: home
12
+ </route>
@@ -4,7 +4,7 @@ import { useRouter } from 'vue-router'
4
4
  const router = useRouter()
5
5
 
6
6
  const { tags, getTagStyle } = useTags({
7
- primary: 'red',
7
+ primary: '#1bc9a6',
8
8
  })
9
9
 
10
10
  const displayTag = (tag: string) => {
@@ -17,7 +17,7 @@ const displayTag = (tag: string) => {
17
17
  <div text="center" class="text-size-2.5em pt-10 mb-5">
18
18
  目前共计 {{ Array.from(tags).length }} 个标签
19
19
  </div>
20
- <div text="center">
20
+ <div text="center" class="max-w-7xl flex flex-wrap justify-center items-center gap-2">
21
21
  <a v-for="[key, tag] in Array.from(tags).sort()" :key="key" class="post-tag cursor-pointer" :style="getTagStyle(tag.count)" p="1" @click="displayTag(key.toString())">
22
22
  {{ key }}
23
23
  </a>
@@ -29,3 +29,13 @@ const displayTag = (tag: string) => {
29
29
  meta:
30
30
  layout: tags
31
31
  </route>
32
+
33
+ <style lang="scss" scoped>
34
+ a {
35
+ color: var(--yun-tag-color);
36
+ &:hover {
37
+ --un-text-opacity: 1;
38
+ color: var(--hy-c-primary-dark);
39
+ }
40
+ }
41
+ </style>
@@ -14,7 +14,7 @@
14
14
  src: url('./fonts/Modesty.ttf')
15
15
  }
16
16
 
17
- @font-face {
18
- font-family: "Seto";
19
- src: url('./fonts/Seto.ttf')
20
- }
17
+ // @font-face {
18
+ // font-family: "Seto";
19
+ // src: url('./fonts/Seto.ttf')
20
+ // }
package/styles/index.scss CHANGED
@@ -65,4 +65,8 @@ body {
65
65
  .breakpoint {
66
66
  width: 75vw;
67
67
  }
68
+ }
69
+
70
+ body {
71
+ // background-image: linear-gradient(to top, #f7f7f7 0, #fdfdfd 20%) no-repeat bottom;
68
72
  }
package/utils/fonts.ts ADDED
@@ -0,0 +1,15 @@
1
+ import Seto from '../styles/fonts/Seto.ttf?url'
2
+ import { createPromise } from '.'
3
+
4
+ export const fontFacePromise = createPromise<void>()
5
+
6
+ async function loadFonts(fontFamily: string, url: string) {
7
+ const font = new FontFace(fontFamily, `url(${url})`)
8
+ await font.load()
9
+ ;(document.fonts as any).add(font)
10
+ }
11
+
12
+ (async () => {
13
+ await loadFonts('Seto', Seto)
14
+ fontFacePromise.resolve()
15
+ })()
package/utils/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { isNumber, isString } from 'lodash-es'
2
+
1
3
  /**
2
4
  * 跳转到新的页面
3
5
  * @param url 跳转url
@@ -26,3 +28,28 @@ export const toArr = <T>(arr: T[] | T): T[] => {
26
28
  return arr as any
27
29
  else return [arr].filter(Boolean) as any
28
30
  }
31
+
32
+ export type AtWillNumber = string | number
33
+
34
+ export const atWillToUnit = (value: AtWillNumber, unit = 'px') => {
35
+ if (!(isString(value) || isNumber(value)))
36
+ return ''
37
+ return isString(value) && /\D/g.test(value) ? value : value + unit
38
+ }
39
+
40
+ export interface PromiseResolver<T = void> extends Promise<T> {
41
+ resolve: (value: T) => void
42
+ reject: Function
43
+ }
44
+ export function createPromise<T>(): PromiseResolver<T> {
45
+ let resolve
46
+ let reject
47
+ // eslint-disable-next-line promise/param-names
48
+ const promise: any = new Promise((_r, _j) => {
49
+ resolve = _r
50
+ reject = _j
51
+ })
52
+ promise.resolve = resolve
53
+ promise.reject = reject
54
+ return promise as PromiseResolver<T>
55
+ }
package/valaxy.config.ts CHANGED
@@ -12,6 +12,7 @@ export default defineTheme<HairyTheme>((options) => {
12
12
  return {
13
13
  vite: images.vite,
14
14
  pages: hairy.pages,
15
+ unocss: hairy.unocss,
15
16
  extendMd(ctx) {
16
17
  hairy.extendMd?.(ctx)
17
18
  images.extendMd?.(ctx)
@@ -1,531 +0,0 @@
1
- .vp-loading {
2
- position: absolute;
3
- top: 0;
4
- left: 0;
5
- z-index: 100;
6
- width: 100vw;
7
- height: 100vh;
8
- background: #eee;
9
-
10
- transition: opacity 0.5s;
11
-
12
- .wrapper {
13
- width: 50px;
14
- height: 50px;
15
- position: fixed;
16
- top: 50%;
17
- left: 50%;
18
- margin-left: -50px;
19
- margin-top: -50px;
20
-
21
- }
22
-
23
- #preloader {
24
- width: 50px;
25
- height: 50px;
26
- border: 2px solid var(--hy-c-primary);
27
- border-radius: 0px;
28
- -webkit-animation: preloader 4.5s infinite linear;
29
- -moz-animation: preloader 4.5s infinite linear;
30
- -ms-animation: preloader 4.5s infinite linear;
31
- animation: preloader 4.5s infinite linear;
32
- }
33
-
34
- #preloader:after {
35
- content: '';
36
- width: 14px;
37
- height: 14px;
38
- background: var(--hy-c-primary);
39
- position: absolute;
40
- top: 50%;
41
- left: 50%;
42
- margin-left: -7px;
43
- margin-top: -7px;
44
- border-radius: 20px;
45
- -webkit-animation: preloader_after 4.5s infinite linear;
46
- -moz-animation: preloader_after 4.5s infinite linear;
47
- -ms-animation: preloader_after 4.5s infinite linear;
48
- animation: preloader_after 4.5s infinite linear;
49
- -webkit-transform: scale(0);
50
- }
51
-
52
- @-webkit-keyframes preloader {
53
- 0% {
54
- -webkit-transform: scale(0)
55
- }
56
-
57
- 10% {
58
- -webkit-transform: scale(1.3)
59
- }
60
-
61
- 12% {
62
- -webkit-transform: scale(1)
63
- }
64
-
65
- 15% {
66
- -webkit-transform: scale(1.3)
67
- }
68
-
69
- 17% {
70
- -webkit-transform: scale(1)
71
- }
72
-
73
- 25% {
74
- -webkit-transform: scale(1)
75
- }
76
-
77
- 40% {
78
- -webkit-transform: scale(1) rotate(180deg);
79
- border-radius: 20px;
80
- }
81
-
82
- 42% {
83
- -webkit-transform: scale(1) rotate(180deg);
84
- border-radius: 0px;
85
- }
86
-
87
- 44% {
88
- -webkit-transform: scale(1) rotate(180deg);
89
- border-radius: 20px;
90
- }
91
-
92
- 46% {
93
- -webkit-transform: scale(1) rotate(180deg);
94
- border-radius: 0px;
95
- }
96
-
97
- 48% {
98
- -webkit-transform: scale(1) rotate(180deg);
99
- border-radius: 20px;
100
- }
101
-
102
- 50% {
103
- -webkit-transform: scale(1) rotate(180deg);
104
- border-radius: 20px;
105
- }
106
-
107
- 95% {
108
- -webkit-transform: scale(1) rotate(180deg);
109
- border-radius: 20px;
110
- }
111
-
112
- 100% {
113
- -webkit-transform: scale(0) rotate(180deg);
114
- border-radius: 100px;
115
- }
116
- }
117
-
118
- @-moz-keyframes preloader {
119
- 0% {
120
- -moz-transform: scale(0)
121
- }
122
-
123
- 10% {
124
- -moz-transform: scale(1.3)
125
- }
126
-
127
- 12% {
128
- -moz-transform: scale(1)
129
- }
130
-
131
- 15% {
132
- -moz-transform: scale(1.3)
133
- }
134
-
135
- 17% {
136
- -moz-transform: scale(1)
137
- }
138
-
139
- 25% {
140
- -moz-transform: scale(1)
141
- }
142
-
143
- 40% {
144
- -moz-transform: scale(1) rotate(180deg);
145
- border-radius: 20px;
146
- }
147
-
148
- 42% {
149
- -moz-transform: scale(1) rotate(180deg);
150
- border-radius: 0px;
151
- }
152
-
153
- 44% {
154
- -moz-transform: scale(1) rotate(180deg);
155
- border-radius: 20px;
156
- }
157
-
158
- 46% {
159
- -moz-transform: scale(1) rotate(180deg);
160
- border-radius: 0px;
161
- }
162
-
163
- 48% {
164
- -moz-transform: scale(1) rotate(180deg);
165
- border-radius: 20px;
166
- }
167
-
168
- 50% {
169
- -moz-transform: scale(1) rotate(180deg);
170
- border-radius: 20px;
171
- }
172
-
173
- 95% {
174
- -moz-transform: scale(1) rotate(180deg);
175
- border-radius: 20px;
176
- }
177
-
178
- 100% {
179
- -moz-transform: scale(0) rotate(180deg);
180
- border-radius: 100px;
181
- }
182
- }
183
-
184
- @-ms-keyframes preloader {
185
- 0% {
186
- -ms-transform: scale(0)
187
- }
188
-
189
- 10% {
190
- -ms-transform: scale(1.3)
191
- }
192
-
193
- 12% {
194
- -ms-transform: scale(1)
195
- }
196
-
197
- 15% {
198
- -ms-transform: scale(1.3)
199
- }
200
-
201
- 17% {
202
- -ms-transform: scale(1)
203
- }
204
-
205
- 25% {
206
- -ms-transform: scale(1)
207
- }
208
-
209
- 40% {
210
- -ms-transform: scale(1) rotate(180deg);
211
- border-radius: 20px;
212
- }
213
-
214
- 42% {
215
- -ms-transform: scale(1) rotate(180deg);
216
- border-radius: 0px;
217
- }
218
-
219
- 44% {
220
- -ms-transform: scale(1) rotate(180deg);
221
- border-radius: 20px;
222
- }
223
-
224
- 46% {
225
- -ms-transform: scale(1) rotate(180deg);
226
- border-radius: 0px;
227
- }
228
-
229
- 48% {
230
- -ms-transform: scale(1) rotate(180deg);
231
- border-radius: 20px;
232
- }
233
-
234
- 50% {
235
- -ms-transform: scale(1) rotate(180deg);
236
- border-radius: 20px;
237
- }
238
-
239
- 95% {
240
- -ms-transform: scale(1) rotate(180deg);
241
- border-radius: 20px;
242
- }
243
-
244
- 100% {
245
- -ms-transform: scale(0) rotate(180deg);
246
- border-radius: 100px;
247
- }
248
- }
249
-
250
- @keyframes preloader {
251
- 0% {
252
- transform: scale(0)
253
- }
254
-
255
- 10% {
256
- transform: scale(1.3)
257
- }
258
-
259
- 12% {
260
- transform: scale(1)
261
- }
262
-
263
- 15% {
264
- transform: scale(1.3)
265
- }
266
-
267
- 17% {
268
- transform: scale(1)
269
- }
270
-
271
- 25% {
272
- transform: scale(1)
273
- }
274
-
275
- 40% {
276
- transform: scale(1) rotate(180deg);
277
- border-radius: 20px;
278
- }
279
-
280
- 42% {
281
- transform: scale(1) rotate(180deg);
282
- border-radius: 0px;
283
- }
284
-
285
- 44% {
286
- transform: scale(1) rotate(180deg);
287
- border-radius: 20px;
288
- }
289
-
290
- 46% {
291
- transform: scale(1) rotate(180deg);
292
- border-radius: 0px;
293
- }
294
-
295
- 48% {
296
- transform: scale(1) rotate(180deg);
297
- border-radius: 20px;
298
- }
299
-
300
- 50% {
301
- transform: scale(1) rotate(180deg);
302
- border-radius: 20px;
303
- }
304
-
305
- 95% {
306
- transform: scale(1) rotate(180deg);
307
- border-radius: 20px;
308
- }
309
-
310
- 100% {
311
- transform: scale(0) rotate(180deg);
312
- border-radius: 100px;
313
- }
314
- }
315
-
316
- @-webkit-keyframes preloader_after {
317
- 0% {
318
- -webkit-transform: scale(0);
319
- }
320
-
321
- 45% {
322
- -webkit-transform: scale(0);
323
- }
324
-
325
- 50% {
326
- -webkit-transform: scale(1);
327
- }
328
-
329
- 55% {
330
- -webkit-transform: scale(1) translateY(-20px) translateX(-14px);
331
- }
332
-
333
- 60% {
334
- -webkit-transform: scale(1) translateY(20px) translateX(14px);
335
- }
336
-
337
- 65% {
338
- -webkit-transform: scale(1) translateY(-20px) translateX(14px);
339
- }
340
-
341
- 70% {
342
- -webkit-transform: scale(1) translateY(20px) translateX(-14px);
343
- }
344
-
345
- 75% {
346
- -webkit-transform: scale(1) translateY(-20px) translateX(14px);
347
- }
348
-
349
- 80% {
350
- -webkit-transform: scale(1) translateY(20px) translateX(-14px);
351
- }
352
-
353
- 85% {
354
- -webkit-transform: scale(1) translateY(-20px) translateX(-14px);
355
- }
356
-
357
- 90% {
358
- -webkit-transform: scale(1) translateY(0px) translateX(0px);
359
- }
360
-
361
- 95% {
362
- -webkit-transform: scale(1.5);
363
- }
364
-
365
- 100% {
366
- -webkit-transform: scale(0);
367
- }
368
- }
369
-
370
- @-moz-keyframes preloader_after {
371
- 0% {
372
- -moz-transform: scale(0);
373
- }
374
-
375
- 45% {
376
- -moz-transform: scale(0);
377
- }
378
-
379
- 50% {
380
- -moz-transform: scale(1);
381
- }
382
-
383
- 55% {
384
- -moz-transform: scale(1) translateY(-20px) translateX(-14px);
385
- }
386
-
387
- 60% {
388
- -moz-transform: scale(1) translateY(20px) translateX(14px);
389
- }
390
-
391
- 65% {
392
- -moz-transform: scale(1) translateY(-20px) translateX(14px);
393
- }
394
-
395
- 70% {
396
- -moz-transform: scale(1) translateY(20px) translateX(-14px);
397
- }
398
-
399
- 75% {
400
- -moz-transform: scale(1) translateY(-20px) translateX(14px);
401
- }
402
-
403
- 80% {
404
- -moz-transform: scale(1) translateY(20px) translateX(-14px);
405
- }
406
-
407
- 85% {
408
- -moz-transform: scale(1) translateY(-20px) translateX(-14px);
409
- }
410
-
411
- 90% {
412
- -moz-transform: scale(1) translateY(0px) translateX(0px);
413
- }
414
-
415
- 95% {
416
- -moz-transform: scale(1.5);
417
- }
418
-
419
- 100% {
420
- -moz-transform: scale(0);
421
- }
422
- }
423
-
424
- @-ms-keyframes preloader_after {
425
- 0% {
426
- -ms-transform: scale(0);
427
- }
428
-
429
- 45% {
430
- -ms-transform: scale(0);
431
- }
432
-
433
- 50% {
434
- -ms-transform: scale(1);
435
- }
436
-
437
- 55% {
438
- -ms-transform: scale(1) translateY(-20px) translateX(-14px);
439
- }
440
-
441
- 60% {
442
- -ms-transform: scale(1) translateY(20px) translateX(14px);
443
- }
444
-
445
- 65% {
446
- -ms-transform: scale(1) translateY(-20px) translateX(14px);
447
- }
448
-
449
- 70% {
450
- -ms-transform: scale(1) translateY(20px) translateX(-14px);
451
- }
452
-
453
- 75% {
454
- -ms-transform: scale(1) translateY(-20px) translateX(14px);
455
- }
456
-
457
- 80% {
458
- -ms-transform: scale(1) translateY(20px) translateX(-14px);
459
- }
460
-
461
- 85% {
462
- -ms-transform: scale(1) translateY(-20px) translateX(-14px);
463
- }
464
-
465
- 90% {
466
- -ms-transform: scale(1) translateY(0px) translateX(0px);
467
- }
468
-
469
- 95% {
470
- -ms-transform: scale(1.5);
471
- }
472
-
473
- 100% {
474
- -ms-transform: scale(0);
475
- }
476
- }
477
-
478
- @keyframes preloader_after {
479
- 0% {
480
- transform: scale(0);
481
- }
482
-
483
- 45% {
484
- transform: scale(0);
485
- }
486
-
487
- 50% {
488
- transform: scale(1);
489
- }
490
-
491
- 55% {
492
- transform: scale(1) translateY(-20px) translateX(-14px);
493
- }
494
-
495
- 60% {
496
- transform: scale(1) translateY(20px) translateX(14px);
497
- }
498
-
499
- 65% {
500
- transform: scale(1) translateY(-20px) translateX(14px);
501
- }
502
-
503
- 70% {
504
- transform: scale(1) translateY(20px) translateX(-14px);
505
- }
506
-
507
- 75% {
508
- transform: scale(1) translateY(-20px) translateX(14px);
509
- }
510
-
511
- 80% {
512
- transform: scale(1) translateY(20px) translateX(-14px);
513
- }
514
-
515
- 85% {
516
- transform: scale(1) translateY(-20px) translateX(-14px);
517
- }
518
-
519
- 90% {
520
- transform: scale(1) translateY(0px) translateX(0px);
521
- }
522
-
523
- 95% {
524
- transform: scale(1.5);
525
- }
526
-
527
- 100% {
528
- transform: scale(0);
529
- }
530
- }
531
- }
package/utils/loading.ts DELETED
@@ -1,30 +0,0 @@
1
- import './loading.scss'
2
-
3
- function createElement() {
4
- const loadingEl = document.createElement('div')
5
- loadingEl.className = 'vp-loading'
6
- loadingEl.innerHTML = `\
7
- <div class="wrapper">
8
- <div id="preloader"></div>
9
- </div>
10
- `
11
- return loadingEl
12
- }
13
-
14
- let el: HTMLElement
15
-
16
- export function showFullLoading() {
17
- if (!el)
18
- el = createElement()
19
- el.style.opacity = '0'
20
- document.body.appendChild(el)
21
- setTimeout(() => el.style.opacity = '1')
22
- }
23
-
24
- export function hideFullLoading() {
25
- if (!el)
26
- return
27
- el.style.opacity = '0'
28
- setTimeout(() => el.remove(), 500)
29
- }
30
-