Skip to content

Commit

Permalink
Select strokes to show center lines of in StrokeCenterLine
Browse files Browse the repository at this point in the history
  • Loading branch information
kurgm committed Oct 7, 2023
1 parent 358f608 commit 1aa23ac
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 66 deletions.
4 changes: 1 addition & 3 deletions src/components/GlyphArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useDispatch, useSelector } from 'react-redux';
import { AppState } from '../reducers';

import { selectActions } from '../actions/select';
import { ShowCenterLine } from '../actions/display';
import { dragActions, CTMInv } from '../actions/drag';
import { draggedGlyphSelector } from '../selectors/draggedGlyph';

Expand All @@ -25,7 +24,6 @@ const GlyphArea = () => {
const selection = useSelector((state: AppState) => state.selection);
const areaSelectRect = useSelector((state: AppState) => state.areaSelectRect);
const freehandMode = useSelector((state: AppState) => state.freehandMode);
const showStrokeCenterLine = useSelector((state: AppState) => state.showStrokeCenterLine);

const svgClassName = freehandMode ? 'freehand' : '';

Expand Down Expand Up @@ -110,7 +108,7 @@ const GlyphArea = () => {
handleMouseDownDeselectedStroke={handleMouseDownDeselectedStroke}
handleMouseDownSelectedStroke={handleMouseDownSelectedStroke}
/>
{showStrokeCenterLine === ShowCenterLine.always && <StrokeCenterLine glyph={glyph} buhinMap={buhinMap} />}
<StrokeCenterLine />
<SelectionControl />
<AreaSelectRect rect={areaSelectRect} />
</svg>
Expand Down
39 changes: 4 additions & 35 deletions src/components/SelectionControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useDispatch, useSelector } from 'react-redux';

import { createSelector } from 'reselect';

import { ShowCenterLine } from '../actions/display';
import { dragActions, RectPointPosition } from '../actions/drag';
import { AppState } from '../reducers';
import { draggedGlyphSelector } from '../selectors/draggedGlyph';
Expand All @@ -27,7 +26,6 @@ interface ControlPointSpec {
interface SelectionControlSpec {
rectControl: RectControl | null;
pointControl: ControlPointSpec[];
centerLine: string | null;
}

const selectionControlSelector = createSelector(
Expand All @@ -37,7 +35,7 @@ const selectionControlSelector = createSelector(
],
(glyph, selection): SelectionControlSpec => {
if (selection.length === 0) {
return { rectControl: null, pointControl: [], centerLine: null };
return { rectControl: null, pointControl: [] };
}
if (selection.length > 1) {
const selectedStrokes = selection.map((index) => glyph[index]);
Expand All @@ -48,7 +46,6 @@ const selectionControlSelector = createSelector(
coords: bbx,
},
pointControl: [],
centerLine: null,
};
}
const selectedStroke = glyph[selection[0]];
Expand All @@ -67,7 +64,6 @@ const selectionControlSelector = createSelector(
],
},
pointControl: [],
centerLine: null,
};
case 1:
case 2:
Expand All @@ -94,40 +90,16 @@ const selectionControlSelector = createSelector(
className,
});
}

const v = selectedStroke.value;
let centerLine: string | null = null;
switch (v[0]) {
case 1:
centerLine = `M ${v[3]} ${v[4]} ${v[5]} ${v[6]}`;
break;
case 2:
centerLine = `M ${v[3]} ${v[4]} Q ${v[5]} ${v[6]} ${v[7]} ${v[8]}`;
break;
case 3:
case 4:
centerLine = `M ${v[3]} ${v[4]} ${v[5]} ${v[6]} ${v[7]} ${v[8]}`;
break;
case 6:
centerLine = `M ${v[3]} ${v[4]} C ${v[5]} ${v[6]} ${v[7]} ${v[8]} ${v[9]} ${v[10]}`;
break;
case 7:
centerLine = `M ${v[3]} ${v[4]} ${v[5]} ${v[6]} Q ${v[7]} ${v[8]} ${v[9]} ${v[10]}`;
break;
default:
break;
}
return { rectControl: null, pointControl, centerLine };
return { rectControl: null, pointControl };
}
default:
return { rectControl: null, pointControl: [], centerLine: null };
return { rectControl: null, pointControl: [] };
}
}
);

const SelectionControl = () => {
const { rectControl, pointControl, centerLine } = useSelector(selectionControlSelector);
const showStrokeCenterLine = useSelector((state: AppState) => state.showStrokeCenterLine);
const { rectControl, pointControl } = useSelector(selectionControlSelector);

const dispatch = useDispatch();
const handleMouseDownRectControl = useCallback((evt: React.MouseEvent, position: RectPointPosition) => {
Expand Down Expand Up @@ -203,9 +175,6 @@ const SelectionControl = () => {
handleMouseDown={handleMouseDownSoutheastPoint}
/>
</>}
{showStrokeCenterLine === ShowCenterLine.selection && centerLine &&
<path className="stroke-center-line" d={centerLine} />
}
{pointControl.map(({ x, y, className }, index) => (
<ControlPoint
key={index}
Expand Down
105 changes: 77 additions & 28 deletions src/components/StrokeCenterLine.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,88 @@
import React from 'react';

import { decomposeDeepGlyph } from '../kageUtils/decompose';
import { Glyph } from '../kageUtils/glyph';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';

import { ShowCenterLine } from '../actions/display';
import { AppState } from '../reducers';
import { draggedGlyphSelector } from '../selectors/draggedGlyph';
import { decomposeDeep } from '../kageUtils/decompose';
import { GlyphLine } from '../kageUtils/glyph';

import './StrokeCenterLine.css';

export interface StrokeCenterLineProps {
glyph: Glyph;
buhinMap: Map<string, string>;
}
const strokeCenterLineShownNumbersSelector = createSelector(
[
draggedGlyphSelector,
(state: AppState) => state.showStrokeCenterLine,
(state: AppState) => state.selection,
],
(glyph, showStrokeCenterLine, selection): number[] => {
switch (showStrokeCenterLine) {
case ShowCenterLine.none:
return [];
case ShowCenterLine.selection: {
if (selection.length !== 1) {
return [];
}
const selectedGlyphLine = glyph[selection[0]];
switch (selectedGlyphLine.value[0]) {
case 0:
case 9:
case 99:
return [];
default:
return selection;
}
}
case ShowCenterLine.always:
return glyph.map((_gLine, index) => index);
default:
// exhaustive?
return ((_x: never) => _x)(showStrokeCenterLine);
}
}
);

const StrokeCenterLine = (props: StrokeCenterLineProps) => {
const strokes = decomposeDeepGlyph(props.glyph, props.buhinMap);
const strokeCenterLineStrokesPerLinesSelector = createSelector(
[
draggedGlyphSelector,
(state: AppState) => state.buhinMap,
strokeCenterLineShownNumbersSelector,
],
(glyph, buhinMap, glyphLineNumbers): GlyphLine[][] => (
glyph.map((gLine, index) => glyphLineNumbers.includes(index) ? decomposeDeep(gLine, buhinMap) : [])
)
);

const StrokeCenterLine = () => {
const strokesPerLines = useSelector(strokeCenterLineStrokesPerLinesSelector);
return (
<g className="stroke-center-line">
{strokes.map((stroke, index) => {
const v = stroke.value;
switch (v[0]) {
case 1:
return <path key={index} d={`M ${v[3]} ${v[4]} ${v[5]} ${v[6]}`} />
case 2:
return <path key={index} d={`M ${v[3]} ${v[4]} Q ${v[5]} ${v[6]} ${v[7]} ${v[8]}`} />
case 3:
case 4:
return <path key={index} d={`M ${v[3]} ${v[4]} ${v[5]} ${v[6]} ${v[7]} ${v[8]}`} />
case 6:
return <path key={index} d={`M ${v[3]} ${v[4]} C ${v[5]} ${v[6]} ${v[7]} ${v[8]} ${v[9]} ${v[10]}`} />
case 7:
return <path key={index} d={`M ${v[3]} ${v[4]} ${v[5]} ${v[6]} Q ${v[7]} ${v[8]} ${v[9]} ${v[10]}`} />
default:
return null;
}
})}
{strokesPerLines.map((strokesPerLine, lineIndex) => (
<g key={lineIndex}>
{strokesPerLine.map((stroke, strokeIndex) => {
const v = stroke.value;
switch (v[0]) {
case 1:
return <path key={strokeIndex} d={`M ${v[3]} ${v[4]} ${v[5]} ${v[6]}`} />
case 2:
return <path key={strokeIndex} d={`M ${v[3]} ${v[4]} Q ${v[5]} ${v[6]} ${v[7]} ${v[8]}`} />
case 3:
case 4:
return <path key={strokeIndex} d={`M ${v[3]} ${v[4]} ${v[5]} ${v[6]} ${v[7]} ${v[8]}`} />
case 6:
return <path key={strokeIndex} d={`M ${v[3]} ${v[4]} C ${v[5]} ${v[6]} ${v[7]} ${v[8]} ${v[9]} ${v[10]}`} />
case 7:
return <path key={strokeIndex} d={`M ${v[3]} ${v[4]} ${v[5]} ${v[6]} Q ${v[7]} ${v[8]} ${v[9]} ${v[10]}`} />
default:
return null;
}
})}
</g>
))}
</g>
)
}
);
};

export default StrokeCenterLine;

0 comments on commit 1aa23ac

Please sign in to comment.