mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-19 11:43:35 +00:00
Switch to HSL for avatar generation
This commit is contained in:
parent
5e19ceb99a
commit
c1f7a30a85
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<svg fill="#eb5e28" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
width="800px" height="800px" viewBox="0 -10 409.165 409.164"
|
|
||||||
xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M204.583,216.671c50.664,0,91.74-48.075,91.74-107.378c0-82.237-41.074-107.377-91.74-107.377
|
|
||||||
c-50.668,0-91.74,25.14-91.74,107.377C112.844,168.596,153.916,216.671,204.583,216.671z"/>
|
|
||||||
<path d="M407.164,374.717L360.88,270.454c-2.117-4.771-5.836-8.728-10.465-11.138l-71.83-37.392
|
|
||||||
c-1.584-0.823-3.502-0.663-4.926,0.415c-20.316,15.366-44.203,23.488-69.076,23.488c-24.877,0-48.762-8.122-69.078-23.488
|
|
||||||
c-1.428-1.078-3.346-1.238-4.93-0.415L58.75,259.316c-4.631,2.41-8.346,6.365-10.465,11.138L2.001,374.717
|
|
||||||
c-3.191,7.188-2.537,15.412,1.75,22.005c4.285,6.592,11.537,10.526,19.4,10.526h362.861c7.863,0,15.117-3.936,19.402-10.527
|
|
||||||
C409.699,390.129,410.355,381.902,407.164,374.717z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1,28 +1,23 @@
|
|||||||
<svg
|
<svg
|
||||||
class={$$props.class}
|
{...$$props}
|
||||||
width="189"
|
width="189"
|
||||||
height="189"
|
height="189"
|
||||||
viewBox="0 0 189 189"
|
viewBox="0 0 189 189"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
style={$$props.style}
|
|
||||||
>
|
|
||||||
<g id="paths" clip-path="url(#clip0_753_289)" style="stroke: var(--logo-color, #EB5E28)">
|
<g id="paths" clip-path="url(#clip0_753_289)" style="stroke: var(--logo-color, #EB5E28)">
|
||||||
<path
|
<path
|
||||||
d="M43.7937 12.5298C0.57938 44.8609 0.342815 92.8076 16.3236 126.458C33.6361 162.913 75.9226 184.525 117.769 173.613C156.42 163.534 183.82 122.549 182.358 95.8221"
|
d="M43.7937 12.5298C0.57938 44.8609 0.342815 92.8076 16.3236 126.458C33.6361 162.913 75.9226 184.525 117.769 173.613C156.42 163.534 183.82 122.549 182.358 95.8221"
|
||||||
stroke-width="12"
|
stroke-width="12"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round" />
|
||||||
/>
|
|
||||||
<path
|
<path
|
||||||
d="M78.6923 75.6945C50.8177 86.6612 44.0155 112.559 47.9751 133.172C52.2646 155.502 72.1284 173.572 96.2818 173.985C118.59 174.366 139.116 156.332 142.045 141.655"
|
d="M78.6923 75.6945C50.8177 86.6612 44.0155 112.559 47.9751 133.172C52.2646 155.502 72.1284 173.572 96.2818 173.985C118.59 174.366 139.116 156.332 142.045 141.655"
|
||||||
stroke-width="12"
|
stroke-width="12"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round" />
|
||||||
/>
|
|
||||||
<path
|
<path
|
||||||
d="M43.5856 12.4047C17.9702 31.569 17.83 59.9895 27.3026 79.936C37.5646 101.545 62.6301 114.355 87.4348 107.887C110.345 101.913 126.587 77.6188 125.72 61.7764"
|
d="M43.5856 12.4047C17.9702 31.569 17.83 59.9895 27.3026 79.936C37.5646 101.545 62.6301 114.355 87.4348 107.887C110.345 101.913 126.587 77.6188 125.72 61.7764"
|
||||||
stroke-width="12"
|
stroke-width="12"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round" />
|
||||||
/>
|
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<clipPath id="clip0_753_289">
|
<clipPath id="clip0_753_289">
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.0 KiB |
@ -1,27 +1,29 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { generateAvatarColors } from "src/util/misc";
|
import {stringToHue, hsl} from "src/util/misc"
|
||||||
import ImageCircle from "./ImageCircle.svelte";
|
import ImageCircle from "src/partials/ImageCircle.svelte"
|
||||||
import LogoSvg from "./LogoSvg.svelte";
|
import LogoSvg from "src/partials/LogoSvg.svelte"
|
||||||
import cx from "classnames";
|
import cx from "classnames"
|
||||||
import type { Person } from "src/util/types"
|
|
||||||
|
|
||||||
export let person : Person;
|
export let person
|
||||||
export let size = 4;
|
export let size = 4
|
||||||
|
|
||||||
$: avatarColor = person.kind0 && !person.kind0.picture
|
const hue = stringToHue(person.pubkey)
|
||||||
? generateAvatarColors(person.pubkey)
|
const primary = hsl(hue, {lightness: 80})
|
||||||
: { primary: '#EB5E28', bg: 'transparent' };
|
const secondary = hsl(hue, {saturation: 30, lightness: 30})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if person.kind0?.picture}
|
{#if false && person.kind0?.picture}
|
||||||
<ImageCircle {size} src={person.kind0.picture} class={$$props.class} />
|
<ImageCircle {size} src={person.kind0.picture} class={$$props.class} />
|
||||||
{:else}
|
{:else}
|
||||||
<ImageCircle
|
<div
|
||||||
{size}
|
class={cx(
|
||||||
src={""}
|
$$props.class,
|
||||||
class={cx($$props.class, "relative")}
|
`relative overflow-hidden w-${size} h-${size} inline-block shrink-0 rounded-full border border-solid
|
||||||
style="--logo-color: {avatarColor.primary}; --logo-bg-color: {avatarColor.bg}; background-color: var(--logo-bg-color);"
|
border-white bg-cover bg-center`
|
||||||
>
|
)}
|
||||||
<LogoSvg class="absolute left-2/4 top-2/4 -translate-x-1/2 -translate-y-1/2 logo" style="height: 85%; width: 85%;" />
|
style="--logo-color: {primary}; --logo-bg-color: {secondary}; background-color: var(--logo-bg-color);">
|
||||||
</ImageCircle>
|
<LogoSvg
|
||||||
|
class="logo absolute left-2/4 top-2/4 -translate-x-1/2 -translate-y-1/2"
|
||||||
|
style="height: 85%; width: 85%;" />
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import {last} from "ramda"
|
import {last} from "ramda"
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {poll, stringToColor} from "src/util/misc"
|
import {poll, stringToHue, hsl} from "src/util/misc"
|
||||||
import {between} from "hurdak/lib/hurdak"
|
import {between} from "hurdak/lib/hurdak"
|
||||||
import {fly} from "svelte/transition"
|
import {fly} from "svelte/transition"
|
||||||
import Anchor from "src/partials/Anchor.svelte"
|
import Anchor from "src/partials/Anchor.svelte"
|
||||||
@ -36,7 +36,7 @@
|
|||||||
`bg-${theme}`,
|
`bg-${theme}`,
|
||||||
"flex flex-col justify-between gap-3 rounded border border-l-2 border-solid border-medium py-3 px-6 shadow"
|
"flex flex-col justify-between gap-3 rounded border border-l-2 border-solid border-medium py-3 px-6 shadow"
|
||||||
)}
|
)}
|
||||||
style={`border-left-color: ${stringToColor(relay.url)}`}
|
style={`border-left-color: ${hsl(stringToHue(relay.url))}`}
|
||||||
in:fly={{y: 20}}>
|
in:fly={{y: 20}}>
|
||||||
<div class="flex items-center justify-between gap-2">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<div class="flex items-center gap-2 text-xl">
|
<div class="flex items-center gap-2 text-xl">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {last} from "ramda"
|
import {last} from "ramda"
|
||||||
import {fly} from "svelte/transition"
|
import {fly} from "svelte/transition"
|
||||||
import {stringToColor} from "src/util/misc"
|
import {stringToHue, hsl} from "src/util/misc"
|
||||||
|
|
||||||
export let relay
|
export let relay
|
||||||
</script>
|
</script>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
<div
|
<div
|
||||||
class="flex flex-col justify-between gap-3 rounded border border-l-2 border-solid
|
class="flex flex-col justify-between gap-3 rounded border border-l-2 border-solid
|
||||||
border-medium py-3 px-6 shadow"
|
border-medium py-3 px-6 shadow"
|
||||||
style={`border-left-color: ${stringToColor(relay.url)}`}
|
style={`border-left-color: ${hsl(stringToHue(relay.url))}`}
|
||||||
in:fly={{y: 20}}>
|
in:fly={{y: 20}}>
|
||||||
<div class="flex items-center justify-between gap-2">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<div class="flex items-center gap-2 text-xl">
|
<div class="flex items-center gap-2 text-xl">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {find, propEq} from "ramda"
|
import {find, propEq} from "ramda"
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {poll, stringToColor} from "src/util/misc"
|
import {poll, stringToHue, hsl} from "src/util/misc"
|
||||||
import {displayRelay} from "src/util/nostr"
|
import {displayRelay} from "src/util/nostr"
|
||||||
import {between} from "hurdak/lib/hurdak"
|
import {between} from "hurdak/lib/hurdak"
|
||||||
import Content from "src/partials/Content.svelte"
|
import Content from "src/partials/Content.svelte"
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<div class="flex items-center justify-between gap-2">
|
<div class="flex items-center justify-between gap-2">
|
||||||
<div class="flex items-center gap-2 text-xl">
|
<div class="flex items-center gap-2 text-xl">
|
||||||
<i class={relay.url.startsWith("wss") ? "fa fa-lock" : "fa fa-unlock"} />
|
<i class={relay.url.startsWith("wss") ? "fa fa-lock" : "fa fa-unlock"} />
|
||||||
<span class="border-b border-solid" style={`border-color: ${stringToColor(relay.url)}`}>
|
<span class="border-b border-solid" style={`border-color: ${hsl(stringToHue(relay.url))}`}>
|
||||||
{displayRelay(relay)}
|
{displayRelay(relay)}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
@ -5,7 +5,6 @@ import Fuse from "fuse.js/dist/fuse.min.js"
|
|||||||
import {writable} from 'svelte/store'
|
import {writable} from 'svelte/store'
|
||||||
import {isObject, round} from 'hurdak/lib/hurdak'
|
import {isObject, round} from 'hurdak/lib/hurdak'
|
||||||
import {warn} from 'src/util/logger'
|
import {warn} from 'src/util/logger'
|
||||||
import {memoizeWith} from 'ramda';
|
|
||||||
|
|
||||||
export const fuzzy = (data, opts = {}) => {
|
export const fuzzy = (data, opts = {}) => {
|
||||||
const fuse = new Fuse(data, opts)
|
const fuse = new Fuse(data, opts)
|
||||||
@ -271,65 +270,18 @@ export const where = filters =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
// https://stackoverflow.com/a/21682946
|
// https://stackoverflow.com/a/21682946
|
||||||
//
|
export const stringToHue = value => {
|
||||||
export const stringToColor = (value, {saturation = 100, lightness = 50, opacity = 1} = {}) => {
|
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
hash = value.charCodeAt(i) + ((hash << 5) - hash)
|
hash = value.charCodeAt(i) + ((hash << 5) - hash)
|
||||||
hash = hash & hash
|
hash = hash & hash
|
||||||
}
|
}
|
||||||
|
|
||||||
return `hsl(${(hash % 360)}, ${saturation}%, ${lightness}%, ${opacity})`;
|
return hash % 360
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/75255491
|
export const hsl = (hue, {saturation = 100, lightness = 50, opacity = 1} = {}) =>
|
||||||
const stringToHex = function(str: string) {
|
`hsl(${hue}, ${saturation}%, ${lightness}%, ${opacity})`
|
||||||
let hash = 0;
|
|
||||||
for (let i = 0; i < str.length; i++) {
|
|
||||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
||||||
}
|
|
||||||
let colour = '#';
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
let value = (hash >> (i * 8)) & 0xFF;
|
|
||||||
colour += ('00' + value.toString(16)).substr(-2);
|
|
||||||
}
|
|
||||||
return colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
function padZero(str: string, len?: number) {
|
|
||||||
len = len || 2;
|
|
||||||
let zeros = new Array(len).join('0');
|
|
||||||
return (zeros + str).slice(-len);
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/35970186
|
|
||||||
function invertColor(hex: string) {
|
|
||||||
if (hex.indexOf('#') === 0) {
|
|
||||||
hex = hex.slice(1);
|
|
||||||
}
|
|
||||||
// convert 3-digit hex to 6-digits.
|
|
||||||
if (hex.length === 3) {
|
|
||||||
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
|
||||||
}
|
|
||||||
if (hex.length !== 6) {
|
|
||||||
throw new Error('Invalid HEX color.');
|
|
||||||
}
|
|
||||||
// invert color components
|
|
||||||
let r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16),
|
|
||||||
g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16),
|
|
||||||
b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16);
|
|
||||||
// pad each with zeros and return
|
|
||||||
return '#' + padZero(r) + padZero(g) + padZero(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const generateAvatarColors = memoizeWith(identity, (pubkey: string) => {
|
|
||||||
const primary = stringToHex(pubkey);
|
|
||||||
|
|
||||||
return {
|
|
||||||
primary,
|
|
||||||
bg: invertColor(primary),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export const tryFunc = (f, ignore = null) => {
|
export const tryFunc = (f, ignore = null) => {
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user