You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
hexmap/client/src/ui/HexColorPicker.tsx

66 lines
2.8 KiB

import {CustomPicker, InjectedColorProps} from "react-color";
import {ReactElement, useMemo} from "react";
import {
renderCoordinatesToPolygonPoints,
RenderOffsets,
storageCoordinatesToRenderCoordinates
} from "../../../common/src/state/Coordinates";
import {HexagonOrientation, LineParity} from "../../../common/src/state/HexMap";
import {normalizeColor} from "../../../common/src/util/ColorUtils";
function HexSwatch({color, index, offsets, classNames, onClick}: {color: string, index: number, offsets: RenderOffsets, classNames?: readonly string[], onClick: () => void}): ReactElement {
const renderCoordinates = useMemo(() => storageCoordinatesToRenderCoordinates({line: index, cell: 0}, offsets), [index, offsets]);
const points = useMemo(() => renderCoordinatesToPolygonPoints(renderCoordinates), [renderCoordinates]);
return <polygon
className={classNames !== undefined ? `hexagon swatch ${classNames.join(" ")}` : "hexagon swatch"}
fill={color}
points={points}
onClick={onClick}
onContextMenu={(e) => e.preventDefault()}/>
}
const ACTIVE_OFFSETS: RenderOffsets = {
layout: {
orientation: HexagonOrientation.POINTY_TOP,
indentedLines: LineParity.ODD
},
top: 13,
left: 13,
size: 50,
}
const SWATCH_OFFSETS: RenderOffsets = {
layout: {
orientation: HexagonOrientation.FLAT_TOP,
indentedLines: LineParity.EVEN
},
top: 34,
left: 110,
size: 30,
}
const COLORS: readonly string[] = [
"#000000FF", "#555555FF",
"#800000FF", "#FF0000FF",
"#008000FF", "#00FF00FF",
"#808000FF", "#FFFF00FF",
"#000080FF", "#0000FFFF",
"#800080FF", "#FF00FFFF",
"#008080FF", "#00FFFFFF",
"#AAAAAAFF", "#FFFFFFFF",
]
function HexColorPicker({ hex, onChange }: InjectedColorProps): ReactElement {
const selected = COLORS.indexOf(normalizeColor(hex || "#INVALID"))
const swatches = COLORS.map((color, index) =>
index === selected ? null : <HexSwatch key={index} classNames={["preset"]} color={color} index={index} offsets={SWATCH_OFFSETS} onClick={() => onChange !== undefined ? onChange(color) : null} />
)
return <svg viewBox={"0 0 855 126"} width={"855"} height={"126"} className={"hexColorPicker"}>
<rect className={"colorPickerBackground"} x={0} y={0} width={855} height={126} rx={15} />
<HexSwatch classNames={["active"]} color={hex || "#000000FF"} index={0} offsets={ACTIVE_OFFSETS} onClick={() => null} />
{swatches}
{selected !== -1 ? <HexSwatch key={selected} classNames={["preset", "selected"]} color={COLORS[selected]} index={selected} offsets={SWATCH_OFFSETS} onClick={() => onChange !== undefined ? onChange(COLORS[selected]) : null} /> : null}
</svg>
}
export default CustomPicker(HexColorPicker);