fix(theme-yun): background-attach: fixed; compatible with ios

This commit is contained in:
YunYouJun 2023-01-26 23:24:17 +08:00
parent 13d5e2da0d
commit 50a508b704
25 changed files with 104 additions and 75 deletions

View File

@ -1,6 +0,0 @@
---
layout: post
title: new-test
date: 2023-01-26 06:00:15
---

View File

@ -20,6 +20,7 @@ export default defineValaxyConfig<ThemeConfig>({
// colors: {
// primary: 'red',
// },
// bg_image: {},
banner: {
enable: true,

View File

@ -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` 伪元素实现。

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -68,7 +68,7 @@ const { hasSidebar } = useSidebar()
}
}
@include media('md') {
@include screen('md') {
.press-sidebar {
z-index: 1;
width: var(--va-sidebar-width);

View File

@ -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);

View File

@ -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);

View File

@ -69,7 +69,7 @@ const app = useAppStore()
}
}
@include media('xl') {
@include screen('xl') {
.aside {
transform: translateX(0);
}

View File

@ -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">

View File

@ -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;

View File

@ -34,7 +34,7 @@
width: 100%;
height: 100px;
@include media('md') {
@include screen('md') {
height: 40px;
}
}

View File

@ -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 />

View File

@ -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"

View File

@ -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
);

View File

@ -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>

View File

@ -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;

View File

@ -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
}

View File

@ -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;

View File

@ -1,3 +1,4 @@
@forward './config.scss';
@forward './media.scss';
@forward './size.scss';
@forward './variable.scss';

View File

@ -0,0 +1,6 @@
@mixin ios {
@supports (-webkit-touch-callout: none) {
/* CSS specific to iOS devices */
@content;
}
}

View File

@ -41,7 +41,7 @@ $breakpoints: (
}
}
@mixin media($size) {
@mixin screen($size) {
@media screen and (min-width: map.get($breakpoints, $size)) {
@content;
}

View File

@ -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 {