index.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <el-switch
  3. v-if="'technology' != theme.themeName && 'plain' != theme.themeName && route.path !== '/goods/posterDesign'"
  4. v-model="mode"
  5. :active-icon="Moon"
  6. active-value="dark"
  7. class="vab-dark"
  8. :inactive-icon="Sunny"
  9. inactive-value="light"
  10. inline-prompt
  11. @click="_toggleDark($event)"
  12. />
  13. </template>
  14. <script lang="ts" setup>
  15. // @ts-nocheck
  16. import { Moon, Sunny } from '@element-plus/icons-vue'
  17. import { useSettingsStore } from '/@/store/modules/settings'
  18. defineOptions({
  19. name: 'VabDark',
  20. })
  21. const route = useRoute()
  22. const settingsStore = useSettingsStore()
  23. const { theme, mode } = storeToRefs(settingsStore)
  24. const { updateMode } = settingsStore
  25. const _toggleDark = async (event: MouseEvent) => {
  26. if (typeof document.startViewTransition === 'function') {
  27. const x = event.clientX
  28. const y = event.clientY
  29. const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y))
  30. let isDark: boolean
  31. const transition = document.startViewTransition(() => {
  32. const root = document.documentElement
  33. isDark = root.classList.contains('dark')
  34. root.classList.remove(isDark ? 'dark' : 'light')
  35. root.classList.add(isDark ? 'light' : 'dark')
  36. handleSetScheme(isDark ? 'light' : 'dark')
  37. })
  38. await transition.ready.then(() => {
  39. const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`]
  40. document.documentElement.animate(
  41. {
  42. clipPath: isDark ? [...clipPath].reverse() : clipPath,
  43. },
  44. {
  45. duration: 500,
  46. easing: 'ease-in',
  47. pseudoElement: isDark ? '::view-transition-old(root)' : '::view-transition-new(root)',
  48. }
  49. )
  50. })
  51. } else {
  52. const toggleDark = useToggle(handleUseDark())
  53. await toggleDark()
  54. }
  55. await updateMode(localStorage.getItem('vueuse-color-scheme'))
  56. }
  57. const handleUseDark = () => {
  58. return useDark()
  59. }
  60. const handleGetScheme = () => {
  61. return localStorage.getItem('vueuse-color-scheme')
  62. }
  63. const handleSetScheme = (value: string) => {
  64. return localStorage.setItem('vueuse-color-scheme', value)
  65. }
  66. onBeforeMount(() => {
  67. // 还原默认
  68. $sub('shop-vite-reset-dark', () => {
  69. mode.value = handleGetScheme()
  70. if (handleGetScheme() === 'dark') {
  71. handleSetScheme('light')
  72. handleUseDark()
  73. mode.value = 'light'
  74. }
  75. })
  76. handleUseDark()
  77. if (handleGetScheme() === 'auto') handleSetScheme('light')
  78. mode.value = handleGetScheme()
  79. })
  80. </script>
  81. <style lang="scss">
  82. ::view-transition-old(root),
  83. ::view-transition-new(root) {
  84. mix-blend-mode: normal;
  85. animation: none;
  86. }
  87. ::view-transition-old(root) {
  88. z-index: 999;
  89. }
  90. ::view-transition-new(root) {
  91. z-index: 1;
  92. }
  93. .dark {
  94. &::view-transition-old(root) {
  95. z-index: 1;
  96. }
  97. &::view-transition-new(root) {
  98. z-index: 999;
  99. }
  100. }
  101. .vab-dark {
  102. margin-left: var(--el-margin);
  103. }
  104. </style>