tethys.backend/resources/js/Components/UserAvatar.vue
Arno Kaimbacher cefd9081ae - add AvatarController.ts
- adapted menu.ts, NavBar.vue, NavBarItem.vue for highlighting active nav item
- NavBarItemLabel.vue for app menu highlighting
- adapted routes.ts
- adapted app.edge for new favicon
- adapted LayoutAuthenticated.vue (:showAsideMenu="false") for showing AsideMenu optional
- new material icons: BriefcaseCheck.vue, SwapHorizontal.vue, AccountGroup.vue, Lock.vue
- started with FirstRunWizard
2023-12-15 17:17:33 +01:00

116 lines
3.4 KiB
Vue

<script setup>
import { computed } from 'vue';
const props = defineProps({
username: {
type: String,
required: true,
},
avatar: {
type: String,
default: null,
},
api: {
type: String,
default: 'avataaars',
},
});
const avatar = computed(
// () => props.avatar ?? `https://avatars.dicebear.com/api/${props.api}/${props.username?.replace(/[^a-z0-9]+/i, '-')}.svg`
// () => props.avatar ?? `https://avatars.dicebear.com/api/initials/${props.username}.svg`,
() => {
const initials = props.username
.split(' ')
.map((part) => part.charAt(0).toUpperCase())
.join('');
return props.avatar ?? generateAvatarUrl(props.username);
},
);
const username = computed(() => props.username);
const darkenColor = (color) => {
// Convert hex to RGB
const r = parseInt(color.slice(0, 2), 16);
const g = parseInt(color.slice(2, 4), 16);
const b = parseInt(color.slice(4, 6), 16);
// Calculate darker color by reducing 20% of each RGB component
const darkerR = Math.round(r * 0.6);
const darkerG = Math.round(g * 0.6);
const darkerB = Math.round(b * 0.6);
// Convert back to hex
const darkerColor = ((darkerR << 16) + (darkerG << 8) + darkerB).toString(16);
return darkerColor.padStart(6, '0'); // Ensure it's 6 digits
};
const getRandomColor = () => {
return Math.floor(Math.random() * 16777215).toString(16);
};
const adjustOpacity = (hexColor, opacity) => {
// Remove # if present
hexColor = hexColor.replace('#', '');
// Convert hex to RGB
// const r = parseInt(hexColor.slice(0, 2), 16);
// const g = parseInt(hexColor.slice(2, 4), 16);
// const b = parseInt(hexColor.slice(4, 6), 16);
// const r = parseInt(hexColor.slice(1, 3), 16);
// const g = parseInt(hexColor.slice(3, 5), 16);
// const b = parseInt(hexColor.slice(5, 7), 16);
const [r, g, b] = hexColor.match(/\w\w/g).map(x => parseInt(x, 16));
return `rgba(${r},${g},${b},${opacity})`;
};
const lightenColor = (hexColor, percent) => {
let r = parseInt(hexColor.substring(0, 2), 16);
let g = parseInt(hexColor.substring(2, 4), 16);
let b = parseInt(hexColor.substring(4, 6), 16);
r = Math.floor(r * (100 + percent) / 100);
g = Math.floor(g * (100 + percent) / 100);
b = Math.floor(b * (100 + percent) / 100);
r = (r < 255) ? r : 255;
g = (g < 255) ? g : 255;
b = (b < 255) ? b : 255;
const lighterHex = ((r << 16) | (g << 8) | b).toString(16);
return lighterHex.padStart(6, '0');
};
// backgroundColor = '7F9CF5',
const generateAvatarUrl = (name) => {
const initials = name
.split(' ')
.map((part) => part.charAt(0).toUpperCase())
.join('');
const originalColor = getRandomColor();
const backgroundColor = lightenColor(originalColor, 60); // Lighten by 20%
const textColor = darkenColor(originalColor);
// const avatarUrl = `https://ui-avatars.com/api/?name=${initials}&size=50&background=${backgroundColor}&color=${textColor}`;
const avatarUrl = `/api/avatar?name=${name}&size=50&background=${backgroundColor}&textColor=${textColor}`;
return avatarUrl;
};
</script>
<template>
<div>
<img :src="avatar" :alt="username"
class="rounded-full block h-auto w-full max-w-full bg-gray-100 dark:bg-slate-800" />
</div>
</template>