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.
66 lines
2.8 KiB
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); |