mirror of https://github.com/YunYouJun/valaxy
fix(theme-yun): background-attach: fixed; compatible with ios
This commit is contained in:
parent
13d5e2da0d
commit
50a508b704
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
layout: post
|
||||
title: new-test
|
||||
date: 2023-01-26 06:00:15
|
||||
---
|
||||
|
|
@ -20,6 +20,7 @@ export default defineValaxyConfig<ThemeConfig>({
|
|||
// colors: {
|
||||
// primary: 'red',
|
||||
// },
|
||||
// bg_image: {},
|
||||
|
||||
banner: {
|
||||
enable: true,
|
||||
|
|
|
@ -17,3 +17,10 @@ pnpm test:space
|
|||
超过 50 篇文章时需要超过 2G 内存。
|
||||
|
||||
内存使用需要优化……
|
||||
|
||||
## `background-attachment: fixed` iOS 不支持
|
||||
|
||||
> iOS has an issue preventing background-attachment: fixed from being used with background-size: cover.
|
||||
> [The Fixed Background Attachment Hack | CSS Tricks](https://css-tricks.com/the-fixed-background-attachment-hack/)
|
||||
|
||||
改为使用 `::before` 伪元素实现。
|
||||
|
|
|
@ -70,7 +70,7 @@ const app = useAppStore()
|
|||
height: calc(100vh - var(--pr-nav-height) - 32px);
|
||||
}
|
||||
|
||||
@include media('xl') {
|
||||
@include screen('xl') {
|
||||
.aside-container {
|
||||
top: 0;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ function scrollToTop() {
|
|||
transition: border-color 0.5s;
|
||||
}
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.press-local-nav {
|
||||
display: none;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ function scrollToTop() {
|
|||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.menu {
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ function scrollToTop() {
|
|||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.top-link {
|
||||
padding: 12px 32px 11px;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ const classes = computed(() => ({
|
|||
background-color: var(--pr-nav-bg-color);
|
||||
}
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.press-nav {
|
||||
-webkit-backdrop-filter: saturate(50%) blur(8px);
|
||||
backdrop-filter: saturate(50%) blur(8px);
|
||||
|
|
|
@ -60,13 +60,13 @@ const themeConfig = useThemeConfig()
|
|||
background-color: var(--pr-navbar-c-bg);
|
||||
}
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.pr-navbar {
|
||||
padding: 0 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.pr-navbar.has-sidebar .content {
|
||||
margin-right: -32px;
|
||||
padding-right: 32px;
|
||||
|
|
|
@ -68,7 +68,7 @@ const { hasSidebar } = useSidebar()
|
|||
}
|
||||
}
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.press-sidebar {
|
||||
z-index: 1;
|
||||
width: var(--va-sidebar-width);
|
||||
|
|
|
@ -67,7 +67,7 @@ const isHome = useLayout('home')
|
|||
<style lang="scss">
|
||||
@use 'valaxy/client/styles/mixins' as *;
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.press-main {
|
||||
&.has-sidebar {
|
||||
padding-top: var(--pr-nav-height);
|
||||
|
@ -76,7 +76,7 @@ const isHome = useLayout('home')
|
|||
}
|
||||
}
|
||||
|
||||
@include media('xl') {
|
||||
@include screen('xl') {
|
||||
.content{
|
||||
// 8px scrollbar width
|
||||
max-width: calc(100vw - 2 * var(--va-sidebar-width) - 2.5rem);
|
||||
|
|
|
@ -70,7 +70,7 @@ const aside = computed(() => props.frontmatter.aside !== false)
|
|||
<style lang="scss">
|
||||
@use 'valaxy/client/styles/mixins' as *;
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
.yun-main {
|
||||
&.has-sidebar {
|
||||
padding-left: var(--va-sidebar-width);
|
||||
|
@ -78,7 +78,7 @@ const aside = computed(() => props.frontmatter.aside !== false)
|
|||
}
|
||||
}
|
||||
|
||||
@include media('xl') {
|
||||
@include screen('xl') {
|
||||
.content{
|
||||
// 8px scrollbar width
|
||||
max-width: calc(100vw - 2 * var(--va-sidebar-width) - 1rem - 8px);
|
||||
|
|
|
@ -69,7 +69,7 @@ const app = useAppStore()
|
|||
}
|
||||
}
|
||||
|
||||
@include media('xl') {
|
||||
@include screen('xl') {
|
||||
.aside {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
|
|
@ -22,16 +22,16 @@ const chars = computed(() => {
|
|||
// height of top/bottom line
|
||||
const lineH = computed(() => chars.value.reduce((a, b) => a + b, 0) / 2)
|
||||
|
||||
const lintStyle = computed(() => (
|
||||
const lineStyle = computed(() => (
|
||||
{
|
||||
'--banner-line-height': `calc(50vh - ${lineH.value}rem)`,
|
||||
'--banner-line-height': `calc(var(--app-height, 100vh) / 2 - ${lineH.value}rem)`,
|
||||
} as CSSProperties
|
||||
))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="banner">
|
||||
<div class="banner-line vertical-line-top" :style="lintStyle" />
|
||||
<div id="banner" :style="lineStyle">
|
||||
<div class="banner-line vertical-line-top" :style="lineStyle" />
|
||||
<div class="banner-char-container">
|
||||
<div v-for="c, i in themeConfig.banner.title" :key="i" class="char-box">
|
||||
<span
|
||||
|
@ -45,10 +45,11 @@ const lintStyle = computed(() => (
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="banner-line vertical-line-bottom" :style="lintStyle" />
|
||||
<div class="banner-line vertical-line-bottom" :style="lineStyle" />
|
||||
</div>
|
||||
|
||||
<YunGoDown />
|
||||
<YunCloud v-if="themeConfig.banner.cloud?.enable" />
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { computed, watch } from 'vue'
|
||||
import { useThemeConfig } from 'valaxy-theme-yun/composables'
|
||||
import { useCssVar } from '@vueuse/core'
|
||||
import { isDark } from 'valaxy'
|
||||
|
@ -10,37 +10,50 @@ const bgImgOpacity = useCssVar('--va-bg-img-opacity')
|
|||
if (themeConfig.value.bg_image.opacity)
|
||||
bgImgOpacity.value = themeConfig.value.bg_image.opacity.toString() || '1'
|
||||
|
||||
const styles = computed(() => {
|
||||
return {
|
||||
backgroundImage: `url('${isDark.value
|
||||
? themeConfig.value.bg_image.dark
|
||||
: themeConfig.value.bg_image.url
|
||||
}')`,
|
||||
}
|
||||
const bgImgUrl = computed(() => {
|
||||
return isDark.value
|
||||
? themeConfig.value.bg_image.dark
|
||||
: themeConfig.value.bg_image.url
|
||||
})
|
||||
|
||||
const bgImgCssVar = useCssVar('--va-bg-img')
|
||||
|
||||
watch(() => bgImgUrl.value, () => {
|
||||
bgImgCssVar.value = `url('${bgImgUrl.value}')`
|
||||
}, { immediate: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="va-bg" :style="styles" />
|
||||
<div class="va-bg" />
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@use 'valaxy/client/styles/mixins' as *;
|
||||
|
||||
.va-bg {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background-image: var(--va-bg-image);
|
||||
|
||||
background-image: var(--va-bg-img);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
// avoid flicker
|
||||
// avoid scroll flicker but not compatible with ios
|
||||
background-attachment: fixed;
|
||||
animation-name: bgFadeIn;
|
||||
animation-duration: 2s;
|
||||
opacity: var(--va-bg-img-opacity, 1);
|
||||
}
|
||||
|
||||
// for ios
|
||||
@include ios {
|
||||
.va-bg {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bgFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
width: 100%;
|
||||
height: 100px;
|
||||
|
||||
@include media('md') {
|
||||
@include screen('md') {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ const footerIcon = computed(() => themeConfig.value.footer.icon || {
|
|||
</div>
|
||||
|
||||
<div v-if="themeConfig.footer.powered" class="powered" m="2">
|
||||
<span v-html="poweredHtml" /> | <span>{{ t('footer.theme') }} - <a :href="themeConfig.pkg.homepage" :title="themeConfig.pkg.name" target="_blank">{{ capitalize(config.theme) }}</a> v{{ themeConfig.pkg.version }}</span>
|
||||
<span v-html="poweredHtml" /> | <span>{{ t('footer.theme') }} - <a :href="themeConfig.pkg.repository.url" :title="themeConfig.pkg.name" target="_blank">{{ capitalize(config.theme) }}</a> v{{ themeConfig.pkg.version }}</span>
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
|
|
|
@ -17,7 +17,6 @@ const themeConfig = useThemeConfig()
|
|||
|
||||
<YunBanner />
|
||||
<YunSay v-if="themeConfig.say.enable" w="full" />
|
||||
<YunCloud v-if="themeConfig.banner.cloud?.enable" />
|
||||
<YunNotice
|
||||
v-if="themeConfig.notice.enable"
|
||||
:content="themeConfig.notice.content" mt="4"
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
$light: () !default;
|
||||
$light: map.merge(
|
||||
(
|
||||
"bg-image":
|
||||
"bg-img":
|
||||
url("https://cdn.yunyoujun.cn/img/bg/stars-timing-0-blur-30px.jpg"),
|
||||
"sidebar-bg-color": var(--va-c-bg-light),
|
||||
"sidebar-bg-image":
|
||||
"sidebar-bg-img":
|
||||
url("https://cdn.yunyoujun.cn/img/bg/alpha-stars-timing-1.webp"),
|
||||
),
|
||||
$light
|
||||
|
@ -16,8 +16,8 @@ $light: map.merge(
|
|||
$dark: () !default;
|
||||
$dark: map.merge(
|
||||
(
|
||||
"bg-image": none,
|
||||
"sidebar-bg-image": none,
|
||||
"bg-img": none,
|
||||
"sidebar-bg-img": none,
|
||||
),
|
||||
$dark
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, provide, ref } from 'vue'
|
||||
import { computed, onBeforeMount, provide, ref } from 'vue'
|
||||
import { useHead, useSeoMeta } from '@vueuse/head'
|
||||
// @ts-expect-error virtual module
|
||||
import ValaxyUserApp from '/@valaxyjs/UserAppVue'
|
||||
|
@ -66,6 +66,11 @@ useSeoMeta({
|
|||
|
||||
const onContentUpdated = ref()
|
||||
provide('onContentUpdated', onContentUpdated)
|
||||
|
||||
onBeforeMount(() => {
|
||||
// for browser with nav bar height
|
||||
document.documentElement.style.setProperty('--app-height', `${window.innerHeight}px`)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -4,7 +4,7 @@ import valaxyLogoPng from '../assets/images/valaxy-logo.png'
|
|||
|
||||
<template>
|
||||
<div class="valaxy-logo-container" relative inline-flex justify="center" items="center">
|
||||
<div class="absolute bg-image" />
|
||||
<div class="absolute bg-img" />
|
||||
<img max-w="50" m="auto" :src="valaxyLogoPng" alt="Valaxy Logo" z="1">
|
||||
</div>
|
||||
</template>
|
||||
|
@ -12,12 +12,12 @@ import valaxyLogoPng from '../assets/images/valaxy-logo.png'
|
|||
<style lang="scss" scoped>
|
||||
.valaxy-logo-container {
|
||||
&:hover {
|
||||
.bg-image {
|
||||
.bg-img {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bg-image {
|
||||
.bg-img {
|
||||
border-radius: 50%;
|
||||
filter: blur(72px);
|
||||
max-width: 350px;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { TinyColor } from '@ctrl/tinycolor'
|
||||
import { computed } from 'vue'
|
||||
import type { Post } from '../..'
|
||||
import { usePostList } from './post'
|
||||
|
||||
|
@ -47,32 +48,32 @@ export function useTags(options: {
|
|||
export function useTag() {
|
||||
const posts = usePostList()
|
||||
|
||||
const tagMap: Tags = new Map()
|
||||
return computed(() => {
|
||||
const tagMap: Tags = new Map()
|
||||
posts.value.forEach((post: Post) => {
|
||||
if (post.tags) {
|
||||
let tags: string[]
|
||||
if (typeof post.tags === 'string')
|
||||
tags = [post.tags]
|
||||
else
|
||||
tags = post.tags
|
||||
|
||||
posts.value.forEach((post: Post) => {
|
||||
if (post.tags) {
|
||||
let tags: string[]
|
||||
if (typeof post.tags === 'string')
|
||||
tags = [post.tags]
|
||||
else
|
||||
tags = post.tags
|
||||
|
||||
tags.forEach((tag) => {
|
||||
if (tagMap.has(tag)) {
|
||||
const item = tagMap.get(tag)!
|
||||
tagMap.set(tag, {
|
||||
...item,
|
||||
count: item.count + 1,
|
||||
})
|
||||
}
|
||||
else {
|
||||
tagMap.set(tag, {
|
||||
count: 1,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
tags.forEach((tag) => {
|
||||
if (tagMap.has(tag)) {
|
||||
const item = tagMap.get(tag)!
|
||||
tagMap.set(tag, {
|
||||
...item,
|
||||
count: item.count + 1,
|
||||
})
|
||||
}
|
||||
else {
|
||||
tagMap.set(tag, {
|
||||
count: 1,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return tagMap
|
||||
})
|
||||
|
||||
return tagMap
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
width: calc(100vw - 64px);
|
||||
max-width: var(--va-sidebar-width);
|
||||
|
||||
background-image: var(--yun-sidebar-bg-image);
|
||||
background-image: var(--yun-sidebar-bg-img);
|
||||
background-color: var(--yun-sidebar-bg-color);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@forward './config.scss';
|
||||
@forward './media.scss';
|
||||
@forward './size.scss';
|
||||
@forward './variable.scss';
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
@mixin ios {
|
||||
@supports (-webkit-touch-callout: none) {
|
||||
/* CSS specific to iOS devices */
|
||||
@content;
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ $breakpoints: (
|
|||
}
|
||||
}
|
||||
|
||||
@mixin media($size) {
|
||||
@mixin screen($size) {
|
||||
@media screen and (min-width: map.get($breakpoints, $size)) {
|
||||
@content;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ $char-animation-duration: 0.4s;
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
height: var(--app-height, 100vh);
|
||||
}
|
||||
|
||||
.banner-char-container {
|
||||
|
|
Loading…
Reference in New Issue