Skip to content

Commit 65c26a3

Browse files
authored
feat: picasso avatar generation (#35)
1 parent e25dde6 commit 65c26a3

File tree

4 files changed

+154
-2
lines changed

4 files changed

+154
-2
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"pragmarx/google2fa-laravel": "^2.0",
5252
"rector/rector": "^0.11",
5353
"ruafozy/mersenne-twister": "^1.3",
54+
"savvot/random": "^0.3.0",
5455
"spatie/laravel-flash": "^1.8",
5556
"spatie/laravel-honeypot": "^4.0",
5657
"spatie/laravel-medialibrary": "^9.8",
@@ -101,4 +102,4 @@
101102
"config": {
102103
"sort-packages": true
103104
}
104-
}
105+
}

composer.lock

Lines changed: 53 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Picasso/Avatar.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ARKEcosystem\Foundation\Picasso;
6+
7+
// See https://github.com/vechain/picasso/blob/master/src/index.ts
8+
9+
final class Avatar
10+
{
11+
public static function make(string $seed): string
12+
{
13+
$defaultColors = [
14+
'rgb(244, 67, 54)',
15+
'rgb(233, 30, 99)',
16+
'rgb(156, 39, 176)',
17+
'rgb(103, 58, 183)',
18+
'rgb(63, 81, 181)',
19+
'rgb(33, 150, 243)',
20+
'rgb(3, 169, 244)',
21+
'rgb(0, 188, 212)',
22+
'rgb(0, 150, 136)',
23+
'rgb(76, 175, 80)',
24+
'rgb(139, 195, 74)',
25+
'rgb(205, 220, 57)',
26+
'rgb(255, 193, 7)',
27+
'rgb(255, 152, 0)',
28+
'rgb(255, 87, 34)',
29+
];
30+
31+
$twister = new Mersenne(static::hash($seed));
32+
33+
$genColor = function () use (&$defaultColors, $twister): string {
34+
$index = (int) floor(count($defaultColors) * $twister->random());
35+
36+
return array_splice($defaultColors, $index, 1)[0];
37+
};
38+
39+
$backgroundString = '<rect fill="'.$genColor().'" width="100" height="100"/>';
40+
$styleString = '<style>.picasso circle{mix-blend-mode:soft-light;}</style>';
41+
$shapeString = '';
42+
$layers = 3;
43+
$rs = [35, 40, 45, 50, 55, 60];
44+
$cxs = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
45+
$cys = [30, 40, 50, 60, 70];
46+
47+
for ($i = 0; $i < $layers; $i++) {
48+
$r = array_splice($rs, (int) floor(count($rs) * $twister->random()), 1)[0];
49+
$cx = array_splice($cxs, (int) floor(count($cxs) * $twister->random()), 1)[0];
50+
$cy = array_splice($cys, (int) floor(count($cys) * $twister->random()), 1)[0];
51+
$fill = $genColor();
52+
53+
$shapeString .= '<circle r="'.$r.'" cx="'.$cx.'" cy="'.$cy.'" fill="'.$fill.'"/>';
54+
}
55+
56+
return sprintf(
57+
"<svg version='1.1' xmlns='http://www.w3.org/2000/svg' class='rounded-full picasso' viewBox='0 0 100 100'>%s%s%s</svg>",
58+
$styleString,
59+
$backgroundString,
60+
$shapeString
61+
);
62+
}
63+
64+
private static function hash(string $value): int
65+
{
66+
$h = 0;
67+
68+
for ($i = 0; $i < strlen($value); $i++) {
69+
$h = $h * 31 + ord($value[$i]);
70+
$h = $h % (2 ** 32);
71+
}
72+
73+
return $h;
74+
}
75+
}

src/Picasso/Mersenne.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ARKEcosystem\Foundation\Picasso;
6+
7+
use mersenne_twister\twister;
8+
9+
final class Mersenne
10+
{
11+
private twister $twister;
12+
13+
public function __construct(int $seed)
14+
{
15+
ini_set('precision', '16');
16+
17+
$this->twister = new twister($seed);
18+
}
19+
20+
public function random(): float
21+
{
22+
return $this->twister->real_halfopen();
23+
}
24+
}

0 commit comments

Comments
 (0)