agent-robot-avatar 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -1
- package/README.md +84 -19
- package/agent-robot-avatar-lite.js +44 -0
- package/agent-robot-avatar.js +2 -1
- package/index.d.ts +64 -0
- package/lite.d.ts +5 -0
- package/package.json +11 -6
- package/src/agent-robot-avatar-core.js +5 -2
- package/src/agent-robot-avatar-runtime.js +4 -1
- package/src/agent-robot-avatar-skin-patterns.js +234 -0
- package/src/agent-robot-avatar-skins.js +256 -0
- package/src/agent-robot-avatar-version.js +1 -1
- package/src/skins/catalog.js +218 -0
- package/src/skins/collection-materials.js +118 -0
- package/src/skins/eyelids.js +32 -0
- package/src/skins/glaze-variants.js +29 -0
- package/src/skins/layered-texture.js +162 -0
- package/src/skins/material-data.js +111 -0
- package/src/skins/material-library.js +302 -0
- package/src/skins/metal-tint.js +11 -0
- package/src/skins/more-materials.js +69 -0
- package/src/skins/native.js +754 -0
- package/src/skins/paints.js +3 -0
- package/src/skins/revised-materials.js +44 -0
- package/src/skins/second-pass-materials.js +71 -0
- package/src/skins/soft-materials.js +111 -0
- package/src/skins/sports-materials.js +38 -0
- package/src/skins/wood-materials.js +68 -0
- package/assets/support/alipay.png +0 -0
- package/assets/support/wechat-pay.png +0 -0
- package/docs/README.de.md +0 -185
- package/docs/README.es.md +0 -185
- package/docs/README.fr.md +0 -185
- package/docs/README.ja.md +0 -185
- package/docs/README.ko.md +0 -185
- package/docs/README.pt.md +0 -185
- package/docs/README.ru.md +0 -185
- package/docs/README.zh-CN.md +0 -202
- package/docs/README.zh-TW.md +0 -185
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// Each texture here has its own SVG artwork.
|
|
2
|
+
const COLLECTION = new Set(['ceramicblue', 'tartan', 'argyle', 'sashiko', 'quilt', 'corduroy', 'linen', 'strawberry', 'orangepeel', 'chocolate', 'waffle', 'cookie', 'donut', 'cactus', 'raindrop', 'snowflake', 'artdeco', 'memphis', 'hexbolt', 'rivet']);
|
|
3
|
+
|
|
4
|
+
export function collectionTexture(defs,id,kind,el,gradient) {
|
|
5
|
+
if (!COLLECTION.has(kind)) return null;
|
|
6
|
+
const sizes = {kiwi:240,lemon:120,peach:240,chocolate:48,waffle:32,latte:240,malachite:160,agate:160,sandstone:160,ocean:120,cloud:120,tartan:80,houndstooth:32,sashiko:48,corduroy:12,linen:24,hexbolt:48,disco:80,kintsugi:160,opart:160};
|
|
7
|
+
const s=sizes[kind] || 80;
|
|
8
|
+
const p=el('pattern',{id,width:s,height:kind==='hexbolt'?42:s,patternUnits:'userSpaceOnUse'},defs);
|
|
9
|
+
const path=(d,fill='none',stroke='none',width=1,opacity=1,parent=p)=>el('path',{d,fill,stroke,'stroke-width':width,opacity,'stroke-linecap':'round','stroke-linejoin':'round'},parent);
|
|
10
|
+
const circle=(x,y,r,fill,opacity=1,parent=p)=>el('circle',{cx:x,cy:y,r,fill,opacity},parent);
|
|
11
|
+
const rect=(x,y,w,h,fill,opacity=1,rx=0)=>el('rect',{x,y,width:w,height:h,fill,opacity,rx},p);
|
|
12
|
+
const ellipse=(x,y,rx,ry,fill,angle=0,opacity=1,parent=p)=>el('ellipse',{cx:x,cy:y,rx,ry,fill,opacity,transform:`rotate(${angle} ${x} ${y})`},parent);
|
|
13
|
+
const specks=(count,colors,radius=.6)=>{
|
|
14
|
+
for(let i=0;i<count;i++) circle((i*31.71+7)%s,(i*i*13.37+11)%s,radius+(i%3)*.3,colors[i%colors.length],.3);
|
|
15
|
+
};
|
|
16
|
+
if(kind==='strawberry') {
|
|
17
|
+
for(const [x,y] of [[16,18],[55,58],[58,13],[13,57]]) {
|
|
18
|
+
ellipse(x,y,2.1,4,'#9d4d57',-18,.55);ellipse(x-1,y-1,1.3,2.5,'#ffe7a3',-18,.95);
|
|
19
|
+
}
|
|
20
|
+
} else if(kind==='orangepeel') {
|
|
21
|
+
for(let i=0;i<85;i++) {
|
|
22
|
+
const x=(i*21.3)%s,y=(i*i*17.7)%s;
|
|
23
|
+
circle(x,y,1.4,'#b97129',.3);path(`M${x-1} ${y+1}h1.5`,'none','#fff0b9',.7,.5);
|
|
24
|
+
}
|
|
25
|
+
} else if(kind==='chocolate') {
|
|
26
|
+
rect(1,1,46,46,'#432a20',.5,5);rect(5,5,38,38,'#a57652',.5,4);
|
|
27
|
+
path('M7 40V7H40','none','#d4a97d',1.5,.5);path('M41 8V41H8','none','#3d241c',2,.65);
|
|
28
|
+
path('M13 16L24 11 35 16V31L24 36 13 31Z','none','#603b2d',1,.3);
|
|
29
|
+
} else if(kind==='waffle') {
|
|
30
|
+
rect(4,4,24,24,'#a4642e',.5,3);rect(7,7,18,18,'#cc8d42',.7,2);
|
|
31
|
+
path('M4 28V4H28','none','#ffe2a1',3,.75);path('M28 4V28H4','none','#9f602d',2,.55);
|
|
32
|
+
} else if(kind==='cookie') {
|
|
33
|
+
specks(45,['#9f702e','#fff3bb']);
|
|
34
|
+
for(let i=0;i<8;i++) {
|
|
35
|
+
const x=(i*29+8)%s,y=(i*i*17+6)%s;
|
|
36
|
+
path(`M${x} ${y}l6-2 4 5-3 5-7-2Z`,'#604030','none',0,.9);
|
|
37
|
+
path(`M${x+1} ${y}l4-1`,'none','#ac7b56',1,.6);
|
|
38
|
+
}
|
|
39
|
+
} else if(kind==='donut') {
|
|
40
|
+
const colors=['#fff3b2','#8dd4ce','#f6f0ec','#8e82c1','#b64b69'];
|
|
41
|
+
for(let i=0;i<18;i++) {
|
|
42
|
+
const x=(i*31.7)%s,y=(i*i*17.1)%s,a=i*2.3;
|
|
43
|
+
path(`M${x} ${y}l${Math.cos(a)*5} ${Math.sin(a)*5}`,'none',colors[i%5],2.5,.95);
|
|
44
|
+
}
|
|
45
|
+
} else if(kind==='cactus') {
|
|
46
|
+
for(const x of [9,36,63]) {
|
|
47
|
+
path(`M${x} 0q-5 20 0 40t0 40`,'none','#547435',5,.3);
|
|
48
|
+
path(`M${x+4} 0q-5 20 0 40t0 40`,'none','#edf2b6',1.5,.6);
|
|
49
|
+
for(const y of [14,54]) path(`M${x-3} ${y-3}l6 6m-6 0 6-6m-3-1v8`,'none','#fff5cc',1,.85);
|
|
50
|
+
}
|
|
51
|
+
} else if(kind==='raindrop') {
|
|
52
|
+
gradient(defs,'radialGradient',`${id}-drop`,{cx:'.65',cy:'.7'},[[0,'#f4ffff',.65],[.6,'#7d9ba6',.05],[1,'#213d51',.4]]);
|
|
53
|
+
for(const [x,y,r] of [[18,20,8],[55,58,11],[65,12,4],[16,65,4]]) {
|
|
54
|
+
ellipse(x,y,r*.75,r,`url(#${id}-drop)`,-15);
|
|
55
|
+
path(`M${x-r*.4} ${y-r*.4}l1-2`,'none','#fff',1.4,.8);
|
|
56
|
+
}
|
|
57
|
+
} else if(kind==='snowflake') {
|
|
58
|
+
for(const [x,y,r] of [[20,20,16],[60,60,10]]) for(let i=0;i<6;i++) {
|
|
59
|
+
const g=el('g',{transform:`translate(${x} ${y}) rotate(${i*60})`},p);
|
|
60
|
+
path(`M0 0V${-r}M0 ${-r*.5}l${-r*.25} ${-r*.25}M0 ${-r*.5}l${r*.25} ${-r*.25}`,'none','#e5f4f8',1,.8,g);
|
|
61
|
+
}
|
|
62
|
+
specks(12,['#fff'],.5);
|
|
63
|
+
} else if(kind==='tartan') {
|
|
64
|
+
rect(0,0,s,s,'#782f42',.65);
|
|
65
|
+
for(const n of [13,53]) {rect(n,0,15,s,'#224f48',.65);rect(0,n,s,15,'#224f48',.65);}
|
|
66
|
+
for(const n of [8,33,48,73]) path(`M${n} 0v80M0 ${n}h80`,'none','#ead39d',.8,.7);
|
|
67
|
+
} else if(kind==='argyle') {
|
|
68
|
+
path('M20 0L40 40 20 80 0 40Z','#6d5b8e','none',0,.7);path('M60 0L80 40 60 80 40 40Z','#ead6de','none',0,.75);
|
|
69
|
+
path('M0 0L40 80 80 0M0 80L40 0 80 80','none','#fff2d9',1,.75);
|
|
70
|
+
} else if(kind==='sashiko') {
|
|
71
|
+
for(const [x,y] of [[0,0],[48,0],[24,24],[0,48],[48,48]]) el('circle',{cx:x,cy:y,r:24,fill:'none',stroke:'#f4ecdc','stroke-width':1,'stroke-dasharray':'3 2',opacity:.8},p);
|
|
72
|
+
} else if(kind==='quilt') {
|
|
73
|
+
for(const [x,y,c] of [[0,0,'#a6b5b5'],[40,0,'#e3c393'],[0,40,'#d18f94'],[40,40,'#9298b9']]) {
|
|
74
|
+
rect(x,y,40,40,c,.8);
|
|
75
|
+
el('rect',{x:x+3,y:y+3,width:34,height:34,fill:'none',stroke:'#fff4de','stroke-width':1,'stroke-dasharray':'2 2',opacity:.8},p);
|
|
76
|
+
for(const n of [12,28]) circle(x+n,y+n,1.5,'#fff5dd',.7);
|
|
77
|
+
}
|
|
78
|
+
} else if(kind==='corduroy') {
|
|
79
|
+
rect(0,0,3,12,'#73482e',.35);rect(4,0,3,12,'#ffe1aa',.4);
|
|
80
|
+
for(let y=0;y<12;y+=2) path(`M4 ${y}h5`,'none','#fff0c6',.5,.28);
|
|
81
|
+
} else if(kind==='linen') {
|
|
82
|
+
for(let i=1;i<24;i+=3) {
|
|
83
|
+
path(`M${i} 0v24`,'none',i%2?'#8b806a':'#fff8e6',.65,.38);
|
|
84
|
+
path(`M0 ${i}h24`,'none',i%2?'#fff8e6':'#8b806a',.65,.35);
|
|
85
|
+
}
|
|
86
|
+
specks(8,['#716a59'],.4);
|
|
87
|
+
} else if(kind==='artdeco') {
|
|
88
|
+
for(const [x,y] of [[0,80],[80,80],[40,40]]) for(let i=0;i<=8;i++) {
|
|
89
|
+
const a=Math.PI+i*Math.PI/8;
|
|
90
|
+
path(`M${x} ${y}L${x+Math.cos(a)*40} ${y+Math.sin(a)*40}`,'none','#dfc185',.9,.8);
|
|
91
|
+
}
|
|
92
|
+
path('M0 80A40 40 0 0 1 80 80M0 40A40 40 0 0 1 80 40','none','#e5c589',1.5,.8);
|
|
93
|
+
} else if(kind==='memphis') {
|
|
94
|
+
path('M4 18q6-10 12 0t12 0','none','#795c9b',3,.9);
|
|
95
|
+
path('M48 10l16 4-10 13Z','#f2cd79');circle(19,59,7,'#88bcb3');
|
|
96
|
+
path('M46 57l5-5 5 10 5-10 5 5','none','#b36284',2.5,.9);
|
|
97
|
+
for(const [x,y] of [[38,35],[71,41],[6,35]]) circle(x,y,1.5,'#46526d');
|
|
98
|
+
} else if(kind==='hexbolt') {
|
|
99
|
+
for(const [x,y] of [[0,0],[24,0],[48,0],[12,21],[36,21],[0,42],[24,42],[48,42]]) {
|
|
100
|
+
path(`M${x} ${y-14}l12 7v14l-12 7-12-7v-14Z`,'#748786','#354e53',1.5,.7);
|
|
101
|
+
path(`M${x-9} ${y-5}l9-5 9 5`,'none','#e3e9d9',1,.6);
|
|
102
|
+
}
|
|
103
|
+
} else if(kind==='rivet') {
|
|
104
|
+
path('M0 0H80V80H0Z','none','#132235',3,.65);path('M3 77V3H77','none','#9cb0c0',1,.55);
|
|
105
|
+
for(const [x,y] of [[9,9],[71,9],[9,71],[71,71]]) {
|
|
106
|
+
circle(x,y,3.5,'#172b3d',.8);circle(x-1,y-1,2.5,'#afbec5',.85);
|
|
107
|
+
path(`M${x-2} ${y-2}h2`,'none','#f2f6ee',.8,.9);
|
|
108
|
+
}
|
|
109
|
+
} else if(kind==='ceramicblue') {
|
|
110
|
+
for(const [x,y] of [[20,22],[61,61]]) {
|
|
111
|
+
const g=el('g',{transform:`translate(${x} ${y})`},p);
|
|
112
|
+
for(let i=0;i<6;i++) el('ellipse',{cx:0,cy:-6,rx:3,ry:7,fill:'#4c7097',opacity:.8,transform:`rotate(${i*60})`},g);
|
|
113
|
+
circle(0,0,2,'#e5ebdf',1,g);
|
|
114
|
+
path('M5 14Q22 28 18 40M10 22q10-13 15-3q-3 8-15 3','none','#416d94',1.2,.9,g);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return p;
|
|
118
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const NS = 'http://www.w3.org/2000/svg';
|
|
2
|
+
|
|
3
|
+
function svg(tag, attributes = {}, parent) {
|
|
4
|
+
const element = document.createElementNS(NS, tag);
|
|
5
|
+
for (const [name, value] of Object.entries(attributes)) element.setAttribute(name, String(value));
|
|
6
|
+
parent?.append(element);
|
|
7
|
+
return element;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// The eyelids are rectangles painted in the head color over the eyes. A skin
|
|
11
|
+
// paints the head with gradients, so a flat lid would show as a patch. Moving
|
|
12
|
+
// the lids into a mask lets them cut the eyes instead, and the skin shows
|
|
13
|
+
// through. With a flat head color this looks exactly like the original.
|
|
14
|
+
export function maskEyelids(instance) {
|
|
15
|
+
const root = instance.shadowRoot;
|
|
16
|
+
const defs = root.querySelector('defs');
|
|
17
|
+
for (const side of ['left', 'right']) {
|
|
18
|
+
const eye = root.getElementById(`${side}Eye`);
|
|
19
|
+
const lids = root.getElementById(`${side}Top`)?.parentElement;
|
|
20
|
+
if (!eye || !lids || lids.parentElement?.tagName === 'mask') continue;
|
|
21
|
+
const mask = svg('mask', {
|
|
22
|
+
id: `skin-${side}-lids`, maskUnits: 'userSpaceOnUse', maskContentUnits: 'userSpaceOnUse',
|
|
23
|
+
x: -180, y: -240, width: 360, height: 480,
|
|
24
|
+
}, defs);
|
|
25
|
+
svg('rect', { x: -180, y: -240, width: 360, height: 480, fill: '#fff' }, mask);
|
|
26
|
+
for (const lid of lids.children) lid.style.fill = '#000';
|
|
27
|
+
mask.append(lids);
|
|
28
|
+
const paint = svg('g', { mask: `url(#skin-${side}-lids)` });
|
|
29
|
+
paint.append(...eye.children);
|
|
30
|
+
eye.append(paint);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const variant = (source,label,english,colors,antenna,eyeColor) => ({
|
|
2
|
+
source,label,english,antenna,
|
|
3
|
+
palette:{baseColor:colors[0],bodyColor:colors[1],bodyEndColor:colors[2],
|
|
4
|
+
secondaryColor:colors[3],reflectionColor:colors[3],edgeColor:colors[4],...(eyeColor ? {eyeColor} : {})},
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
export const glazeVariants = {
|
|
8
|
+
jadeglaze:variant('blueglaze','亮釉翡翠绿','JADE GLAZE',
|
|
9
|
+
['#086953','#40c49b','#12856c','#b0f1d6','#ddfff0'],['#effff6','#50c99f','#126b57']),
|
|
10
|
+
berryglaze:variant('blueglaze','亮釉莓果粉','BERRY GLAZE',
|
|
11
|
+
['#9e285f','#ec77ac','#c13b7b','#ffc6e4','#fff0f7'],['#fff1f8','#ed8cba','#a53169']),
|
|
12
|
+
amberglaze:variant('blueglaze','亮釉琥珀橙','AMBER GLAZE',
|
|
13
|
+
['#ae531b','#f4b053','#db762b','#ffe1af','#fff3dc'],['#fff7dc','#f2b85e','#ad5e27']),
|
|
14
|
+
irisglaze:variant('blueglaze','亮釉鸢尾紫','IRIS GLAZE',
|
|
15
|
+
['#5831a8','#aa83ef','#7846cf','#ddceff','#f4edff'],['#f7efff','#b18bed','#6440ac']),
|
|
16
|
+
mintice:variant('iceglaze','冰透薄荷绿','MINT ICE',
|
|
17
|
+
['#8bbcae','#d7f0e5','#b3d8c9','#e9fff5','#f5fff9'],['#ffffff','#c4e6d7','#7fae9c']),
|
|
18
|
+
blushice:variant('iceglaze','冰透樱花粉','BLUSH ICE',
|
|
19
|
+
['#c093ab','#f5dfe9','#e2bed0','#fff0f7','#fff8fc'],['#ffffff','#e8c9d9','#b28b9f']),
|
|
20
|
+
champagneice:variant('iceglaze','冰透香槟金','CHAMPAGNE ICE',
|
|
21
|
+
['#c2ac81','#f4e9d2','#e0cda8','#fff6df','#fffaf0'],['#ffffff','#e7d8b9','#b4a078']),
|
|
22
|
+
lavenderice:variant('iceglaze','冰透薰衣紫','LAVENDER ICE',
|
|
23
|
+
['#a89ac9','#e8e1f6','#cec1e8','#f4efff','#fbf8ff'],['#ffffff','#d8ceeb','#9f91bd'],'#304c6e'),
|
|
24
|
+
blackglaze:variant('blueglaze','亮釉曜石黑','OBSIDIAN GLAZE',
|
|
25
|
+
['#090d14','#39434f','#101923','#94a5ba','#dce5ee'],['#d9e3ed','#4a596a','#101923'],'#ffffff'),
|
|
26
|
+
whiteice:{...variant('iceglaze','冰透霜白','FROST WHITE ICE',
|
|
27
|
+
['#c0cdd6','#f6fbff','#dce8ef','#effaff','#ffffff'],['#ffffff','#e7f2f7','#abbfc9'],'#405765'),number:119},
|
|
28
|
+
};
|
|
29
|
+
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { glazeVariants } from './glaze-variants.js';
|
|
2
|
+
const arcLayers = ['main','secondary','reflection'];
|
|
3
|
+
const defaults = {"baseColor": "#253bb9", "bodyColor": "#359ee5", "bodyEndColor": "#2451c9", "bodyGradientStrength": 50, "bodyGradientAngle": 90, "bodyGradientRange": 100, "bodyX": 129, "bodyY": 104, "bodyWidth": 190, "bodyHeight": 166, "bodyBlur": 12, "bodyOpacity": 100, "mainColor": "#ffffff", "mainInset": 10, "mainWidth": 8, "mainStart": 85, "mainLength": 12, "mainFadeRange": 35, "mainFadeStrength": 100, "mainBlur": 1, "mainOpacity": 95, "secondaryColor": "#dbf1ff", "secondaryInset": 5, "secondaryWidth": 4, "secondaryStart": 66, "secondaryLength": 17, "secondaryFadeRange": 35, "secondaryFadeStrength": 100, "secondaryBlur": 1.5, "secondaryOpacity": 30, "reflectionColor": "#a8c7ff", "reflectionInset": 7, "reflectionWidth": 16, "reflectionStart": 26, "reflectionLength": 20, "reflectionFadeRange": 35, "reflectionFadeStrength": 100, "reflectionBlur": 3, "reflectionOpacity": 60, "edgeColor": "#d5efff", "edgeWidth": 4, "edgeBlur": 1.5, "edgeOpacity": 55, "eyeColor": "#ffffff"};
|
|
4
|
+
export function matchingIceEyeColor(values) {
|
|
5
|
+
const color = values.baseColor || values.bodyColor || '#94afd0';
|
|
6
|
+
const [r,g,b] = [1,3,5].map(offset => parseInt(color.slice(offset,offset+2),16)/255);
|
|
7
|
+
const max = Math.max(r,g,b), min = Math.min(r,g,b), delta = max-min;
|
|
8
|
+
const lightness = (max+min)/2;
|
|
9
|
+
let hue = 0;
|
|
10
|
+
if (delta) hue = max === r ? ((g-b)/delta+6)%6 : max === g ? (b-r)/delta+2 : (r-g)/delta+4;
|
|
11
|
+
const saturation = delta < .025 ? .08 : Math.max(.24,Math.min(.55,delta/(1-Math.abs(2*lightness-1))));
|
|
12
|
+
// Keep the body's hue while lowering lightness for readable, colored eyes.
|
|
13
|
+
const chroma = (1-Math.abs(2*.31-1))*saturation;
|
|
14
|
+
const x = chroma*(1-Math.abs(hue%2-1)), m = .31-chroma/2;
|
|
15
|
+
const rgb = [[chroma,x,0],[x,chroma,0],[0,chroma,x],[0,x,chroma],[x,0,chroma],[chroma,0,x]][Math.floor(hue)];
|
|
16
|
+
return '#' + rgb.map(value => Math.round((value+m)*255).toString(16).padStart(2,'0')).join('');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function layerDefaults(name) {
|
|
20
|
+
const values = {...defaults};
|
|
21
|
+
if ((glazeVariants[name]?.source || name) === 'iceglaze') Object.assign(values, {
|
|
22
|
+
baseColor:'#94afd0',bodyColor:'#d4e3f3',bodyEndColor:'#b4cbe3',bodyGradientStrength:0,reflectionColor:'#edf7ff',edgeColor:'#f3f8ff',
|
|
23
|
+
});
|
|
24
|
+
Object.assign(values,glazeVariants[name]?.palette);
|
|
25
|
+
if (['iceglaze','mintice','blushice','champagneice'].includes(name)) values.eyeColor = matchingIceEyeColor(values);
|
|
26
|
+
return values;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Build only the requested arc, with a tapered silhouette and opacity gradient.
|
|
30
|
+
// Short adjoining patches let the gradient follow the bend, even across 0%.
|
|
31
|
+
// This avoids repeated SVG dashes and a uniform bright line with blunt ends.
|
|
32
|
+
function drawRibbon(layer, shape, values, key) {
|
|
33
|
+
const doc = layer.ownerDocument;
|
|
34
|
+
const ns = 'http://www.w3.org/2000/svg';
|
|
35
|
+
const fragment = doc.createDocumentFragment();
|
|
36
|
+
const make = (tag,attrs,parent) => {
|
|
37
|
+
const node = doc.createElementNS(ns,tag);
|
|
38
|
+
for (const [name,value] of Object.entries(attrs)) node.setAttribute(name,value);
|
|
39
|
+
parent.append(node);
|
|
40
|
+
return node;
|
|
41
|
+
};
|
|
42
|
+
const span = values[`${key}Length`] / 100;
|
|
43
|
+
const total = shape.getTotalLength();
|
|
44
|
+
const start = values[`${key}Start`] / 100;
|
|
45
|
+
const fadeRange = values[`${key}FadeRange`] / 100;
|
|
46
|
+
const strength = values[`${key}FadeStrength`] / 100;
|
|
47
|
+
const fade = t => {
|
|
48
|
+
const distance = Math.min(t,1-t);
|
|
49
|
+
const u = fadeRange > 0 ? Math.min(1,Math.max(0,distance / fadeRange)) : 1;
|
|
50
|
+
return 1-strength + strength*u*u*(3-2*u);
|
|
51
|
+
};
|
|
52
|
+
const at = length => shape.getPointAtLength(((length % total) + total) % total);
|
|
53
|
+
const point = t => at((start+t*span)*total);
|
|
54
|
+
const pieces = Math.max(1,Math.ceil(span*8));
|
|
55
|
+
const defs = make('defs',{},fragment);
|
|
56
|
+
for (let i=0;i<pieces;i++) {
|
|
57
|
+
const a = i/pieces, b = (i+1)/pieces;
|
|
58
|
+
const first = point(a), last = point(b);
|
|
59
|
+
const gradientId = `${layer.id}-fade-${i}`;
|
|
60
|
+
const paint = make('linearGradient',{id:gradientId,gradientUnits:'userSpaceOnUse',x1:first.x,y1:first.y,x2:last.x,y2:last.y},defs);
|
|
61
|
+
for (let j=0;j<=8;j++) make('stop',{offset:j/8,'stop-color':values[`${key}Color`],'stop-opacity':fade(a+(b-a)*j/8)},paint);
|
|
62
|
+
const outer = [], inner = [];
|
|
63
|
+
const steps = Math.max(8,Math.ceil(total*span/pieces/3));
|
|
64
|
+
for (let j=0;j<=steps;j++) {
|
|
65
|
+
const t = a+(b-a)*j/steps, distance = (start+t*span)*total;
|
|
66
|
+
const center = point(t), before = at(distance-.4), after = at(distance+.4);
|
|
67
|
+
const dx = after.x-before.x, dy = after.y-before.y;
|
|
68
|
+
const magnitude = Math.hypot(dx,dy) || 1;
|
|
69
|
+
const halfWidth = values[`${key}Width`] / 2 * (.15+.85*Math.sqrt(fade(t)));
|
|
70
|
+
outer.push(`${center.x+dy/magnitude*halfWidth} ${center.y-dx/magnitude*halfWidth}`);
|
|
71
|
+
inner.push(`${center.x-dy/magnitude*halfWidth} ${center.y+dx/magnitude*halfWidth}`);
|
|
72
|
+
}
|
|
73
|
+
make('path',{d:`M${outer.join('L')}L${inner.reverse().join('L')}Z`,fill:`url(#${gradientId})`},fragment);
|
|
74
|
+
}
|
|
75
|
+
layer.replaceChildren(fragment);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function setLayers(get, values, shape) {
|
|
79
|
+
const body = get('body');
|
|
80
|
+
const sx = values.bodyWidth / 200, sy = values.bodyHeight / 200;
|
|
81
|
+
body.setAttribute('transform',`translate(${values.bodyX-120*sx} ${values.bodyY-120*sy}) scale(${sx} ${sy})`);
|
|
82
|
+
const paint = get('body-paint');
|
|
83
|
+
const angle = values.bodyGradientAngle * Math.PI / 180;
|
|
84
|
+
const radius = values.bodyGradientRange / 200;
|
|
85
|
+
paint.setAttribute('x1',.5-Math.cos(angle)*radius);
|
|
86
|
+
paint.setAttribute('y1',.5-Math.sin(angle)*radius);
|
|
87
|
+
paint.setAttribute('x2',.5+Math.cos(angle)*radius);
|
|
88
|
+
paint.setAttribute('y2',.5+Math.sin(angle)*radius);
|
|
89
|
+
const strength = values.bodyGradientStrength / 100;
|
|
90
|
+
const endColor = '#' + [1,3,5].map(offset => {
|
|
91
|
+
const from = parseInt(values.bodyColor.slice(offset,offset+2),16);
|
|
92
|
+
const to = parseInt(values.bodyEndColor.slice(offset,offset+2),16);
|
|
93
|
+
return Math.round(from+(to-from)*strength).toString(16).padStart(2,'0');
|
|
94
|
+
}).join('');
|
|
95
|
+
paint.firstElementChild.setAttribute('stop-color',values.bodyColor);
|
|
96
|
+
paint.lastElementChild.setAttribute('stop-color',endColor);
|
|
97
|
+
body.setAttribute('opacity',values.bodyOpacity / 100);
|
|
98
|
+
get('body-blur').firstElementChild.setAttribute('stdDeviation',values.bodyBlur);
|
|
99
|
+
for (const key of arcLayers) {
|
|
100
|
+
const layer = get(key);
|
|
101
|
+
const scale = 1 - values[`${key}Inset`] / 100;
|
|
102
|
+
const offset = 120 * (1 - scale);
|
|
103
|
+
const length = values[`${key}Length`];
|
|
104
|
+
layer.setAttribute('transform',`translate(${offset} ${offset}) scale(${scale})`);
|
|
105
|
+
layer.setAttribute('opacity',length <= 0 ? 0 : values[`${key}Opacity`] / 100);
|
|
106
|
+
drawRibbon(layer,shape,values,key);
|
|
107
|
+
get(`${key}-blur`).firstElementChild.setAttribute('stdDeviation',values[`${key}Blur`]);
|
|
108
|
+
}
|
|
109
|
+
const edge = get('edge');
|
|
110
|
+
edge.setAttribute('stroke',values.edgeColor);
|
|
111
|
+
edge.setAttribute('stroke-width',values.edgeWidth);
|
|
112
|
+
edge.setAttribute('opacity',values.edgeOpacity / 100);
|
|
113
|
+
get('edge-blur').firstElementChild.setAttribute('stdDeviation',values.edgeBlur);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function createLayerTexture(defs,id,name,el,gradient) {
|
|
117
|
+
const values = layerDefaults(name);
|
|
118
|
+
const shape = defs.querySelector('#headShape');
|
|
119
|
+
const p = el('pattern',{id,width:240,height:240,patternUnits:'userSpaceOnUse'},defs);
|
|
120
|
+
const nodes = new Map();
|
|
121
|
+
const add = (key,tag,attrs,parent) => {
|
|
122
|
+
const node = el(tag,{id:`${id}-${key}`,...attrs},parent);
|
|
123
|
+
nodes.set(key,node);
|
|
124
|
+
return node;
|
|
125
|
+
};
|
|
126
|
+
const blur = key => {
|
|
127
|
+
const filter = add(`${key}-blur`,'filter',{filterUnits:'userSpaceOnUse',x:-200,y:-200,width:640,height:640,'color-interpolation-filters':'sRGB'},defs);
|
|
128
|
+
el('feGaussianBlur',{stdDeviation:0},filter);
|
|
129
|
+
return `url(#${id}-${key}-blur)`;
|
|
130
|
+
};
|
|
131
|
+
const bodyPaint = gradient(defs,'linearGradient',`${id}-body-paint`,{},[[0,values.bodyColor],[1,values.bodyEndColor]]);
|
|
132
|
+
nodes.set('body-paint',bodyPaint);
|
|
133
|
+
add('body','use',{href:'#headShape',fill:`url(#${id}-body-paint)`,filter:blur('body')},p);
|
|
134
|
+
for (const key of arcLayers) {
|
|
135
|
+
add(key,'g',{filter:blur(key)},p);
|
|
136
|
+
}
|
|
137
|
+
add('edge','use',{href:'#headShape',fill:'none',filter:blur('edge')},p);
|
|
138
|
+
setLayers(key => nodes.get(key),values,shape);
|
|
139
|
+
p._layerValues = values;
|
|
140
|
+
// Keep the curved highlights attached to the animated head. Tracing them is
|
|
141
|
+
// costly, so a squeeze or drag redraws them at once, while the tiny changes
|
|
142
|
+
// of idle breathing redraw them a few times a second.
|
|
143
|
+
let drawn = shape.getBBox(), drawnAt = performance.now(), pending = 0;
|
|
144
|
+
const redraw = () => {
|
|
145
|
+
pending = 0;
|
|
146
|
+
if (!p.isConnected) return;
|
|
147
|
+
for (const key of arcLayers) drawRibbon(nodes.get(key),shape,p._layerValues,key);
|
|
148
|
+
drawn = shape.getBBox();
|
|
149
|
+
drawnAt = performance.now();
|
|
150
|
+
};
|
|
151
|
+
const observer = new MutationObserver(() => {
|
|
152
|
+
if (!p.isConnected) { observer.disconnect(); return; }
|
|
153
|
+
const box = shape.getBBox();
|
|
154
|
+
const moved = Math.max(Math.abs(box.x - drawn.x), Math.abs(box.y - drawn.y),
|
|
155
|
+
Math.abs(box.width - drawn.width), Math.abs(box.height - drawn.height));
|
|
156
|
+
if (moved > 1.5) redraw();
|
|
157
|
+
// Under half a pixel the ribbons would look the same.
|
|
158
|
+
else if (moved > .5 && !pending) pending = setTimeout(redraw, Math.max(0, 250 - (performance.now() - drawnAt)));
|
|
159
|
+
});
|
|
160
|
+
observer.observe(shape,{attributes:true,attributeFilter:['d']});
|
|
161
|
+
return p;
|
|
162
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// The material skins, as the painter reads them.
|
|
2
|
+
export const MATERIALS = {
|
|
3
|
+
"blackglaze": {"rim": "#dce5ee", "antenna": ["#d9e3ed", "#4a596a", "#101923"], "pattern": "blackglaze", "simpleLayers": true, "darkColor": "#090d14", "raisedEyes": true, "eyeShadow": "#090d14"},
|
|
4
|
+
"blueglaze": {"rim": "#b5daef", "antenna": ["#e9faff", "#58abe9", "#2b52b3"], "pattern": "blueglaze", "simpleLayers": true, "darkColor": "#253bb9", "raisedEyes": true},
|
|
5
|
+
"jadeglaze": {"rim": "#ddfff0", "antenna": ["#effff6", "#50c99f", "#126b57"], "pattern": "jadeglaze", "simpleLayers": true, "darkColor": "#086953", "raisedEyes": true, "eyeShadow": "#086953"},
|
|
6
|
+
"berryglaze": {"rim": "#fff0f7", "antenna": ["#fff1f8", "#ed8cba", "#a53169"], "pattern": "berryglaze", "simpleLayers": true, "darkColor": "#9e285f", "raisedEyes": true, "eyeShadow": "#9e285f"},
|
|
7
|
+
"amberglaze": {"rim": "#fff3dc", "antenna": ["#fff7dc", "#f2b85e", "#ad5e27"], "pattern": "amberglaze", "simpleLayers": true, "darkColor": "#ae531b", "raisedEyes": true, "eyeShadow": "#ae531b"},
|
|
8
|
+
"irisglaze": {"rim": "#f4edff", "antenna": ["#f7efff", "#b18bed", "#6440ac"], "pattern": "irisglaze", "simpleLayers": true, "darkColor": "#5831a8", "raisedEyes": true, "eyeShadow": "#5831a8"},
|
|
9
|
+
"iceglaze": {"rim": "#d8e5f3", "antenna": ["#ffffff", "#c3dbef", "#7d9fc2"], "pattern": "iceglaze", "simpleLayers": true, "darkColor": "#94afd0", "raisedEyes": true},
|
|
10
|
+
"mintice": {"rim": "#f5fff9", "antenna": ["#ffffff", "#c4e6d7", "#7fae9c"], "pattern": "mintice", "simpleLayers": true, "darkColor": "#8bbcae", "raisedEyes": true, "eyeShadow": "#8bbcae"},
|
|
11
|
+
"blushice": {"rim": "#fff8fc", "antenna": ["#ffffff", "#e8c9d9", "#b28b9f"], "pattern": "blushice", "simpleLayers": true, "darkColor": "#c093ab", "raisedEyes": true, "eyeShadow": "#c093ab"},
|
|
12
|
+
"champagneice": {"rim": "#fffaf0", "antenna": ["#ffffff", "#e7d8b9", "#b4a078"], "pattern": "champagneice", "simpleLayers": true, "darkColor": "#c2ac81", "raisedEyes": true, "eyeShadow": "#c2ac81"},
|
|
13
|
+
"lavenderice": {"rim": "#fbf8ff", "antenna": ["#ffffff", "#d8ceeb", "#9f91bd"], "pattern": "lavenderice", "simpleLayers": true, "darkColor": "#a89ac9", "raisedEyes": true, "eyeShadow": "#a89ac9"},
|
|
14
|
+
"whiteice": {"rim": "#ffffff", "antenna": ["#ffffff", "#e7f2f7", "#abbfc9"], "pattern": "whiteice", "simpleLayers": true, "darkColor": "#c0cdd6", "raisedEyes": true, "eyeShadow": "#c0cdd6"},
|
|
15
|
+
"clearwhite": {"base": ["#ffffff", "#eff5f7", "#d8e4ea", "#b3c5d0"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.1, "shade": 0.18, "antenna": ["#ffffff", "#e0ebf0", "#9bb2c1"], "pattern": "clearsilver", "translucent": true, "glassTint": "#e4f0f7", "glassRim": "#edf7ff"},
|
|
16
|
+
"clearsilver": {"base": ["#fcfaf6", "#d3dbdf", "#98a6ae", "#66767f"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.1, "shade": 0.18, "antenna": ["#f5fbff", "#b9cbd4", "#607b8b"], "pattern": "clearsilver", "translucent": true, "glassTint": "#e4f0f7", "glassRim": "#edf7ff"},
|
|
17
|
+
"clearweighted": {"base": ["#fcfaf6", "#d3dbdf", "#98a6ae", "#66767f"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.1, "shade": 0.18, "antenna": ["#f5fbff", "#b9cbd4", "#607b8b"], "pattern": "clearweighted", "translucent": true, "glassTint": "#e4f0f7", "glassRim": "#edf7ff"},
|
|
18
|
+
"clearhard": {"base": ["#fcfaf6", "#d3dbdf", "#98a6ae", "#66767f"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.035, "shade": 0.18, "antenna": ["#f5fbff", "#b9cbd4", "#607b8b"], "pattern": "clearhard", "translucent": true, "glassTint": "#e4f0f7", "glassRim": "#edf7ff"},
|
|
19
|
+
"clearsmoke": {"base": ["#dce5e9", "#abbac3", "#778e9d", "#485f70"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.1, "shade": 0.18, "antenna": ["#e8f2f8", "#9ab1c0", "#4e697c"], "pattern": "clearsilver", "translucent": true, "glassTint": "#e4f0f7", "glassRim": "#edf7ff"},
|
|
20
|
+
"clearink": {"base": ["#bacbd6", "#7e97a8", "#4b687e", "#2a4257"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.1, "shade": 0.18, "antenna": ["#cedfe9", "#7895aa", "#314f65"], "pattern": "clearsilver", "translucent": true, "glassTint": "#e4f0f7", "glassRim": "#edf7ff"},
|
|
21
|
+
"golddrop": {"base": ["#fcfbf6", "#f0e4c5", "#dcc37d", "#c69f35"], "eye": "#594818", "rim": "#f8f2e3", "shine": 0.12, "shade": 0.26, "antenna": ["#fefefc", "#e7d5a3", "#b3902f"], "pattern": "silverdrop"},
|
|
22
|
+
"deepmetalgold": {"base": ["#f6e1b8", "#d4a446", "#a57009", "#704a00"], "eye": "#f2f7fa", "rim": "#efd093", "shine": 0.1, "shade": 0.29, "antenna": ["#fbefd7", "#cd9b3a", "#7b5100"], "pattern": "silverdrop"},
|
|
23
|
+
"deepmetalrose": {"base": ["#fcdcd9", "#e19991", "#b3645b", "#833f38"], "eye": "#f2f7fa", "rim": "#f7c8c3", "shine": 0.1, "shade": 0.29, "antenna": ["#feecea", "#db9087", "#8d463e"], "pattern": "silverdrop"},
|
|
24
|
+
"copperdeep": {"base": ["#f0ded4", "#d29c7e", "#ac663d", "#734428"], "eye": "#faf5f2", "rim": "#e8ccbc", "shine": 0.1, "shade": 0.29, "antenna": ["#f7eee8", "#cd9371", "#7c492c"], "pattern": "silverdrop"},
|
|
25
|
+
"deepmetalcopper": {"base": ["#ffddc9", "#ec9969", "#c0652f", "#8d4012"], "eye": "#f2f7fa", "rim": "#fec9a9", "shine": 0.1, "shade": 0.29, "antenna": ["#ffede2", "#e7905d", "#984617"], "pattern": "silverdrop"},
|
|
26
|
+
"iphonecosmicorange": {"base": ["#ffdecc", "#ff9962", "#e3611c", "#ae3d01"], "eye": "#f2f7fa", "rim": "#ffcaae", "shine": 0.1, "shade": 0.29, "antenna": ["#ffede4", "#ff8e52", "#b94405"], "pattern": "silverdrop"},
|
|
27
|
+
"deepmetalbronze": {"base": ["#e8e5bc", "#b5ac51", "#827a14", "#585100"], "eye": "#f2f7fa", "rim": "#dad59a", "shine": 0.1, "shade": 0.29, "antenna": ["#f3f1da", "#aca444", "#615900"], "pattern": "silverdrop"},
|
|
28
|
+
"deepmetaltitanium": {"base": ["#dbe4ee", "#97aac2", "#627791", "#3d4f66"], "eye": "#f2f7fa", "rim": "#c7d3e3", "shine": 0.1, "shade": 0.29, "antenna": ["#ebf0f6", "#8ea1bb", "#44576e"], "pattern": "silverdrop"},
|
|
29
|
+
"deepmetalplatinum": {"base": ["#eff0f2", "#cacdd2", "#a5aab0", "#848990"], "eye": "#43515c", "rim": "#e5e7e9", "shine": 0.1, "shade": 0.29, "antenna": ["#f6f7f8", "#c4c8cd", "#8b9097"], "pattern": "silverdrop"},
|
|
30
|
+
"deepmetalchampagne": {"base": ["#f1eadc", "#cebb97", "#a78f61", "#816a3c"], "eye": "#795b36", "rim": "#e8ddc7", "shine": 0.1, "shade": 0.29, "antenna": ["#f8f4ec", "#c8b48d", "#897143"], "pattern": "silverdrop"},
|
|
31
|
+
"deepmetaliceblue": {"base": ["#d4ecf8", "#86bfdc", "#4d92b6", "#2a6b8d"], "eye": "#275772", "rim": "#bddff2", "shine": 0.1, "shade": 0.29, "antenna": ["#e8f5fb", "#7bb8d7", "#307395"], "pattern": "silverdrop"},
|
|
32
|
+
"iphoneultramarine": {"base": ["#dae0ff", "#8ea0ff", "#576bd6", "#34459c"], "eye": "#f2f7fa", "rim": "#c4ceff", "shine": 0.1, "shade": 0.29, "antenna": ["#ebeeff", "#8397fe", "#3a4ca8"], "pattern": "silverdrop"},
|
|
33
|
+
"deepmetalviolet": {"base": ["#efd8ff", "#ce88ff", "#9e4fd5", "#6c2e98"], "eye": "#f2f7fa", "rim": "#e5c1ff", "shine": 0.1, "shade": 0.29, "antenna": ["#f6eaff", "#c97cff", "#7633a5"], "pattern": "silverdrop"},
|
|
34
|
+
"iphoneburgundy": {"base": ["#fbbfd3", "#be5f7e", "#702b42", "#38131f"], "eye": "#f2f7fa", "rim": "#f09fba", "shine": 0.1, "shade": 0.29, "antenna": ["#ffdbe7", "#b25473", "#421725"], "pattern": "silverdrop"},
|
|
35
|
+
"iphoneteal": {"base": ["#cdeae9", "#76bab7", "#3d8986", "#1d605e"], "eye": "#f2f7fa", "rim": "#b2dddc", "shine": 0.1, "shade": 0.29, "antenna": ["#e3f4f3", "#6bb2af", "#226865"], "pattern": "silverdrop"},
|
|
36
|
+
"deepmetalforest": {"base": ["#bad4ca", "#588272", "#26453a", "#10221b"], "eye": "#f2f7fa", "rim": "#99bcaf", "shine": 0.1, "shade": 0.29, "antenna": ["#d8e8e2", "#4e7767", "#142820"], "pattern": "silverdrop"},
|
|
37
|
+
"iphonenatural": {"base": ["#eceae7", "#c1bcb4", "#969085", "#716b60"], "eye": "#59534b", "rim": "#e0ddd8", "shine": 0.1, "shade": 0.29, "antenna": ["#f5f4f2", "#bab5ac", "#787268"], "pattern": "silverdrop"},
|
|
38
|
+
"iphonedeepurple": {"base": ["#d7ccdc", "#86748f", "#4a3c50", "#251d28"], "eye": "#f2f7fa", "rim": "#bfb1c7", "shine": 0.1, "shade": 0.29, "antenna": ["#e9e3ed", "#7b6a84", "#2b222f"], "pattern": "silverdrop"},
|
|
39
|
+
"iphonepink": {"base": ["#f8eff1", "#e5ccd1", "#cda8b0", "#b28890"], "eye": "#804d61", "rim": "#f3e6e8", "shine": 0.1, "shade": 0.29, "antenna": ["#fbf7f8", "#e1c6cc", "#b88e97"], "pattern": "silverdrop"},
|
|
40
|
+
"iphonesage": {"base": ["#e8ece4", "#b8c2ac", "#8b987b", "#667357"], "eye": "#4b6041", "rim": "#dbe1d4", "shine": 0.1, "shade": 0.29, "antenna": ["#f3f5f0", "#b1bba4", "#6d7a5e"], "pattern": "silverdrop"},
|
|
41
|
+
"iphonelavender": {"base": ["#eeebf6", "#c8bfdb", "#a095ba", "#7d7198"], "eye": "#61517d", "rim": "#e4dfef", "shine": 0.1, "shade": 0.29, "antenna": ["#f6f4fa", "#c2b8d6", "#84789f"], "pattern": "silverdrop"},
|
|
42
|
+
"satinplatinum": {"base": ["#bcc0c4", "#7e868e", "#5b6269", "#44494e"], "eye": "#fcfaf3", "rim": "#bec2c6", "shine": 0.08, "shade": 0.32, "antenna": ["#dbdddf", "#838b93", "#50565c"], "pattern": "silverdrop"},
|
|
43
|
+
"satinrose": {"base": ["#d5aca1", "#ac604d", "#774235", "#512d24"], "eye": "#fcfaf3", "rim": "#d6aea4", "shine": 0.08, "shade": 0.32, "antenna": ["#e8d2cd", "#b16552", "#64382d"], "pattern": "silverdrop"},
|
|
44
|
+
"satinredcopper": {"base": ["#dba483", "#a65c30", "#6a3a1f", "#412413"], "eye": "#fcfaf3", "rim": "#dca687", "shine": 0.08, "shade": 0.32, "antenna": ["#ebcdbb", "#af6033", "#552f19"], "pattern": "silverdrop"},
|
|
45
|
+
"satinbronze": {"base": ["#c6b680", "#7f6f39", "#4d4322", "#2d2714"], "eye": "#fcfaf3", "rim": "#c7b783", "shine": 0.08, "shade": 0.32, "antenna": ["#dfd6b8", "#87753c", "#3c341b"], "pattern": "silverdrop"},
|
|
46
|
+
"satingunmetal": {"base": ["#7a8a9b", "#353e46", "#1a1e22", "#0c0e10"], "eye": "#fcfaf3", "rim": "#7d8d9d", "shine": 0.08, "shade": 0.32, "antenna": ["#b2bcc5", "#3a434c", "#121518"], "pattern": "silverdrop"},
|
|
47
|
+
"silverbright": {"base": ["#ffffff", "#f0f3f3", "#d5dee2", "#a5b5bf"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.16, "shade": 0.17, "antenna": ["#ffffff", "#e1e9ed", "#95a8b3"], "pattern": "silverdrop"},
|
|
48
|
+
"silverdrop": {"base": ["#fcfaf6", "#d5dde0", "#a3afb6", "#71818a"], "eye": "#283c49", "rim": "#e9eff2", "shine": 0.12, "shade": 0.26, "antenna": ["#fbfdff", "#bcc8ce", "#63757f"], "pattern": "silverdrop"},
|
|
49
|
+
"silverdeep": {"base": ["#dce4e8", "#9baab4", "#657784", "#3d505e"], "eye": "#f2f7fa", "rim": "#c7d4dd", "shine": 0.1, "shade": 0.29, "antenna": ["#e9f1f6", "#8fa2af", "#425866"], "pattern": "silverdrop"},
|
|
50
|
+
"silvergraphite": {"base": ["#aabac5", "#647987", "#3b505f", "#213440"], "eye": "#f3f8fc", "rim": "#a8bccb", "shine": 0.08, "shade": 0.32, "antenna": ["#ccdbe5", "#667f90", "#2b4252"], "pattern": "silverdrop"},
|
|
51
|
+
"obsidian": {"base": ["#7b8796", "#313a47", "#101722", "#05080e"], "eye": "#f0f7ff", "rim": "#c1d5f4", "shine": 0.57, "shade": 0.68, "antenna": ["#c3cfdf", "#384452", "#080e19"]},
|
|
52
|
+
"porcelain": {"base": ["#ffffff", "#f5f4ec", "#d9dad3", "#a3aaab"], "eye": "#343b3c", "rim": "#ffffff", "shine": 0.95, "shade": 0.18, "antenna": ["#ffffff", "#e7e9df", "#a6afb0"]},
|
|
53
|
+
"clay": {"base": ["#e6b59a", "#d9997d", "#c58065", "#ad674e"], "eye": "#573c34", "rim": "#edc6ae", "shine": 0.12, "shade": 0.22, "antenna": ["#e8bca1", "#cb8b6f", "#a96650"], "pattern": "grain", "matte": true},
|
|
54
|
+
"terrazzo": {"base": ["#fff9ed", "#f1e7d7", "#e1d3c1", "#cab9a8"], "eye": "#635146", "rim": "#fff7e8", "shine": 0.18, "shade": 0.22, "matte": true, "pattern": "terrazzo", "antenna": ["#fff5e3", "#e4ceb2", "#b5987f"]},
|
|
55
|
+
"ceramicblue": {"base": ["#fffaf0", "#eee5d3", "#d5c5aa", "#b5a58b"], "eye": "#615246", "rim": "#fff9e6", "shine": 0.7, "shade": 0.25, "antenna": ["#fff9e6", "#eee5d3", "#b5a58b"], "pattern": "ceramicblue"},
|
|
56
|
+
"woodmaple": {"base": ["#f7e8ca", "#e4c999", "#c9a575", "#a87d50"], "eye": "#62492d", "rim": "#f3e0b8", "shine": 0.075, "shade": 0.12, "antenna": ["#fff1d2", "#d7b585", "#997146"], "pattern": "woodmaple", "matte": true},
|
|
57
|
+
"woodoak": {"base": ["#efd3a0", "#cea065", "#ad7844", "#82532e"], "eye": "#503522", "rim": "#e7c594", "shine": 0.085, "shade": 0.16, "antenna": ["#f6dfb4", "#c99b60", "#84552f"], "pattern": "woodoak", "matte": true},
|
|
58
|
+
"woodwalnut": {"base": ["#b58d67", "#865b3c", "#5e3b28", "#38251c"], "eye": "#f5e7cc", "rim": "#c9a27c", "shine": 0.11, "shade": 0.2, "antenna": ["#d9b28b", "#8b6143", "#432d21"], "pattern": "woodwalnut", "matte": true},
|
|
59
|
+
"woodrose": {"base": ["#cf9376", "#a65d42", "#773d2c", "#48251e"], "eye": "#f8e8d2", "rim": "#d9a48a", "shine": 0.15, "shade": 0.19, "antenna": ["#e2b39a", "#aa674b", "#582d23"], "pattern": "woodrose", "matte": true},
|
|
60
|
+
"woodebony": {"base": ["#696052", "#42382d", "#2a221c", "#171411"], "eye": "#f2e7d2", "rim": "#8c7a60", "shine": 0.12, "shade": 0.23, "antenna": ["#b0a08a", "#554636", "#241c17"], "pattern": "woodebony", "matte": true},
|
|
61
|
+
"cork": {"base": ["#e8cb99", "#cfad76", "#b99159", "#9c7646"], "eye": "#604831", "rim": "#efdab6", "shine": 0.1, "shade": 0.25, "antenna": ["#efdab6", "#cfad76", "#9c7646"], "pattern": "cork"},
|
|
62
|
+
"basketball": {"base": ["#ffbd63", "#ed8836", "#d26320", "#93421c"], "eye": "#fff4d9", "rim": "#ffd29a", "shine": 0.16, "shade": 0.32, "antenna": ["#ffd29a", "#ed8836", "#93421c"], "pattern": "basketball", "matte": true},
|
|
63
|
+
"baseball": {"base": ["#fffdf4", "#f3eee0", "#e2dccb", "#bfb7a4"], "eye": "#364e65", "rim": "#fffdf0", "shine": 0.2, "shade": 0.24, "antenna": ["#fffdf0", "#f3eee0", "#bfb7a4"], "pattern": "baseball", "matte": true},
|
|
64
|
+
"aurora": {"base": ["#9aebea", "#92c9f1", "#a795eb", "#e79bc7"], "eye": "#2d3052", "rim": "#fff4fe", "shine": 0.82, "shade": 0.3, "antenna": ["#edffff", "#9ba7ec", "#7456a5"]},
|
|
65
|
+
"pearl": {"base": ["#fff8eb", "#ecd8e6", "#c6ddd8", "#b5afcf"], "eye": "#615e79", "rim": "#fff6e8", "shine": 0.82, "shade": 0.25, "antenna": ["#fff6e8", "#ecd8e6", "#b5afcf"], "pattern": "pearl"},
|
|
66
|
+
"hologram": {"base": ["#88e9df", "#c5b6f5", "#f6b8d0", "#f5ebad", "#9adce0"], "eye": "#393e75", "rim": "#f5ffff", "shine": 0.7, "shade": 0.25, "antenna": ["#f5ffff", "#c5b6f5", "#9adce0"], "pattern": "hologram", "linear": true},
|
|
67
|
+
"ice": {"base": ["#f0ffff", "#b6e9f2", "#71b9d4", "#437baf"], "eye": "#214f7d", "rim": "#efffff", "shine": 0.8, "shade": 0.25, "antenna": ["#efffff", "#b6e9f2", "#437baf"], "pattern": "ice", "translucent": true},
|
|
68
|
+
"soap": {"base": ["#f9eafa", "#bfe6ed", "#ded1f0", "#bad9e6"], "eye": "#635077", "rim": "#fff4fa", "shine": 0.92, "shade": 0.13, "antenna": ["#fff4fa", "#bfe6ed", "#bad9e6"], "pattern": "soap", "translucent": true},
|
|
69
|
+
"denim": {"base": ["#698ba3", "#456d8b", "#315775", "#244460"], "eye": "#fff0ce", "rim": "#9db2c2", "shine": 0.12, "shade": 0.28, "matte": true, "pattern": "denim", "stitched": true, "antenna": ["#8ca6b9", "#4a718b", "#29465d"]},
|
|
70
|
+
"leather": {"base": ["#c79665", "#ab784c", "#8f5d38", "#6a432b"], "eye": "#ffedd0", "rim": "#e8c095", "shine": 0.16, "shade": 0.25, "antenna": ["#e8c095", "#ab784c", "#6a432b"], "pattern": "leather", "stitched": true, "matte": true},
|
|
71
|
+
"knit": {"base": ["#d5a4b6", "#b5809b", "#925d7c", "#70465f"], "eye": "#fff2da", "rim": "#ebc9d2", "shine": 0.06, "shade": 0.22, "antenna": ["#ebc9d2", "#b67e95", "#79435f"], "pattern": "second-knit", "matte": true},
|
|
72
|
+
"lace": {"base": ["#4d526f", "#353a57", "#252b46", "#1c2138"], "eye": "#fff0d6", "rim": "#d6d5df", "shine": 0.15, "shade": 0.25, "antenna": ["#d6d5df", "#353a57", "#1c2138"], "pattern": "lace", "matte": true},
|
|
73
|
+
"tartan": {"base": ["#ffbcc7", "#ef899e", "#d86383", "#b34364"], "eye": "#fff0cb", "rim": "#ffe5df", "shine": 0.08, "shade": 0.25, "antenna": ["#ffe5df", "#ef899e", "#b34364"], "matte": true, "pattern": "tartan"},
|
|
74
|
+
"argyle": {"base": ["#e4d6ef", "#bcabd5", "#9a88bc", "#776397"], "eye": "#4e4168", "rim": "#fff0fe", "shine": 0.1, "shade": 0.25, "antenna": ["#fff0fe", "#bcabd5", "#776397"], "matte": true, "pattern": "argyle"},
|
|
75
|
+
"sashiko": {"base": ["#546b8b", "#394f71", "#273b5b", "#1a2a43"], "eye": "#fff1cf", "rim": "#bccfe1", "shine": 0.1, "shade": 0.25, "antenna": ["#bccfe1", "#394f71", "#1a2a43"], "matte": true, "pattern": "sashiko"},
|
|
76
|
+
"quilt": {"base": ["#ffe7db", "#f3bfb9", "#df969f", "#bd738c"], "eye": "#754e62", "rim": "#fff5e6", "shine": 0.1, "shade": 0.25, "antenna": ["#fff5e6", "#f3bfb9", "#bd738c"], "matte": true, "pattern": "quilt"},
|
|
77
|
+
"corduroy": {"base": ["#ffd5a0", "#f5b267", "#de8941", "#b5672d"], "eye": "#68402e", "rim": "#ffedc2", "shine": 0.08, "shade": 0.25, "antenna": ["#ffedc2", "#f5b267", "#b5672d"], "matte": true, "pattern": "corduroy"},
|
|
78
|
+
"linen": {"base": ["#fffaf0", "#eee5d3", "#d5c5aa", "#b5a58b"], "eye": "#615246", "rim": "#fff9e6", "shine": 0.05, "shade": 0.25, "antenna": ["#fff9e6", "#eee5d3", "#b5a58b"], "matte": true, "pattern": "linen"},
|
|
79
|
+
"bamboo": {"base": ["#e7d49b", "#ceb574", "#b79b5b", "#937a40"], "eye": "#574f2b", "rim": "#f4e5b5", "shine": 0.13, "shade": 0.25, "antenna": ["#f4e5b5", "#ceb574", "#937a40"], "pattern": "bamboo", "matte": true},
|
|
80
|
+
"candy": {"base": ["#ffd5df", "#f4a2bf", "#e782a7", "#c85d89"], "eye": "#7a3058", "rim": "#fff1f6", "shine": 0.7, "shade": 0.23, "antenna": ["#fff8fb", "#f3a0c3", "#be507f"], "pattern": "stripes"},
|
|
81
|
+
"cow": {"base": ["#fffdf5", "#f4f0e6", "#deded5", "#bfc8c6"], "eye": "#373d4b", "rim": "#fff7ed", "shine": 0.62, "shade": 0.16, "pattern": "revised-cow", "antenna": ["#fbd8e3", "#e8a5bc", "#bb718f"]},
|
|
82
|
+
"watermelon": {"base": ["#ffb5ad", "#f68d8f", "#e9747f", "#cc5267"], "eye": "#703b47", "rim": "#d9edbc", "shine": 0.55, "shade": 0.19, "pattern": "seeds", "edgeColor": "#7fa658", "antenna": ["#eef5c4", "#a9c372", "#638744"]},
|
|
83
|
+
"strawberry": {"base": ["#ffbcc7", "#ef899e", "#d86383", "#b34364"], "eye": "#613449", "rim": "#ffe5df", "shine": 0.6, "shade": 0.25, "antenna": ["#ffe5df", "#ef899e", "#b34364"], "pattern": "strawberry"},
|
|
84
|
+
"kiwi": {"base": ["#e2efb0", "#bdd574", "#94b94e", "#627f35"], "eye": "#304c29", "rim": "#edf6bf", "shine": 0.34, "shade": 0.19, "antenna": ["#edf6bf", "#a9c568", "#597538"], "pattern": "second-kiwi", "edgeColor": "#8a7845"},
|
|
85
|
+
"lemon": {"base": ["#fff3ac", "#f6d657", "#eab62c", "#c58c22"], "eye": "#70501e", "rim": "#fff9cb", "shine": 0.52, "shade": 0.16, "antenna": ["#fff9cb", "#efcf61", "#b97b25"], "pattern": "second-lemon", "edgeColor": "#e6c84b"},
|
|
86
|
+
"orangepeel": {"base": ["#ffd5a0", "#f5b267", "#de8941", "#b5672d"], "eye": "#68402e", "rim": "#ffedc2", "shine": 0.4, "shade": 0.25, "antenna": ["#ffedc2", "#f5b267", "#b5672d"], "pattern": "orangepeel"},
|
|
87
|
+
"dragonfruit": {"base": ["#fffefa", "#f6f4ec", "#e6e4df", "#c4cccb"], "eye": "#4b3b57", "rim": "#fff9e6", "shine": 0.42, "shade": 0.15, "antenna": ["#fff9e6", "#eee5d3", "#b5a58b"], "edgeColor": "#d4588c", "pattern": "revised-dragonfruit"},
|
|
88
|
+
"chocolate": {"base": ["#b38a69", "#8a6046", "#6a4334", "#493027"], "eye": "#fff0cb", "rim": "#d5b58e", "shine": 0.5, "shade": 0.25, "antenna": ["#d5b58e", "#8a6046", "#493027"], "pattern": "chocolate"},
|
|
89
|
+
"waffle": {"base": ["#ffd5a0", "#f5b267", "#de8941", "#b5672d"], "eye": "#68402e", "rim": "#ffedc2", "shine": 0.18, "shade": 0.25, "antenna": ["#ffedc2", "#f5b267", "#b5672d"], "matte": true, "pattern": "waffle"},
|
|
90
|
+
"cookie": {"base": ["#fff2a4", "#efcf61", "#d9a438", "#b97b25"], "eye": "#665024", "rim": "#fff9cb", "shine": 0.12, "shade": 0.25, "antenna": ["#fff9cb", "#efcf61", "#b97b25"], "matte": true, "pattern": "cookie"},
|
|
91
|
+
"donut": {"base": ["#ffbcc7", "#ef899e", "#d86383", "#b34364"], "eye": "#613449", "rim": "#ffe5df", "shine": 0.68, "shade": 0.25, "antenna": ["#ffe5df", "#ef899e", "#b34364"], "pattern": "donut"},
|
|
92
|
+
"cactus": {"base": ["#d4e6a0", "#a9c568", "#7f9d47", "#597538"], "eye": "#354b30", "rim": "#edf6bf", "shine": 0.22, "shade": 0.25, "antenna": ["#edf6bf", "#a9c568", "#597538"], "pattern": "cactus"},
|
|
93
|
+
"galaxy": {"base": ["#6545ad", "#45277f", "#193b70", "#101b3a"], "eye": "#fff6da", "rim": "#c1b0f5", "shine": 0.21, "shade": 0.32, "pattern": "galaxy", "antenna": ["#f0dfff", "#ad84ed", "#57338e"]},
|
|
94
|
+
"matcharib": {"base": ["#d1ef9b", "#96c953", "#6ba737", "#3e6e29"], "eye": "#fff9de", "rim": "#d6ecb0", "shine": 0.08, "shade": 0.28, "antenna": ["#d5eeac", "#96c85c", "#548039"], "pattern": "matcharib", "matte": true},
|
|
95
|
+
"cloud": {"base": ["#b5e0f2", "#86bfe0", "#5f9bc9", "#3e73a4"], "eye": "#264c76", "rim": "#e9f7ff", "shine": 0.2, "shade": 0.18, "antenna": ["#e9f7ff", "#78a6ce", "#355c89"], "pattern": "second-cloud"},
|
|
96
|
+
"wave": {"base": ["#5b7fa5", "#3f648e", "#2b4c77", "#20395d"], "eye": "#fff1d4", "rim": "#c6dded", "shine": 0.46, "shade": 0.25, "antenna": ["#c6dded", "#3f648e", "#20395d"], "pattern": "wave"},
|
|
97
|
+
"raindrop": {"base": ["#dbd9d0", "#b9bbb4", "#919a97", "#6b7b7c"], "eye": "#334b52", "rim": "#f4f0de", "shine": 0.7, "shade": 0.25, "antenna": ["#f4f0de", "#b9bbb4", "#6b7b7c"], "pattern": "raindrop"},
|
|
98
|
+
"snowflake": {"base": ["#546b8b", "#394f71", "#273b5b", "#1a2a43"], "eye": "#fff1cf", "rim": "#bccfe1", "shine": 0.15, "shade": 0.25, "antenna": ["#bccfe1", "#394f71", "#1a2a43"], "matte": true, "pattern": "snowflake"},
|
|
99
|
+
"polka": {"base": ["#af9beb", "#8c72d9", "#7860c4", "#5a469e"], "eye": "#fff9e8", "rim": "#e2d5ff", "shine": 0.34, "shade": 0.28, "antenna": ["#fff2ae", "#f2d77d", "#b9963b"], "pattern": "dots"},
|
|
100
|
+
"carbon": {"base": ["#4a5557", "#2c3639", "#1b2428", "#10191e"], "eye": "#e1f3e9", "rim": "#aabfbe", "shine": 0.29, "shade": 0.36, "pattern": "carbon", "antenna": ["#d2e2de", "#647b7a", "#263d42"]},
|
|
101
|
+
"blueprint": {"base": ["#6a9ed4", "#477ebc", "#2d609f", "#244a85"], "eye": "#effbff", "rim": "#c3e6ff", "shine": 0.16, "shade": 0.24, "matte": true, "pattern": "blueprint", "antenna": ["#d4f1ff", "#79a9d5", "#366496"]},
|
|
102
|
+
"origami": {"base": ["#f5e5d3", "#e6c7b0", "#b9c7c1", "#a0a8bb"], "eye": "#4a535a", "rim": "#fff0e2", "shine": 0.07, "shade": 0.25, "antenna": ["#fff0e2", "#e6c7b0", "#a0a8bb"], "pattern": "origami", "matte": true},
|
|
103
|
+
"circuit": {"base": ["#3c6c61", "#235347", "#163b34", "#102b29"], "eye": "#e8ffbd", "rim": "#abd5a7", "shine": 0.3, "shade": 0.25, "antenna": ["#abd5a7", "#235347", "#102b29"], "pattern": "circuit"},
|
|
104
|
+
"camo": {"base": ["#b0b594", "#8e9e75", "#71835e", "#4c6247"], "eye": "#fff2ca", "rim": "#d7dfb7", "shine": 0.06, "shade": 0.22, "antenna": ["#d7dfb7", "#7c8c5c", "#405237"], "pattern": "revised-camo", "matte": true},
|
|
105
|
+
"topo": {"base": ["#7dbbb6", "#519a98", "#347b80", "#235d68"], "eye": "#efffe4", "rim": "#bcebd6", "shine": 0.15, "shade": 0.25, "antenna": ["#bcebd6", "#519a98", "#235d68"], "pattern": "topo", "matte": true},
|
|
106
|
+
"artdeco": {"base": ["#546b8b", "#394f71", "#273b5b", "#1a2a43"], "eye": "#fff1cf", "rim": "#bccfe1", "shine": 0.4, "shade": 0.25, "antenna": ["#bccfe1", "#394f71", "#1a2a43"], "pattern": "artdeco"},
|
|
107
|
+
"memphis": {"base": ["#e4d6ef", "#bcabd5", "#9a88bc", "#776397"], "eye": "#4e4168", "rim": "#fff0fe", "shine": 0.18, "shade": 0.25, "antenna": ["#fff0fe", "#bcabd5", "#776397"], "matte": true, "pattern": "memphis"},
|
|
108
|
+
"chevron": {"base": ["#f3e8cd", "#e4d5b3", "#c8b48f", "#9e8e70"], "eye": "#3d5052", "rim": "#fff9e6", "shine": 0.07, "shade": 0.2, "antenna": ["#fff9e6", "#eee5d3", "#b5a58b"], "matte": true, "pattern": "second-chevron"},
|
|
109
|
+
"hexbolt": {"base": ["#dbd9d0", "#b9bbb4", "#919a97", "#6b7b7c"], "eye": "#334b52", "rim": "#f4f0de", "shine": 0.55, "shade": 0.25, "antenna": ["#f4f0de", "#b9bbb4", "#6b7b7c"], "pattern": "hexbolt"},
|
|
110
|
+
"rivet": {"base": ["#546b8b", "#394f71", "#273b5b", "#1a2a43"], "eye": "#fff1cf", "rim": "#bccfe1", "shine": 0.6, "shade": 0.25, "antenna": ["#bccfe1", "#394f71", "#1a2a43"], "pattern": "rivet"},
|
|
111
|
+
};
|