Skip to content

Commit 8ae89f2

Browse files
committed
feat: new demo
1 parent 7d9fad5 commit 8ae89f2

File tree

27 files changed

+1734
-664
lines changed

27 files changed

+1734
-664
lines changed

.npmignore

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ CHANGELOG.md
1111
src/
1212
demo/
1313
test/
14+
Makefile
15+
README.md
16+
rollup.config.js
17+
jest.config.js
18+
tsconfig.json
19+
.github/
20+
webpack/
21+
tailwind.config.js
1422

1523
// setting files
1624
.babelrc
1725
.travis.yml
18-
.eslintrc
26+
.eslintrc.js
1927
.eslintignore
2028
.travis.yml
2129
.versionrc.json
22-
23-
Makefile
24-
README.md
25-
rollup.config.js
26-
jest.config.js
27-
tsconfig.json
28-
.github/
29-
webpack/

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ The options can be passed into genConfig or as React props
8080
| `shirtStyle` | string | | hoody, short, polo | |
8181
| `shirtColor` | string | | | |
8282
| `bgColor` | string | | | |
83+
| `isGradient` | boolean | false | | |
8384

8485
## Development
8586

demo/app.template.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111
content="A fun, vibrant, and inclusive avatars library for React!"
1212
/>
1313
<meta property="og:type" content="website" />
14-
<meta property="og:url" content="https://nice-avatar.chilllab.io/" />
14+
<meta property="og:url" content="https://nice-avatar.dapiok.io/" />
1515
<meta property="og:title" content="react-nice-avatar" />
1616
<meta
1717
property="og:description"
1818
content="A fun, vibrant, and inclusive avatars library for React!"
1919
/>
2020
<meta property="og:image" content="/static/react-nice-avatar.png" />
2121
<meta property="twitter:card" content="summary_large_image" />
22-
<meta property="twitter:url" content="https://nice-avatar.chilllab.io/" />
22+
<meta property="twitter:url" content="https://nice-avatar.dapiok.io/" />
2323
<meta property="twitter:title" content="react-nice-avatar" />
2424
<meta
2525
property="twitter:description"
767 KB
Binary file not shown.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
@keyframes jelly {
2+
0%,
3+
100% {
4+
transform: scale(1, 1);
5+
}
6+
25% {
7+
transform: scale(0.9, 1.1);
8+
}
9+
50% {
10+
transform: scale(1.1, 0.9);
11+
}
12+
75% {
13+
transform: scale(0.95, 1.05);
14+
}
15+
}
16+
17+
.SectionWrapper {
18+
cursor: pointer;
19+
background: rgba(255, 255, 255, 0.15);
20+
display: flex;
21+
align-items: center;
22+
justify-content: center;
23+
position: relative;
24+
&:hover {
25+
animation: jelly 0.5s;
26+
&:after {
27+
opacity: 1;
28+
transform: translateY(0px);
29+
}
30+
}
31+
&:after {
32+
content: attr(data-tip);
33+
position: absolute;
34+
bottom: 120%;
35+
border-radius: 5px;
36+
font-size: 0.75rem;
37+
color: #fff;
38+
background: rgba(255, 255, 255, 0.15);
39+
padding: 0.15rem 0.75rem;
40+
opacity: 0;
41+
transform: translateY(10px);
42+
transition: all 0.2s ease-out;
43+
}
44+
45+
.childrenWrapper > svg {
46+
top: auto !important;
47+
right: auto !important;
48+
bottom: auto !important;
49+
left: auto !important;
50+
width: 100% !important;
51+
height: 100% !important;
52+
}
53+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react'
2+
3+
import './index.scss'
4+
5+
export default function (props) {
6+
const { className = "", children, switchConfig, tip } = props
7+
return (
8+
<div
9+
className={"SectionWrapper " + className}
10+
data-tip={tip}
11+
onClick={switchConfig}>
12+
<div className="relative w-full h-full">
13+
<div className="childrenWrapper absolute top-0 left-0 w-full h-full flex items-center justify-center">
14+
{children}
15+
</div>
16+
</div>
17+
</div>
18+
)
19+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@keyframes jelly {
2+
0%,
3+
100% {
4+
transform: scale(1, 1);
5+
}
6+
25% {
7+
transform: scale(0.9, 1.1);
8+
}
9+
50% {
10+
transform: scale(1.1, 0.9);
11+
}
12+
75% {
13+
transform: scale(0.95, 1.05);
14+
}
15+
}
16+
17+
.AvatarEditor {
18+
background: rgba(255, 255, 255, 0.1);
19+
20+
.divider {
21+
background: rgba(255, 255, 255, 0.15);
22+
}
23+
24+
.iconfont {
25+
display: flex;
26+
justify-content: center;
27+
position: relative;
28+
&:hover {
29+
animation: jelly 0.5s;
30+
&:not(.banTip):after {
31+
opacity: 1;
32+
transform: translateY(0px);
33+
}
34+
}
35+
&:after {
36+
content: attr(data-tip);
37+
position: absolute;
38+
bottom: 120%;
39+
border-radius: 5px;
40+
font-size: 0.75rem;
41+
color: #fff;
42+
background: rgba(255, 255, 255, 0.15);
43+
padding: 0.15rem 0.75rem;
44+
opacity: 0;
45+
transform: translateY(10px);
46+
transition: all 0.2s ease-out;
47+
}
48+
}
49+
50+
.codeBlock {
51+
background: #222;
52+
color: #eeebff;
53+
opacity: 0;
54+
transform: translateY(10px);
55+
transition: all 0.2s ease-out;
56+
&.active {
57+
opacity: 1;
58+
transform: translateY(0);
59+
}
60+
}
61+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import React, { Component } from 'react'
2+
import PropTypes from 'prop-types'
3+
import classnames from 'classnames'
4+
5+
import { defaultOptions } from "react-nice-avatar/utils"
6+
import Face from "react-nice-avatar/face/index"
7+
import Hair from "react-nice-avatar/hair/index"
8+
import Hat from "react-nice-avatar/hat/index"
9+
import Eyes from "react-nice-avatar/eyes/index"
10+
import Glasses from "react-nice-avatar/glasses/index"
11+
import Ear from "react-nice-avatar/ear/index"
12+
import Nose from "react-nice-avatar/nose/index"
13+
import Mouth from "react-nice-avatar/mouth/index"
14+
import Shirt from "react-nice-avatar/shirt/index"
15+
16+
import SectionWrapper from "./SectionWrapper/index"
17+
18+
import './index.scss'
19+
20+
export default class AvatarEditor extends Component {
21+
static propTypes = {
22+
config: PropTypes.object.isRequired,
23+
shape: PropTypes.string.isRequired,
24+
updateConfig: PropTypes.func.isRequired,
25+
updateShape: PropTypes.func.isRequired,
26+
download: PropTypes.func.isRequired
27+
}
28+
29+
constructor (props) {
30+
super(props)
31+
this.state = {
32+
isCodeShow: false
33+
}
34+
this.myDefaultOptions = this.genDefaultOptions(defaultOptions)
35+
this.shapes = ['circle', 'rounded', 'square']
36+
}
37+
38+
// Modification on defaultOptions for convenient
39+
genDefaultOptions (opts) {
40+
const hairSet = new Set(opts.hairStyleMan.concat(opts.hairStyleWoman))
41+
return {
42+
...opts,
43+
hairStyle: Array.from(hairSet)
44+
}
45+
}
46+
47+
switchConfig (type, currentOpt) {
48+
const { updateConfig } = this.props
49+
const opts = this.myDefaultOptions[type]
50+
const currentIdx = opts.findIndex(item => item === currentOpt)
51+
const newIdx = (currentIdx + 1) % opts.length
52+
updateConfig(type, opts[newIdx])
53+
}
54+
55+
switchShape (currentShape) {
56+
const { updateShape } = this.props
57+
const currentIdx = this.shapes.findIndex(item => item === currentShape)
58+
const newIdx = (currentIdx + 1) % this.shapes.length
59+
updateShape(this.shapes[newIdx])
60+
}
61+
62+
toggleCodeShow () {
63+
const { isCodeShow } = this.state
64+
this.setState({
65+
isCodeShow: !isCodeShow
66+
})
67+
}
68+
69+
genCodeString (config) {
70+
return "const config = " +
71+
JSON.stringify(config, null, 2) +
72+
"\n" +
73+
"const myConfig = genConfig(config)\n" +
74+
"<NiceAvatar style={{ width: '5rem', height: '5rem' }} {...myConfig} />"
75+
}
76+
77+
render () {
78+
const { config, shape, download } = this.props
79+
const { isCodeShow } = this.state
80+
return (
81+
<div className="AvatarEditor rounded-full p-3 flex items-center">
82+
{/* Face */}
83+
<SectionWrapper
84+
className="w-8 h-8 rounded-full p-2 mx-2"
85+
tip="Face"
86+
switchConfig={this.switchConfig.bind(this, 'faceColor', config.faceColor)}>
87+
<Face color={config.faceColor} />
88+
</SectionWrapper>
89+
{/* Hair style */}
90+
<SectionWrapper
91+
className="w-8 h-8 rounded-full p-2 mx-2"
92+
tip="Hair"
93+
switchConfig={this.switchConfig.bind(this, 'hairStyle', config.hairStyle)}>
94+
<Hair style={config.hairStyle} color="#fff" colorRandom />
95+
</SectionWrapper>
96+
{/* Hat style */}
97+
<SectionWrapper
98+
className="w-8 h-8 rounded-full p-2 mx-2"
99+
tip="Hat"
100+
switchConfig={this.switchConfig.bind(this, 'hatStyle', config.hatStyle)}>
101+
<Hat style={config.hatStyle} color="#fff" />
102+
</SectionWrapper>
103+
{/* Eyes style */}
104+
<SectionWrapper
105+
className="w-8 h-8 rounded-full p-2 mx-2"
106+
tip="Eyes"
107+
switchConfig={this.switchConfig.bind(this, 'eyeStyle', config.eyeStyle)}>
108+
<Eyes style={config.eyeStyle} color="#fff" />
109+
</SectionWrapper>
110+
{/* Glasses style */}
111+
<SectionWrapper
112+
className="w-8 h-8 rounded-full p-2 mx-2"
113+
tip="Glasses"
114+
switchConfig={this.switchConfig.bind(this, 'glassesStyle', config.glassesStyle)}>
115+
<Glasses style={config.glassesStyle} color="#fff" />
116+
</SectionWrapper>
117+
{/* Ear style */}
118+
<SectionWrapper
119+
className="w-8 h-8 rounded-full p-2 mx-2"
120+
tip="Ear"
121+
switchConfig={this.switchConfig.bind(this, 'earSize', config.earSize)}>
122+
<Ear size={config.earSize} color="#fff" />
123+
</SectionWrapper>
124+
{/* Nose style */}
125+
<SectionWrapper
126+
className="w-8 h-8 rounded-full p-2 mx-2"
127+
tip="Nose"
128+
switchConfig={this.switchConfig.bind(this, 'noseStyle', config.noseStyle)}>
129+
<Nose style={config.noseStyle} color="#fff" />
130+
</SectionWrapper>
131+
{/* Mouth style */}
132+
<SectionWrapper
133+
className="w-8 h-8 rounded-full p-2 mx-2"
134+
tip="Mouth"
135+
switchConfig={this.switchConfig.bind(this, 'mouthStyle', config.mouthStyle)}>
136+
<Mouth style={config.mouthStyle} color="#fff" />
137+
</SectionWrapper>
138+
{/* Shirt style */}
139+
<SectionWrapper
140+
className="w-8 h-8 rounded-full p-2 mx-2"
141+
tip="Shirt"
142+
switchConfig={this.switchConfig.bind(this, 'shirtStyle', config.shirtStyle)}>
143+
<Shirt style={config.shirtStyle} color="#fff" />
144+
</SectionWrapper>
145+
146+
{/* Shape style */}
147+
<SectionWrapper
148+
className="w-8 h-8 rounded-full p-2 mx-2"
149+
tip="Shape"
150+
switchConfig={this.switchShape.bind(this, shape)}>
151+
<div
152+
className={classnames("w-3 h-3 bg-white", {
153+
"rounded-full": shape === 'circle',
154+
"rounded": shape === 'rounded'
155+
})} />
156+
</SectionWrapper>
157+
158+
<div className="divider w-0.5 h-5 rounded mx-2" />
159+
<div className="mx-2 relative flex justify-center">
160+
<i
161+
className={classnames("iconfont icon-code text-xl cursor-pointer transition duration-300 hover:text-green-100", {
162+
banTip: isCodeShow
163+
})}
164+
data-tip="Config"
165+
onClick={this.toggleCodeShow.bind(this)} />
166+
<div className={classnames("rounded-lg bg-white py-5 px-6 absolute bottom-full codeBlock mb-4", {
167+
active: isCodeShow
168+
})}>
169+
<pre className="text-sm">{this.genCodeString(config)}</pre>
170+
</div>
171+
</div>
172+
173+
<div className="divider w-0.5 h-5 rounded mx-2" />
174+
<i
175+
className="iconfont icon-download text-xl mx-2 cursor-pointer transition duration-300 hover:text-green-100"
176+
data-tip="Download"
177+
onClick={download} />
178+
</div>
179+
)
180+
}
181+
}

0 commit comments

Comments
 (0)