feat: 色弱模式和灰色模式

This commit is contained in:
wf 2024-05-06 16:07:17 +08:00
parent ef5f969340
commit 7e47315cab
4 changed files with 123 additions and 9 deletions

View File

@ -10,9 +10,8 @@ import { useThemeMethods } from "@/hooks/useThemeMethods";
// //
const onTheme = () => { const onTheme = () => {
let { setDarkMode, setThemeColor } = useThemeMethods(); let { initTheme } = useThemeMethods();
setDarkMode(); initTheme();
setThemeColor();
}; };
onTheme(); onTheme();

View File

@ -3,6 +3,22 @@ import { useThemeConfig } from "@/store/modules/theme-config";
import { generate, getRgbStr } from "@arco-design/color"; import { generate, getRgbStr } from "@arco-design/color";
/* 主题处理hooks */ /* 主题处理hooks */
export const useThemeMethods = () => { export const useThemeMethods = () => {
/**
* @description:
*/
const initTheme = () => {
// 黑暗模式和主题色
setDarkMode();
// 色弱模式和灰色模式
const themeStore = useThemeConfig();
const { grayMode } = storeToRefs(themeStore);
if (grayMode.value) {
setGray();
} else {
setColorWeak();
}
};
/** /**
* @description: * @description:
*/ */
@ -16,6 +32,8 @@ export const useThemeMethods = () => {
// 恢复亮色主题 // 恢复亮色主题
document.body.removeAttribute("arco-theme"); document.body.removeAttribute("arco-theme");
} }
// 黑暗模式切换后需要更新主题色
setThemeColor();
}; };
/** /**
@ -33,8 +51,45 @@ export const useThemeMethods = () => {
}); });
}; };
/**
* @description:
*/
const setColorWeak = () => {
// 获取html
const htmlCase = document.querySelector("html") as HTMLHtmlElement | null;
if (!htmlCase) return;
const themeStore = useThemeConfig();
const { colorWeakMode, grayMode } = storeToRefs(themeStore);
if (colorWeakMode.value) {
grayMode.value = false; // 色弱模式和灰色模式互斥
htmlCase.style.filter = "invert(80%)"; // 反转色80%
} else {
htmlCase.style.filter = "";
}
};
/**
* @description:
*/
const setGray = () => {
// 获取html
const htmlCase = document.querySelector("html") as HTMLHtmlElement | null;
if (!htmlCase) return;
const themeStore = useThemeConfig();
const { colorWeakMode, grayMode } = storeToRefs(themeStore);
if (grayMode.value) {
colorWeakMode.value = false; // 色弱模式和灰色模式互斥
htmlCase.style.filter = "grayscale(100%)"; // 灰度100%
} else {
htmlCase.style.filter = "";
}
};
return { return {
initTheme,
setDarkMode, setDarkMode,
setThemeColor setThemeColor,
setColorWeak,
setGray
}; };
}; };

View File

@ -18,17 +18,23 @@
<div class="box-gap"> <div class="box-gap">
<a-divider orientation="center">主题设置</a-divider> <a-divider orientation="center">主题设置</a-divider>
<div class="flex-center"> <div class="flex-center">
<a-color-picker v-model="themeColor" hide-trigger show-preset @change="themeColorChange" /> <a-color-picker
v-model="themeColor"
hide-trigger
show-preset
:preset-colors="presetColors"
@change="themeColorChange"
/>
</div> </div>
</div> </div>
<div class="box-gap"> <div class="box-gap">
<div class="flex-row"> <div class="flex-row">
<div>色弱模式</div> <div>色弱模式</div>
<a-switch /> <a-switch v-model="colorWeakMode" @change="onColorWeak" />
</div> </div>
<div class="flex-row"> <div class="flex-row">
<div>灰色模式</div> <div>灰色模式</div>
<a-switch /> <a-switch v-model="grayMode" @change="onGray" />
</div> </div>
<div class="flex-row"> <div class="flex-row">
<div>侧边栏深色</div> <div>侧边栏深色</div>
@ -52,7 +58,7 @@ import { useThemeConfig } from "@/store/modules/theme-config";
import { useThemeMethods } from "@/hooks/useThemeMethods"; import { useThemeMethods } from "@/hooks/useThemeMethods";
const themeStore = useThemeConfig(); const themeStore = useThemeConfig();
const { layoutType, themeColor } = storeToRefs(themeStore); const { layoutType, themeColor, presetColors, colorWeakMode, grayMode } = storeToRefs(themeStore);
const layoutList = reactive({ const layoutList = reactive({
layoutDefaults: { layoutDefaults: {
@ -79,6 +85,18 @@ const themeColorChange = (value: string) => {
setThemeColor(); setThemeColor();
}; };
//
const onColorWeak = () => {
const { setColorWeak } = useThemeMethods();
setColorWeak();
};
//
const onGray = () => {
const { setGray } = useThemeMethods();
setGray();
};
// //
const layouetChange = (type: string) => { const layouetChange = (type: string) => {
layoutType.value = type; layoutType.value = type;
@ -101,12 +119,14 @@ const handleCancel = () => {
.box-gap { .box-gap {
margin-top: 30px; margin-top: 30px;
} }
.flex-row { .flex-row {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: $margin; margin-bottom: $margin;
} }
.flex-center { .flex-center {
display: flex; display: flex;
align-items: center; align-items: center;
@ -124,12 +144,15 @@ const handleCancel = () => {
border-radius: $radius-box; border-radius: $radius-box;
overflow: hidden; overflow: hidden;
box-shadow: $shadow-special; box-shadow: $shadow-special;
.layout-icon { .layout-icon {
display: none; display: none;
} }
} }
.current-layout { .current-layout {
position: relative; position: relative;
.layout-icon { .layout-icon {
display: block; display: block;
position: absolute; position: absolute;
@ -139,8 +162,10 @@ const handleCancel = () => {
color: $color-primary; color: $color-primary;
} }
} }
.layout-defaults { .layout-defaults {
position: relative; position: relative;
&::before { &::before {
content: ""; content: "";
position: absolute; position: absolute;
@ -149,6 +174,7 @@ const handleCancel = () => {
height: 100%; height: 100%;
background: #232324; background: #232324;
} }
&::after { &::after {
content: ""; content: "";
position: absolute; position: absolute;
@ -159,8 +185,10 @@ const handleCancel = () => {
background: #fff; background: #fff;
} }
} }
.layout-head { .layout-head {
position: relative; position: relative;
&::before { &::before {
content: ""; content: "";
position: absolute; position: absolute;
@ -170,8 +198,10 @@ const handleCancel = () => {
background: #232324; background: #232324;
} }
} }
.layout-mixing { .layout-mixing {
position: relative; position: relative;
&::before { &::before {
content: ""; content: "";
position: absolute; position: absolute;
@ -180,6 +210,7 @@ const handleCancel = () => {
height: 15px; height: 15px;
background: #232324; background: #232324;
} }
&::after { &::after {
content: ""; content: "";
position: absolute; position: absolute;

View File

@ -15,7 +15,10 @@ interface ThemeConfig {
watermarkRotate: number; watermarkRotate: number;
watermarkGap: Array<number>; watermarkGap: Array<number>;
layoutType: string; layoutType: string;
grayMode: Boolean;
colorWeakMode: Boolean;
themeColor: string; themeColor: string;
presetColors: Array<string>;
} }
/** /**
@ -42,7 +45,33 @@ export const useThemeConfig = defineStore("theme-config", {
watermarkRotate: 330, // 水印角度 watermarkRotate: 330, // 水印角度
watermarkGap: [100, 100], // 水印间隙 watermarkGap: [100, 100], // 水印间隙
layoutType: "layoutDefaults", // 布局模式layoutDefaults、layoutHead、layoutMixing layoutType: "layoutDefaults", // 布局模式layoutDefaults、layoutHead、layoutMixing
themeColor: "#165dff" // 主题色 colorWeakMode: false, // 色弱模式
grayMode: false, // 灰色模式
themeColor: "#165DFF", // 主题色
presetColors: [
"#165DFF",
"#F53F3F",
"#F77234",
"#FF7D00",
"#F7BA1E",
"#FADC19",
"#9FDB1D",
"#00B42A",
"#14C9C9",
"#3491FA",
"#165DFF",
"#722ED1",
"#D91AD9",
"#F5319D",
"#67C23A",
"#E6A23C",
"#F56C6C",
"#409EFF",
"#a27b42",
"#dfc683",
"#59a680",
"#b1d391"
]
}), }),
actions: { actions: {
// 折叠菜单 // 折叠菜单