perf: improve dark-light theme transition performance

This commit is contained in:
Hakadao
2024-01-08 23:59:20 +08:00
parent 42e789cc12
commit f0511c01e1
3 changed files with 43 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { Icon } from '@iconify/vue'
import type { Ref } from 'vue'
import type { CurrentDockItem, HoveringDockItem } from './types'
import type { AppPage } from '~/enums/appEnums'
import { settings } from '~/logic'
@@ -11,8 +12,9 @@ defineProps<{ activatedPage: AppPage }>()
const emit = defineEmits(['change-page', 'settings-visibility-change'])
const mainStore = useMainStore()
const mainAppRef = inject('mainAppRef') as Ref<HTMLDivElement>
const mainStore = useMainStore()
const { t } = useI18n()
const hideDock = ref<boolean>(false)
@@ -103,10 +105,22 @@ function toggleDark(e: MouseEvent) {
Math.max(y, innerHeight - y),
)
// https://github.com/vueuse/vueuse/pull/3129
const style = window!.document.createElement('style')
const styleString = '*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}'
const style = document.createElement('style')
const styleString = `
*, *::before, *::after
{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`
style.appendChild(document.createTextNode(styleString))
window!.document.head.appendChild(style)
document.head.appendChild(style)
// Since the above normal dom style cannot be applied in shadow dom style
// We need to add this style again to the shadow dom
const shadowDomStyle = document.createElement('style')
const shadowDomStyleString = `
*, *::before, *::after
{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important; will-change: background}`
shadowDomStyle.appendChild(document.createTextNode(shadowDomStyleString))
mainAppRef.value.appendChild(shadowDomStyle)
// @ts-expect-error: Transition API
const transition = document.startViewTransition(async () => {
if (currentAppColorScheme.value === 'light')
@@ -128,8 +142,8 @@ function toggleDark(e: MouseEvent) {
: clipPath,
},
{
duration: 600,
easing: 'ease-in',
duration: 300,
easing: 'ease-in-out',
pseudoElement: currentAppColorScheme.value === 'dark'
? '::view-transition-old(root)'
: '::view-transition-new(root)',
@@ -137,6 +151,7 @@ function toggleDark(e: MouseEvent) {
)
animation.addEventListener('finish', () => {
document.head.removeChild(style!)
mainAppRef.value.removeChild(shadowDomStyle!)
}, { once: true })
})
}

View File

@@ -1,9 +1,12 @@
<script setup lang="ts">
import type { Ref } from 'vue'
import type { HoveringDockItem } from './types'
import { settings } from '~/logic'
const emit = defineEmits(['settings-visibility-change'])
const mainAppRef = inject('mainAppRef') as Ref<HTMLDivElement>
const hoveringDockItem = reactive<HoveringDockItem>({
themeMode: false,
settings: false,
@@ -35,10 +38,22 @@ function toggleDark(e: MouseEvent) {
Math.max(y, innerHeight - y),
)
// https://github.com/vueuse/vueuse/pull/3129
const style = window!.document.createElement('style')
const styleString = '*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}'
const style = document.createElement('style')
const styleString = `
*, *::before, *::after
{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`
style.appendChild(document.createTextNode(styleString))
window!.document.head.appendChild(style)
document.head.appendChild(style)
// Since normal dom style cannot be applied in shadow dom style
// We need to add this style again to the shadow dom
const shadowDomStyle = document.createElement('style')
const shadowDomStyleString = `
*, *::before, *::after
{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`
shadowDomStyle.appendChild(document.createTextNode(shadowDomStyleString))
mainAppRef.value.appendChild(shadowDomStyle)
// @ts-expect-error: Transition API
const transition = document.startViewTransition(async () => {
if (currentAppColorScheme.value === 'light')
@@ -60,8 +75,8 @@ function toggleDark(e: MouseEvent) {
: clipPath,
},
{
duration: 600,
easing: 'ease-in',
duration: 300,
easing: 'ease-in-out',
pseudoElement: currentAppColorScheme.value === 'dark'
? '::view-transition-old(root)'
: '::view-transition-new(root)',
@@ -69,6 +84,7 @@ function toggleDark(e: MouseEvent) {
)
animation.addEventListener('finish', () => {
document.head.removeChild(style!)
mainAppRef.value.removeChild(shadowDomStyle!)
}, { once: true })
})
}

View File

@@ -239,6 +239,7 @@ provide('handleBackToTop', handleBackToTop)
provide('handleRefresh', handleRefresh)
provide('activatedPage', activatedPage)
provide('scrollbarRef', scrollbarRef)
provide('mainAppRef', mainAppRef)
</script>
<template>