-
+
{circles}
diff --git a/lib/svg-composition-context.tsx b/lib/svg-composition-context.tsx
new file mode 100644
index 0000000..68d01b4
--- /dev/null
+++ b/lib/svg-composition-context.tsx
@@ -0,0 +1,60 @@
+import React from "react";
+import { ColorWidget } from "./color-widget";
+import { DEFAULT_BG_COLOR } from "./colors";
+import { createRandomColorPalette } from "./random-colors";
+import { createSvgSymbolContext, SvgSymbolContext } from "./svg-symbol";
+import {
+ SymbolContextWidget,
+ SymbolContextWidgetProps,
+} from "./symbol-context-widget";
+
+const DEFAULT_CONTEXT: SvgCompositionContext = {
+ background: DEFAULT_BG_COLOR,
+ ...createSvgSymbolContext(),
+};
+
+export type SvgCompositionContext = SvgSymbolContext & {
+ /** The background color of the composition, as a hex hash (e.g. '#ff0000'). */
+ background: string;
+};
+
+export function createSvgCompositionContext(
+ ctx: Partial
= {}
+): SvgCompositionContext {
+ return {
+ ...DEFAULT_CONTEXT,
+ ...ctx,
+ };
+}
+
+export type CompositionContextWidgetProps<
+ T extends SvgCompositionContext
+> = SymbolContextWidgetProps;
+
+export function CompositionContextWidget({
+ ctx,
+ onChange,
+ children,
+}: CompositionContextWidgetProps): JSX.Element {
+ const randomizeColors = () => {
+ const [background, stroke, fill] = createRandomColorPalette(3);
+ onChange({ ...ctx, background, stroke, fill });
+ };
+
+ const extra = (
+
+ );
+
+ return (
+
+ {children}
+ onChange({ ...ctx, background })}
+ />{" "}
+
+ );
+}
diff --git a/lib/svg-symbol.tsx b/lib/svg-symbol.tsx
index 0e9a4de..4373abc 100644
--- a/lib/svg-symbol.tsx
+++ b/lib/svg-symbol.tsx
@@ -30,9 +30,23 @@ export type SvgSymbolElement = (
};
export type SvgSymbolContext = {
+ /** The stroke color of the symbol, as a hex hash (e.g. '#ff0000'). */
stroke: string;
+
+ /** The fill color of the symbol, as a hex hash (e.g. '#ff0000'). */
fill: string;
+
+ /**
+ * Whether or not to visibly show the specifications for the symbol,
+ * e.g. its attachment points, nesting boxes, and so on.
+ */
showSpecs: boolean;
+
+ /**
+ * Whether or not to forcibly apply a uniform stroke width to all
+ * the shapes in the symbol. If defined, the stroke width will
+ * *not* vary as the symbol is scaled.
+ */
uniformStrokeWidth?: number;
};
@@ -43,6 +57,11 @@ const DEFAULT_CONTEXT: SvgSymbolContext = {
uniformStrokeWidth: DEFAULT_UNIFORM_STROKE_WIDTH,
};
+/**
+ * If the given symbol context is visibly showing its specifications,
+ * return one with its fill color set to "none" so that the specs can
+ * be seen more easily.
+ */
export function noFillIfShowingSpecs(ctx: T): T {
return {
...ctx,
@@ -50,6 +69,9 @@ export function noFillIfShowingSpecs(ctx: T): T {
};
}
+/**
+ * Return a symbol context with the stroke and fill colors swapped.
+ */
export function swapColors(ctx: T): T {
return {
...ctx,
diff --git a/lib/symbol-context-widget.tsx b/lib/symbol-context-widget.tsx
index 0bb1fac..00a4293 100644
--- a/lib/symbol-context-widget.tsx
+++ b/lib/symbol-context-widget.tsx
@@ -4,11 +4,19 @@ import { ColorWidget } from "./color-widget";
import { NumericSlider } from "./numeric-slider";
import { SvgSymbolContext, swapColors } from "./svg-symbol";
-export const SymbolContextWidget: React.FC<{
- ctx: SvgSymbolContext;
- onChange: (value: SvgSymbolContext) => void;
+export type SymbolContextWidgetProps = {
+ ctx: T;
+ onChange: (value: T) => void;
children?: any;
-}> = ({ ctx, children, onChange }) => {
+ extraButtons?: JSX.Element;
+};
+
+export function SymbolContextWidget({
+ ctx,
+ children,
+ onChange,
+ extraButtons,
+}: SymbolContextWidgetProps): JSX.Element {
const updateCtx = (updates: Partial) => {
onChange({ ...ctx, ...updates });
};
@@ -29,6 +37,7 @@ export const SymbolContextWidget: React.FC<{
{" "}
+ {extraButtons}
);
-};
+}