color selection

This commit is contained in:
Michael Peters 2024-01-27 14:30:06 -08:00
parent 0961ba41fd
commit 851e78bff3
7 changed files with 121 additions and 76 deletions

40
package-lock.json generated
View File

@ -12,7 +12,8 @@
"@uidotdev/usehooks": "^2.4.1",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"recoil": "^0.7.7"
},
"devDependencies": {
"@types/lodash": "^4.14.202",
@ -1776,6 +1777,11 @@
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
"dev": true
},
"node_modules/hamt_plus": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz",
"integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="
},
"node_modules/handle-thing": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@ -3118,6 +3124,25 @@
"node": ">= 10.13.0"
}
},
"node_modules/recoil": {
"version": "0.7.7",
"resolved": "https://registry.npmjs.org/recoil/-/recoil-0.7.7.tgz",
"integrity": "sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==",
"dependencies": {
"hamt_plus": "1.0.2"
},
"peerDependencies": {
"react": ">=16.13.1"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
@ -5749,6 +5774,11 @@
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
"dev": true
},
"hamt_plus": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz",
"integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="
},
"handle-thing": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@ -6729,6 +6759,14 @@
"resolve": "^1.20.0"
}
},
"recoil": {
"version": "0.7.7",
"resolved": "https://registry.npmjs.org/recoil/-/recoil-0.7.7.tgz",
"integrity": "sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==",
"requires": {
"hamt_plus": "1.0.2"
}
},
"relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",

View File

@ -31,6 +31,7 @@
"@uidotdev/usehooks": "^2.4.1",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"recoil": "^0.7.7"
}
}

8
src/atoms.ts Normal file
View File

@ -0,0 +1,8 @@
import { atom } from 'recoil';
export const DEFAULT_COLOR = '#339ad6';
export const currentColorState = atom({
key: 'colorState',
default: DEFAULT_COLOR,
});

View File

@ -1,14 +1,14 @@
import { FC, useState } from 'react';
import { FC } from 'react';
import { RecoilRoot } from 'recoil';
import Grid from '../grid/grid';
import GridConfig from '../grid/grid-config';
const App: FC = () => {
const [color, setColor] = useState('#ffffff');
return (
<>
<RecoilRoot>
<Grid />
<GridConfig color={color} setColor={setColor} />
</>
<GridConfig />
</RecoilRoot>
);
};

View File

@ -2,5 +2,38 @@
position: absolute;
top: 0;
left: 0;
display: flex;
> * {
margin: 20px;
}
.color-config {
background-color: #000;
border-radius: 5px;
padding: 5px;
.color-options {
display: grid;
grid-template-columns: auto auto;
.color-option {
margin: 5px;
padding: 7px;
background-color: #283f56;
border: 2px solid #283f56;
border-radius: 5px;
&.active {
background-color: #265584;
border-color: #458bd1;
}
.sample {
width: 24px;
height: 13px;
border-radius: 3px;
}
}
}
}
}

View File

@ -1,16 +1,16 @@
import { FC } from 'react';
import { useRecoilState } from 'recoil';
import { currentColorState, DEFAULT_COLOR } from '../../atoms';
import './grid-config.scss';
interface ColorOptionProps {
color: string;
currentColor: string;
setCurrentColor: (newColor: string) => void;
}
const ColorOption: FC<ColorOptionProps> = (props: ColorOptionProps) => {
const { color, currentColor, setCurrentColor } = props;
const { color } = props;
const [currentColor, setCurrentColor] = useRecoilState(currentColorState);
return (
<div
@ -19,77 +19,32 @@ const ColorOption: FC<ColorOptionProps> = (props: ColorOptionProps) => {
}
onClick={() => setCurrentColor(color)}
>
{color}
<div className="sample" style={{ backgroundColor: color }} />
</div>
);
};
interface ColorConfigProps {
color: string;
setColor: (newColor: string) => void;
}
const ColorConfig: FC<ColorConfigProps> = (props: ColorConfigProps) => {
const { color, setColor } = props;
const ColorConfig: FC = () => {
return (
<div className="color-config">
<div>Color: {color}</div>
<div className="color-options">
<ColorOption
color="#ffffff"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption
color="#ff0000"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption
color="#00ff00"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption
color="#3cccff"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption
color="#eeee00"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption
color="#ff8800"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption
color="#ee66ee"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption
color="#2e8c41"
currentColor={color}
setCurrentColor={setColor}
/>
<ColorOption color={DEFAULT_COLOR} />
<ColorOption color="#d33b3d" />
<ColorOption color="#3dd33b" />
<ColorOption color="#f1c40f" />
<ColorOption color="#d35400" />
<ColorOption color="#8e44ad" />
<ColorOption color="#eeeeee" />
<ColorOption color="#95a5a6" />
</div>
</div>
);
};
interface GridConfigProps {
color: string;
setColor: (newColor: string) => void;
}
const GridConfig: FC<GridConfigProps> = (props: GridConfigProps) => {
const { color, setColor } = props;
const GridConfig: FC = () => {
return (
<div className="grid-config">
<ColorConfig color={color} setColor={setColor} />
<ColorConfig />
</div>
);
};

View File

@ -12,6 +12,8 @@ import {
import './grid.scss';
import * as lodash from 'lodash';
import { useRecoilValue } from 'recoil';
import { currentColorState } from '../../atoms';
interface Point {
x: number;
@ -122,9 +124,10 @@ const Grid: FC = () => {
return lines_thin.concat(lines_thick);
}, [range, GAP]);
const [userLines, setUserLines] = useState<Range[]>([]);
const [userRedoLines, setUserRedoLines] = useState<Range[]>([]);
const [userLines, setUserLines] = useState<Line[]>([]);
const [userRedoLines, setUserRedoLines] = useState<Line[]>([]);
const [userStartPoint, setUserStartPoint] = useState<Point | null>(null);
const userLineColor = useRecoilValue(currentColorState);
// mouse clicks create lines
const onGridClick = useCallback(
@ -146,7 +149,7 @@ const Grid: FC = () => {
}
const line = pointsToRange(userStartPoint, point);
setUserLines([...userLines, line]);
setUserLines([...userLines, { ...line, stroke: userLineColor }]);
if (event.shiftKey == false) {
setUserStartPoint(null);
@ -154,7 +157,14 @@ const Grid: FC = () => {
setUserStartPoint(point);
}
},
[userStartPoint, setUserStartPoint, setUserLines, GAP, mousePoint]
[
userLineColor,
userStartPoint,
setUserStartPoint,
setUserLines,
GAP,
mousePoint,
]
);
const onGridContextMenu = useCallback(
@ -210,7 +220,7 @@ const Grid: FC = () => {
y1={userStartPoint.y}
x2={point.x}
y2={point.y}
stroke="#ff0000"
stroke={userLineColor}
strokeWidth="2"
/>
);
@ -223,7 +233,7 @@ const Grid: FC = () => {
cx={point.x}
cy={point.y}
r="3"
fill="#ff0000"
fill={userLineColor}
/>
);
}, [userStartPoint, mousePoint]);
@ -237,7 +247,7 @@ const Grid: FC = () => {
y1={line.y0}
x2={line.x1}
y2={line.y1}
stroke="#ff0000"
stroke={line.stroke}
strokeWidth="2"
/>
));