Add shape fill option to drawings
This commit is contained in:
parent
cbaf23cd09
commit
27bcc127bc
@ -7,6 +7,7 @@ import RadioIconButton from "../RadioIconButton";
|
||||
import ColorControl from "./shared/ColorControl";
|
||||
import AlphaBlendToggle from "./shared/AlphaBlendToggle";
|
||||
import ToolSection from "./shared/ToolSection";
|
||||
import ShapeFillToggle from "./shared/ShapeFillToggle";
|
||||
|
||||
import BrushIcon from "../../icons/BrushToolIcon";
|
||||
import BrushPaintIcon from "../../icons/BrushPaintIcon";
|
||||
@ -59,6 +60,8 @@ function DrawingToolSettings({
|
||||
onSettingChange({ type: "erase" });
|
||||
} else if (shortcuts.drawBlend(event)) {
|
||||
onSettingChange({ useBlending: !settings.useBlending });
|
||||
} else if (shortcuts.drawFill(event)) {
|
||||
onSettingChange({ useShapeFill: !settings.useShapeFill });
|
||||
}
|
||||
}
|
||||
useKeyboard(handleKeyDown);
|
||||
@ -148,6 +151,10 @@ function DrawingToolSettings({
|
||||
useBlending={settings.useBlending}
|
||||
onBlendingChange={(useBlending) => onSettingChange({ useBlending })}
|
||||
/>
|
||||
<ShapeFillToggle
|
||||
useShapeFill={settings.useShapeFill}
|
||||
onShapeFillChange={(useShapeFill) => onSettingChange({ useShapeFill })}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
28
src/components/controls/shared/ShapeFillToggle.tsx
Normal file
28
src/components/controls/shared/ShapeFillToggle.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import { IconButton } from "theme-ui";
|
||||
|
||||
import ShapeFillOnIcon from "../../../icons/ShapeFillOnIcon";
|
||||
import ShapeFillOffIcon from "../../../icons/ShapeFillOffIcon";
|
||||
|
||||
type ShapeFillToggleProps = {
|
||||
useShapeFill: boolean;
|
||||
onShapeFillChange: (useShapeFill: boolean) => void;
|
||||
};
|
||||
|
||||
function ShapeFillToggle({
|
||||
useShapeFill,
|
||||
onShapeFillChange,
|
||||
}: ShapeFillToggleProps) {
|
||||
return (
|
||||
<IconButton
|
||||
aria-label={
|
||||
useShapeFill ? "Disable Shape Fill (G)" : "Enable Shape Fill (G)"
|
||||
}
|
||||
title={useShapeFill ? "Disable Shape Fill (G)" : "Enable Shape Fill (G)"}
|
||||
onClick={() => onShapeFillChange(!useShapeFill)}
|
||||
>
|
||||
{useShapeFill ? <ShapeFillOnIcon /> : <ShapeFillOffIcon />}
|
||||
</IconButton>
|
||||
);
|
||||
}
|
||||
|
||||
export default ShapeFillToggle;
|
@ -21,6 +21,7 @@ function Drawing({ drawing, ...props }: DrawingProps) {
|
||||
|
||||
const defaultProps = {
|
||||
fill: colors[drawing.color] || drawing.color,
|
||||
stroke: colors[drawing.color] || drawing.color,
|
||||
opacity: drawing.blend ? 0.5 : 1,
|
||||
id: drawing.id,
|
||||
};
|
||||
@ -29,7 +30,6 @@ function Drawing({ drawing, ...props }: DrawingProps) {
|
||||
return (
|
||||
<Line
|
||||
points={scaleAndFlattenPoints(drawing.data.points, mapSize)}
|
||||
stroke={colors[drawing.color] || drawing.color}
|
||||
tension={0.5}
|
||||
closed={drawing.pathType === "fill"}
|
||||
fillEnabled={drawing.pathType === "fill"}
|
||||
@ -47,6 +47,7 @@ function Drawing({ drawing, ...props }: DrawingProps) {
|
||||
y={drawing.data.y * mapHeight}
|
||||
width={drawing.data.width * mapWidth}
|
||||
height={drawing.data.height * mapHeight}
|
||||
fillEnabled={props.strokeWidth === 0}
|
||||
{...defaultProps}
|
||||
{...props}
|
||||
/>
|
||||
@ -58,6 +59,7 @@ function Drawing({ drawing, ...props }: DrawingProps) {
|
||||
x={drawing.data.x * mapWidth}
|
||||
y={drawing.data.y * mapHeight}
|
||||
radius={drawing.data.radius * minSide}
|
||||
fillEnabled={props.strokeWidth === 0}
|
||||
{...defaultProps}
|
||||
{...props}
|
||||
/>
|
||||
@ -67,6 +69,7 @@ function Drawing({ drawing, ...props }: DrawingProps) {
|
||||
<Line
|
||||
points={scaleAndFlattenPoints(drawing.data.points, mapSize)}
|
||||
closed={true}
|
||||
fillEnabled={props.strokeWidth === 0}
|
||||
{...defaultProps}
|
||||
{...props}
|
||||
/>
|
||||
@ -75,7 +78,6 @@ function Drawing({ drawing, ...props }: DrawingProps) {
|
||||
return (
|
||||
<Line
|
||||
points={scaleAndFlattenPoints(drawing.data.points, mapSize)}
|
||||
stroke={colors[drawing.color] || drawing.color}
|
||||
lineCap="round"
|
||||
{...defaultProps}
|
||||
{...props}
|
||||
|
@ -127,7 +127,8 @@ function DrawingTool({
|
||||
type: "shape",
|
||||
shapeType: type,
|
||||
data: getDefaultShapeData(type, brushPosition),
|
||||
strokeWidth: toolSettings.type === "line" ? 1 : 0,
|
||||
strokeWidth:
|
||||
toolSettings.type === "line" || !toolSettings.useShapeFill ? 1 : 0,
|
||||
...commonShapeData,
|
||||
} as Shape);
|
||||
}
|
||||
@ -237,11 +238,7 @@ function DrawingTool({
|
||||
onTouchStart={() => handleShapeOver(shape, true)}
|
||||
onMouseUp={eraseHoveredShapes}
|
||||
onTouchEnd={eraseHoveredShapes}
|
||||
strokeWidth={
|
||||
shape.type === "path" || shape.shapeType === "line"
|
||||
? gridStrokeWidth * shape.strokeWidth
|
||||
: 0
|
||||
}
|
||||
strokeWidth={gridStrokeWidth * shape.strokeWidth}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
16
src/icons/ShapeFillOffIcon.tsx
Normal file
16
src/icons/ShapeFillOffIcon.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
function ShapeFillOffIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
>
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path d="M3.414 6.52L16.85 19.953a1 1 0 01-1.414 1.415l-2.644-2.644-1.783 1.783a1.688 1.688 0 01-1.025.484l-.16.008c-.371 0-.751-.128-1.058-.378l-.126-.114-6.147-6.147a1.664 1.664 0 01-.11-2.249l.11-.12 1.782-1.784L2 7.934a1 1 0 111.414-1.415zM7.85 2.695l.097.086 9.21 9.21c.62.62.656 1.597.109 2.25l-.11.12-1.769 1.768-2.954-2.954h2.745L9.824 7.823 8.45 9.195 6.87 7.613l1.379-1.377L6.37 4.358a1.113 1.113 0 010-1.576 1.113 1.113 0 011.479-.086zm-.607 10.48L5.856 11.79 4.47 13.176h2.772zM19.882 21a2.242 2.242 0 002.236-2.235c0-1.487-2.236-3.912-2.236-3.912s-2.235 2.425-2.235 3.912A2.242 2.242 0 0019.882 21z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default ShapeFillOffIcon;
|
16
src/icons/ShapeFillOnIcon.tsx
Normal file
16
src/icons/ShapeFillOnIcon.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
function ShapeFillOnIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
>
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path d="M8.639 20.508c.324.324.76.492 1.185.492.424 0 .86-.168 1.184-.492l6.147-6.147c.66-.648.66-1.71 0-2.37l-9.21-9.209a1.113 1.113 0 00-1.575 0 1.113 1.113 0 000 1.576l1.878 1.878-5.756 5.756c-.66.66-.66 1.72 0 2.37l6.147 6.146zM9.824 7.823l5.353 5.353H4.47l5.354-5.353zM19.882 21a2.242 2.242 0 002.236-2.235c0-1.487-2.236-3.912-2.236-3.912s-2.235 2.425-2.235 3.912A2.242 2.242 0 0019.882 21z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default ShapeFillOnIcon;
|
@ -69,6 +69,14 @@ function loadVersions(settings: Settings) {
|
||||
...prev,
|
||||
select: { type: "rectangle" },
|
||||
}));
|
||||
// v1.10.0 - Add use shape fill setting
|
||||
settings.version(9, (prev: any) => ({
|
||||
...prev,
|
||||
drawing: {
|
||||
...prev.drawing,
|
||||
useShapeFill: true,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
export function getSettings() {
|
||||
|
@ -74,6 +74,7 @@ const shortcuts: Record<string, Shortcut> = {
|
||||
drawTriangle: (event) => singleKey(event, "t"),
|
||||
drawErase: (event) => singleKey(event, "e"),
|
||||
drawBlend: (event) => singleKey(event, "o"),
|
||||
drawFill: (event) => singleKey(event, "g"),
|
||||
// Fog tool
|
||||
fogPolygon: (event) => singleKey(event, "p"),
|
||||
fogRectangle: (event) => singleKey(event, "r"),
|
||||
|
@ -14,6 +14,7 @@ export type DrawingToolSettings = {
|
||||
type: DrawingToolType;
|
||||
color: Color;
|
||||
useBlending: boolean;
|
||||
useShapeFill: boolean;
|
||||
};
|
||||
|
||||
export type PointsData = {
|
||||
|
Loading…
Reference in New Issue
Block a user