Skip to content

Commit 7778063

Browse files
committed
Improve Blobbie Appearance (#4173)
Blobbies now select from a subset of predefined colors to form a basic radial gradient form the bottom right corner. ![image](https://github.com/user-attachments/assets/5b708533-506d-417d-ac49-2356aa0a2247) <!-- start pr-codex --> --- ## PR-Codex overview This PR updates the appearance of the Blobbie avatar in the ConnectWallet feature of `thirdweb`. ### Detailed summary - Updated Blobbie appearance with unique gradient colors based on address - Replaced complex color pairing logic with predefined color options - Simplified Blobbie rendering logic for better performance > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 574ff02 commit 7778063

File tree

3 files changed

+39
-118
lines changed

3 files changed

+39
-118
lines changed

.changeset/dry-lies-nail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Update Blobbie appearance
Lines changed: 33 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
"use client";
22
import { hexToNumber } from "@noble/curves/abstract/utils";
33
import { useId, useMemo } from "react";
4-
import { type Address, numberToHex } from "viem";
4+
import type { Address } from "viem";
55

6-
// Distance between 2 colors (in RGB)
7-
type Color = [number, number, number];
8-
function hexToRgb(hex: string) {
9-
return [
10-
Number(hexToNumber(hex.slice(0, 2))),
11-
Number(hexToNumber(hex.slice(2, 4))),
12-
Number(hexToNumber(hex.slice(4, 6))),
13-
] satisfies [number, number, number];
14-
}
6+
const COLOR_OPTIONS = [
7+
["#fca5a5", "#b91c1c"],
8+
["#fdba74", "#c2410c"],
9+
["#fcd34d", "#b45309"],
10+
["#fde047", "#a16207"],
11+
["#a3e635", "#4d7c0f"],
12+
["#86efac", "#15803d"],
13+
["#67e8f9", "#0e7490"],
14+
["#7dd3fc", "#0369a1"],
15+
["#93c5fd", "#1d4ed8"],
16+
["#a5b4fc", "#4338ca"],
17+
["#c4b5fd", "#6d28d9"],
18+
["#d8b4fe", "#7e22ce"],
19+
["#f0abfc", "#a21caf"],
20+
["#f9a8d4", "#be185d"],
21+
["#fda4af", "#be123c"],
22+
];
1523

1624
/**
1725
* A unique gradient avatar based on the provided address.
@@ -21,114 +29,22 @@ function hexToRgb(hex: string) {
2129
*/
2230
export function Blobbie(props: { address: Address; size: number }) {
2331
const id = useId();
24-
const colors: [string, string, string] = useMemo(() => {
25-
const color = props.address.slice(2, 8);
26-
const rgb = hexToRgb(color);
27-
28-
// To get well-paired colors, we use the first rgb hex sequence as our main color then find its two best pairs (split color wheel into thirds)
29-
// To prevent extremely dark colors, which tend to clash, we don't allow values less than 55
30-
const pairing1 = rgb.map((n) => (n + 85 > 255 ? n + 85 - 200 : n + 85));
31-
const pairing2 = rgb.map((n) => (n - 85 < 55 ? n - 85 + 200 : n - 85));
32-
return [
33-
color,
34-
pairing1.map((n) => numberToHex(n).replace("0x", "")).join(""),
35-
pairing2.map((n) => numberToHex(n).replace("0x", "")).join(""),
36-
];
37-
}, [props.address]);
38-
39-
const positions: [Color, Color, Color, Color, Color] = useMemo(() => {
40-
const _positions: Color[] = [];
41-
let i = 8;
42-
while (i < 44) {
43-
const values = hexToRgb(props.address.slice(i, i + 6));
44-
_positions.push(values);
45-
i += 6;
46-
}
47-
return _positions as [Color, Color, Color, Color, Color];
48-
}, [props.address]);
49-
50-
console.log(colors);
32+
const colors = useMemo(
33+
() =>
34+
COLOR_OPTIONS[
35+
Number(hexToNumber(props.address.slice(2, 4))) % COLOR_OPTIONS.length
36+
] as [string, string],
37+
[props.address],
38+
);
5139

5240
return (
53-
<svg
54-
height={`${props.size}px`}
55-
style={{ background: "#FFFFFF" }}
56-
width={`${props.size}px`}
57-
role="presentation"
58-
viewBox="0 0 500 500"
59-
xmlns="http://www.w3.org/2000/svg"
60-
>
61-
<defs>
62-
{colors.map((color, idx) => {
63-
return (
64-
<radialGradient
65-
id={`${id}_grad${idx + 1}`}
66-
cx="50%"
67-
cy="50%"
68-
r="50%"
69-
key={`grad${
70-
// biome-ignore lint/suspicious/noArrayIndexKey: Jonas said so
71-
idx
72-
}`}
73-
>
74-
<stop
75-
offset="0%"
76-
style={{ stopColor: `#${color}`, stopOpacity: 0.9 }}
77-
/>
78-
<stop
79-
offset="100%"
80-
style={{ stopColor: `#${color}`, stopOpacity: 0 }}
81-
/>
82-
</radialGradient>
83-
);
84-
})}
85-
</defs>
86-
87-
<ellipse
88-
cx="250"
89-
cy="250"
90-
rx="500"
91-
ry="500"
92-
fill={`url(#${id}_grad1)`}
93-
opacity={0.5}
94-
/>
95-
<ellipse
96-
cx={400 + positions[0][0]}
97-
cy={400 + positions[0][1]}
98-
rx={350 + positions[0][2]}
99-
ry={350 + positions[0][2]}
100-
fill={`url(#${id}_grad1)`}
101-
/>
102-
<ellipse
103-
cx={positions[1][0]}
104-
cy={positions[1][1]}
105-
rx={350 + positions[1][2]}
106-
ry={350 + positions[1][2]}
107-
fill={`url(#${id}_grad2)`}
108-
/>
109-
<ellipse
110-
cx={400 + positions[2][0]}
111-
cy={positions[2][1]}
112-
rx={350 + positions[2][2]}
113-
ry={350 + positions[2][2]}
114-
fill={`url(#${id}_grad3)`}
115-
/>
116-
<ellipse
117-
cx={positions[3][0]}
118-
cy={positions[3][1]}
119-
rx={100 + positions[3][2]}
120-
ry={100 + positions[3][2]}
121-
fill={`url(#${id}_grad2)`}
122-
opacity={0.5}
123-
/>
124-
<ellipse
125-
cx={positions[4][0]}
126-
cy={positions[4][1]}
127-
rx={100 + positions[4][2]}
128-
ry={100 + positions[4][2]}
129-
fill={`url(#${id}_grad3)`}
130-
opacity={0.5}
131-
/>
132-
</svg>
41+
<div
42+
id={id}
43+
style={{
44+
width: `${props.size}px`,
45+
height: `${props.size}px`,
46+
backgroundImage: `radial-gradient(ellipse at left bottom, ${colors[0]}, ${colors[1]})`,
47+
}}
48+
/>
13349
);
13450
}

packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ export const ConnectedWalletDetails: React.FC<{
213213
style={{
214214
border: `1px solid ${theme.colors.borderColor}`,
215215
textOverflow: "ellipsis",
216-
width: "115px",
216+
minWidth: "115px",
217217
height: "50px",
218218
whiteSpace: "nowrap",
219219
borderRadius: `0 ${radius.md} ${radius.md} 0`,

0 commit comments

Comments
 (0)