Skip to content

Commit 96e14ba

Browse files
committed
add gradient and stroke feature
1 parent 1d26e85 commit 96e14ba

19 files changed

+306
-44
lines changed

config/template.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
<meta name="msapplication-config" content="/favicons/browserconfig.xml" />
9292
<meta name="theme-color" content="#ffffff" />
9393
<link
94-
href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;800&display=swap"
94+
href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;800&display=swap"
9595
rel="stylesheet"
9696
/>
9797
</head>

config/webpack.dev.config.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
const webpackBaseConfig = require('./webpack.base.config');
2-
const paths = require('./paths');
1+
const webpackBaseConfig = require("./webpack.base.config");
2+
const paths = require("./paths");
33

44
module.exports = {
5-
mode: 'development',
6-
devtool: 'eval-source-map',
7-
...webpackBaseConfig({ plugins: [] }),
8-
devServer: {
9-
contentBase: paths.output,
10-
port: 9000,
11-
hot: true,
12-
}
5+
mode: "development",
6+
devtool: "eval-source-map",
7+
...webpackBaseConfig({ plugins: [] }),
8+
devServer: {
9+
contentBase: paths.output,
10+
port: 9000,
11+
host: "0.0.0.0",
12+
hot: true,
13+
},
1314
};

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "blobs.app",
3-
"version": "1.0.0",
4-
"description": "Generate blob shapes for Web and Fluttter",
3+
"version": "1.1.0",
4+
"description": "Generate blob shapes for Web and Flutter",
55
"main": "index.js",
66
"scripts": {
77
"build": "rm -rf build && NODE_ENV=production npm run build:css && webpack ---config ./config/webpack.prod.config.js",
@@ -23,12 +23,10 @@
2323
"@babel/preset-env": "^7.9.0",
2424
"@babel/preset-react": "^7.9.4",
2525
"@risingstack/react-easy-state": "^6.3.0",
26-
"animejs": "^3.2.0",
2726
"antd": "^4.2.4",
2827
"autoprefixer": "^9.7.6",
2928
"babel-loader": "^8.1.0",
3029
"dynamics.js": "^1.1.5",
31-
"kute.js": "^1.6.6",
3230
"postcss-cli": "^7.1.0",
3331
"prop-types": "^15.7.2",
3432
"react": "^16.13.1",

src/app.scss

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
html body {
2+
line-height: 25px;
3+
font-family: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
4+
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
5+
button {
6+
line-height: 25px;
7+
}
28
.brand-bg {
39
margin-top: -16px;
410
transform: translate(-50%, 0);
@@ -9,6 +15,25 @@ html body {
915
max-width: 500px;
1016
}
1117

18+
.stroke {
19+
border: 4px solid #d1d8e0;
20+
&.stroke-fill {
21+
position: relative;
22+
display: flex;
23+
align-items: center;
24+
justify-content: center;
25+
&:after {
26+
content: "";
27+
28+
width: 100%;
29+
height: 100%;
30+
transform: scale(0.7);
31+
border-radius: 100%;
32+
background-color: #4a5568;
33+
}
34+
}
35+
}
36+
1237
.ant-slider-step {
1338
background: rgb(209, 216, 224);
1439
}
@@ -45,7 +70,39 @@ html body {
4570

4671
.ant-popover-inner {
4772
max-width: 300px;
48-
border-radius: 4px;
73+
border-radius: 10px;
74+
}
75+
76+
.ant-popover-arrow {
77+
display: none;
78+
}
79+
80+
.ant-popover-inner-content {
81+
padding: 25px;
82+
background: rgba(207, 214, 222, 0.15);
83+
}
84+
85+
input.ant-input {
86+
border-radius: 6px;
87+
padding: 9px;
88+
font-weight: bold;
89+
color: #828b99;
90+
border-color: #cfd8df;
91+
border-width: 2px;
92+
}
93+
94+
.ant-input:hover {
95+
border-color: #4e566b;
96+
border-right-width: 2px !important;
97+
}
98+
99+
.ant-input:focus,
100+
.ant-input-focused {
101+
border-color: #4c5468;
102+
border-right-width: 2px !important;
103+
outline: 0;
104+
-webkit-box-shadow: 0 0 0 2px rgba(78, 86, 107, 0.34);
105+
box-shadow: 0 0 0 2px rgba(78, 86, 107, 0.34);
49106
}
50107

51108
pre {

src/assets/css/main.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6431,7 +6431,7 @@ video {
64316431
clear: none;
64326432
}
64336433

6434-
.font-manrope {
6434+
.font-body {
64356435
font-family: Manrope;
64366436
}
64376437

@@ -26377,7 +26377,7 @@ video {
2637726377
clear: none;
2637826378
}
2637926379

26380-
.sm\:font-manrope {
26380+
.sm\:font-body {
2638126381
font-family: Manrope;
2638226382
}
2638326383

@@ -46322,7 +46322,7 @@ video {
4632246322
clear: none;
4632346323
}
4632446324

46325-
.md\:font-manrope {
46325+
.md\:font-body {
4632646326
font-family: Manrope;
4632746327
}
4632846328

@@ -66267,7 +66267,7 @@ video {
6626766267
clear: none;
6626866268
}
6626966269

66270-
.lg\:font-manrope {
66270+
.lg\:font-body {
6627166271
font-family: Manrope;
6627266272
}
6627366273

@@ -86212,7 +86212,7 @@ video {
8621286212
clear: none;
8621386213
}
8621486214

86215-
.xl\:font-manrope {
86215+
.xl\:font-body {
8621686216
font-family: Manrope;
8621786217
}
8621886218

src/components/actions/svgCopy.jsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@ import Modal from "../common/modal";
66
import Highlight from "../common/highlight";
77
import Copy from "../common/copy";
88
import Download from "../common/download";
9+
import formatter from "../../services/formatter";
910

1011
const SVGCopy = view(({ onClose }) => {
1112
const [isModalOpen, openModal] = useState(false);
1213
const ID = `${appStore.edges}-${appStore.growth}-${appStore.id}`;
13-
const code = `
14-
<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
15-
<path d="${appStore.path}"></path>
16-
</svg>
17-
`;
14+
const svgEl = document.getElementById("blobSvg");
15+
const code = svgEl ? formatter(svgEl.outerHTML) : "";
1816
return (
1917
<>
2018
<Button

src/components/blob.jsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,36 @@ import { appStore } from "../store";
44

55
const Blob = view(() => {
66
const size = appStore.size;
7+
let props = {
8+
fill: appStore.color,
9+
};
10+
if (appStore.type == "gradient") {
11+
props.fill = "url(#gradient)";
12+
}
13+
if (appStore.stroke) {
14+
props.strokeWidth = "7px";
15+
props.fill = "none";
16+
props.stroke = appStore.color;
17+
}
18+
if (appStore.type == "gradient" && appStore.stroke) {
19+
props.stroke = "url(#gradient)";
20+
}
721
return (
822
<svg
923
viewBox={`0 0 ${size} ${size}`}
1024
xmlns="http://www.w3.org/2000/svg"
1125
width={`100%`}
1226
id="blobSvg"
1327
>
14-
<path id="blob" d={appStore.path} fill={appStore.color} />
28+
{appStore.type == "gradient" && (
29+
<defs>
30+
<linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%">
31+
<stop offset="0%" style={{ stopColor: appStore.gradient[0] }} />
32+
<stop offset="100%" style={{ stopColor: appStore.gradient[1] }} />
33+
</linearGradient>
34+
</defs>
35+
)}
36+
<path id="blob" d={appStore.path} {...props} />
1537
</svg>
1638
);
1739
});

src/components/common/button.jsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ export default function Button({
1010
}) {
1111
let classNames = "";
1212
if (isPrimary) {
13-
classNames =
14-
"shadow-lg bg-theme-400 text-white hover:bg-theme-900 transition duration-200 ease-in-out transform active:shadow-2xl active:translate-y-1";
13+
classNames = "shadow-lg bg-theme-400 text-white hover:bg-theme-900";
1514
} else {
1615
classNames = "text-theme-600";
1716
}

src/components/common/settingsItem.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ export default function SettingsItem({ label, children, info }) {
66
<div className="block w-full py-6">
77
<div className="flex justify-between">
88
<h3>{label}</h3>
9-
<Popover content={info} title={null} trigger="click">
10-
<i className="ri-question-line text-gray-500 cursor-pointer"></i>
11-
</Popover>
9+
{info && (
10+
<Popover content={info} title={null} trigger="click">
11+
<i className="ri-question-line text-gray-500 cursor-pointer"></i>
12+
</Popover>
13+
)}
1214
</div>
1315
{children}
1416
</div>

src/components/layout/grid.jsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ import Settings from "../settings/settings";
77

88
export default function Grid() {
99
return (
10-
<div className="app">
10+
<div className="app font-body">
1111
<div className="flex flex-col w-full max-w-screen-xl mx-auto px-6 min-h-screen">
1212
<div className="md:flex flex-1">
1313
<div className="md:w-9/12 flex flex-col items-center justify-center">
1414
<div className="flex flex-1 w-full justify-center flex-col">
1515
<div className="flex flex-col items-center">
16+
<div className="block md:hidden">
17+
<Header />
18+
</div>
1619
<Blob />
1720
<div className="py-10">
1821
<ActionBar />
@@ -22,7 +25,9 @@ export default function Grid() {
2225
</div>
2326
<div className="md:w-3/12 flex items-center">
2427
<div className="flex-1">
25-
<Header />
28+
<div className="hidden md:block">
29+
<Header />
30+
</div>
2631
<Settings />
2732
</div>
2833
</div>

src/components/layout/header.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default function Header() {
66
<nav className="flex items-center justify-center flex-wrap p-6 my-4">
77
<div className="flex flex-col items-center flex-shrink-0 mr-6 leading-none">
88
<img src={Logo} width="50" />
9-
<h1 className="my-4 font-extrabold text-2xl tracking-tight text-gray-700 font-manrope">
9+
<h1 className="my-4 font-extrabold text-2xl tracking-tight text-gray-700">
1010
Blob generator
1111
</h1>
1212
</div>

src/components/settings/colorPicker.jsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,30 @@ import React, { useState } from "react";
22
import { Popover, Divider, Input } from "antd";
33
import { view } from "@risingstack/react-easy-state";
44
import { appStore } from "../../store";
5+
import hexValidator from "../../services/hex-validator";
56

67
const ColorPicker = view(() => {
78
const [val, setVal] = useState(appStore.color);
8-
const colors = ["#00cec9", "#fab1a0", "#fdcb6e", "#fd79a8", "#a29bfe"];
9+
const colors = [
10+
"#00cec9",
11+
"#fab1a0",
12+
"#fdcb6e",
13+
"#fd79a8",
14+
"#a29bfe",
15+
"#B53471",
16+
];
917
const content = () => {
1018
return (
1119
<div className="flex flex-col">
12-
<div className="flex justify-between">
20+
<div className="flex justify-center">
1321
{colors.map((color, i) => {
1422
return (
1523
<div
1624
className="w-6 h-6 rounded-full mx-1 cursor-pointer"
1725
style={{ backgroundColor: color }}
1826
onClick={() => {
1927
setVal(color);
28+
appStore.type = "color";
2029
appStore.color = color;
2130
}}
2231
></div>
@@ -32,18 +41,27 @@ const ColorPicker = view(() => {
3241
setVal(e.target.value);
3342
}}
3443
onPressEnter={(e) => {
44+
if (!hexValidator(e.target.value)) return;
3545
setVal(e.target.value);
46+
appStore.type = "color";
3647
appStore.color = e.target.value;
3748
}}
3849
/>
3950
</div>
4051
);
4152
};
53+
54+
const getBgCss = () => {
55+
if (appStore.type == "color") {
56+
return { backgroundColor: appStore.color };
57+
}
58+
return { backgroundColor: "#d1d8e0" };
59+
};
4260
return (
4361
<Popover content={content} trigger="click">
4462
<div
45-
className="w-6 h-6 rounded-full cursor-pointer"
46-
style={{ backgroundColor: appStore.color }}
63+
className="w-8 h-8 rounded-full cursor-pointer"
64+
style={getBgCss()}
4765
></div>
4866
</Popover>
4967
);

0 commit comments

Comments
 (0)