feat: add border color option

This commit is contained in:
elderdog 2023-09-28 14:49:35 +08:00
parent df7c3c19ce
commit 068218d30a
8 changed files with 100 additions and 10 deletions

View File

@ -21,6 +21,28 @@
</ul>
</SectionWrapper>
<SectionWrapper :title="t('label.borderColor')">
<ul class="color-list">
<li
v-for="borderColor in SETTINGS.borderColor"
:key="borderColor"
class="color-list__item"
@click="switchBorderColor(borderColor)"
>
<div
:style="{ background: borderColor }"
class="bg-color"
:class="[
{
active: borderColor === avatarOption.background.borderColor,
transparent: borderColor === 'transparent',
},
]"
/>
</li>
</ul>
</SectionWrapper>
<SectionWrapper :title="t('label.backgroundColor')">
<ul class="color-list">
<li
@ -173,6 +195,15 @@ function switchWrapperShape(wrapperShape: WrapperShape) {
}
}
function switchBorderColor(borderColor: string) {
if (borderColor !== avatarOption.value.background.borderColor) {
setAvatarOption({
...avatarOption.value,
background: { ...avatarOption.value.background, borderColor },
})
}
}
function switchBgColor(bgColor: string) {
if (bgColor !== avatarOption.value.background.color) {
setAvatarOption({

View File

@ -5,12 +5,18 @@
:style="{
width: `${avatarSize}px`,
height: `${avatarSize}px`,
...getWrapperShapeStyle(),
}"
:class="getWrapperShapeClassName()"
>
<Background :color="avatarOption.background.color" />
<div class="avatar-payload" v-html="svgContent" />
<Border
:color="avatarOption.background.borderColor"
:radius="getWrapperShapeStyle().borderRadius"
/>
</div>
</template>
@ -26,10 +32,11 @@ import { ref, toRefs, watchEffect } from 'vue'
import { WidgetType, WrapperShape } from '@/enums'
import type { AvatarOption } from '@/types'
import { getRandomAvatarOption } from '@/utils'
import { AVATAR_LAYER, NONE } from '@/utils/constant'
import { AVATAR_LAYER, NONE, SHAPE_STYLE_SET } from '@/utils/constant'
import { widgetData } from '@/utils/dynamic-data'
import Background from './widgets/Background.vue'
import Border from './widgets/Border.vue'
interface VueColorAvatarProps {
option: AvatarOption
@ -58,6 +65,10 @@ function getWrapperShapeClassName() {
}
}
function getWrapperShapeStyle() {
return SHAPE_STYLE_SET[avatarOption.value.wrapperShape]
}
const svgContent = ref('')
watchEffect(async () => {
@ -133,15 +144,6 @@ watchEffect(async () => {
position: relative;
overflow: hidden;
&.circle {
border-radius: 50%;
}
&.squircle {
// TODO: Radius should adapt to the avatar size
border-radius: 25px;
}
.avatar-payload {
position: relative;
z-index: 2;

View File

@ -0,0 +1,31 @@
<template>
<div
class="avatar-border"
:style="{ borderColor: props.color, borderRadius: props.radius }"
></div>
</template>
<script lang="ts" setup>
import { type AvatarOption } from '../../types'
interface BorderProps {
color: AvatarOption['background']['borderColor']
radius: string
}
const props = defineProps<BorderProps>()
</script>
<style lang="scss" scoped>
.avatar-border {
position: absolute;
top: 0;
left: 0;
z-index: 3;
width: 100%;
height: 100%;
border-style: solid;
border-width: 10px;
transition: border-color 0.1s;
}
</style>

View File

@ -16,6 +16,7 @@ export default {
},
label: {
wrapperShape: 'Avatar Shape',
borderColor: 'Border Color',
backgroundColor: 'Background Color',
colors: 'colors',
},

View File

@ -16,6 +16,7 @@ export default {
},
label: {
wrapperShape: '头像形状',
borderColor: '边框颜色',
backgroundColor: '背景颜色',
colors: '颜色',
},

View File

@ -46,6 +46,7 @@ export interface AvatarOption {
background: {
color: string
borderColor: string
}
widgets: Partial<AvatarWidgets>
@ -70,4 +71,5 @@ export interface AvatarSettings {
commonColors: string[]
skinColors: string[]
backgroundColor: string[]
borderColor: string[]
}

View File

@ -99,6 +99,10 @@ export const SETTINGS: Readonly<AvatarSettings> = {
'transparent',
]
},
get borderColor() {
return [...this.commonColors, 'transparent']
},
}
export const SCREEN = {
@ -114,6 +118,7 @@ export const SPECIAL_AVATARS: Readonly<AvatarOption[]> = [
wrapperShape: 'squircle',
background: {
color: 'linear-gradient(62deg, #8EC5FC, #E0C3FC)',
borderColor: 'transparent',
},
widgets: {
face: {
@ -158,6 +163,7 @@ export const SPECIAL_AVATARS: Readonly<AvatarOption[]> = [
wrapperShape: 'squircle',
background: {
color: '#fd6f5d',
borderColor: 'transparent',
},
widgets: {
face: {
@ -207,3 +213,16 @@ export const NOT_COMPATIBLE_AGENTS = [
] as const
export const DOWNLOAD_DELAY = 800
export const SHAPE_STYLE_SET = {
[WrapperShape.Circle]: {
borderRadius: '50%',
},
[WrapperShape.Square]: {
borderRadius: '0',
},
[WrapperShape.Squircle]: {
// TODO: Radius should adapt to the avatar size
borderRadius: '25px',
},
}

View File

@ -75,6 +75,9 @@ export function getRandomAvatarOption(
hairColor, // Handle special cases and prevent color conflicts.
],
}),
borderColor: getRandomValue(SETTINGS.borderColor, {
avoid: [useOption.background?.color],
}),
},
widgets: {