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 = () => {
let { setDarkMode, setThemeColor } = useThemeMethods();
setDarkMode();
setThemeColor();
let { initTheme } = useThemeMethods();
initTheme();
};
onTheme();

View File

@ -3,6 +3,22 @@ import { useThemeConfig } from "@/store/modules/theme-config";
import { generate, getRgbStr } from "@arco-design/color";
/* 主题处理hooks */
export const useThemeMethods = () => {
/**
* @description:
*/
const initTheme = () => {
// 黑暗模式和主题色
setDarkMode();
// 色弱模式和灰色模式
const themeStore = useThemeConfig();
const { grayMode } = storeToRefs(themeStore);
if (grayMode.value) {
setGray();
} else {
setColorWeak();
}
};
/**
* @description:
*/
@ -16,6 +32,8 @@ export const useThemeMethods = () => {
// 恢复亮色主题
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 {
initTheme,
setDarkMode,
setThemeColor
setThemeColor,
setColorWeak,
setGray
};
};

View File

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

View File

@ -15,7 +15,10 @@ interface ThemeConfig {
watermarkRotate: number;
watermarkGap: Array<number>;
layoutType: string;
grayMode: Boolean;
colorWeakMode: Boolean;
themeColor: string;
presetColors: Array<string>;
}
/**
@ -42,7 +45,33 @@ export const useThemeConfig = defineStore("theme-config", {
watermarkRotate: 330, // 水印角度
watermarkGap: [100, 100], // 水印间隙
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: {
// 折叠菜单