Skip to content

Commit

Permalink
Merge pull request #52 from kurgm/selected-center-line
Browse files Browse the repository at this point in the history
Add an option to show only the center line of the current selected stroke
  • Loading branch information
kurgm authored Oct 15, 2023
2 parents ff26b78 + fbd1c39 commit 573fed9
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 44 deletions.
8 changes: 7 additions & 1 deletion src/actions/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import actionCreatorFactory from 'typescript-fsa';
import { KShotai } from '../kage';
import { XorMaskType } from '../xorMask';

export enum ShowCenterLine {
none,
selection,
always
}

const actionCreator = actionCreatorFactory('DISPLAY');

export const displayActions = {
Expand All @@ -16,7 +22,7 @@ export const displayActions = {
setGridSpacingY: actionCreator<number>('SET_GRID_SPACING_Y'),

setShotai: actionCreator<KShotai>('SET_SHOTAI'),
setStrokeCenterLineDisplay: actionCreator<boolean>('SET_STROKE_CENTER_LINE_DISPLAY'),
setStrokeCenterLineDisplay: actionCreator<ShowCenterLine>('SET_STROKE_CENTER_LINE_DISPLAY'),

setXorMaskType: actionCreator<XorMaskType>('SET_XOR_MASK_TYPE'),
};
3 changes: 1 addition & 2 deletions src/components/GlyphArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,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 @@ -109,7 +108,7 @@ const GlyphArea = () => {
handleMouseDownDeselectedStroke={handleMouseDownDeselectedStroke}
handleMouseDownSelectedStroke={handleMouseDownSelectedStroke}
/>
{showStrokeCenterLine && <StrokeCenterLine glyph={glyph} buhinMap={buhinMap} />}
<StrokeCenterLine />
<SelectionControl />
<AreaSelectRect rect={areaSelectRect} />
</svg>
Expand Down
11 changes: 6 additions & 5 deletions src/components/OptionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useSelector, useDispatch } from 'react-redux';
import ReactModal from 'react-modal';
import { useTranslation } from 'react-i18next';

import { displayActions } from '../actions/display';
import { displayActions, ShowCenterLine } from '../actions/display';
import { AppState } from '../reducers';
import { KShotai } from '../kage';
import { XorMaskType, xorMaskTypes } from '../xorMask';
Expand Down Expand Up @@ -42,7 +42,7 @@ const OptionModal = () => {
dispatch(displayActions.setShotai(+evt.currentTarget.value as KShotai));
}, [dispatch]);
const handleStrokeCenterLineChange = useCallback((evt: React.ChangeEvent<HTMLSelectElement>) => {
dispatch(displayActions.setStrokeCenterLineDisplay(+evt.currentTarget.value === 1));
dispatch(displayActions.setStrokeCenterLineDisplay(+evt.currentTarget.value as ShowCenterLine));
}, [dispatch]);
const handleXorMaskTypeChange = useCallback((evt: React.ChangeEvent<HTMLSelectElement>) => {
dispatch(displayActions.setXorMaskType(evt.currentTarget.value as XorMaskType));
Expand Down Expand Up @@ -122,11 +122,12 @@ const OptionModal = () => {

<div>{t('show stroke center line')}</div>
<select
value={showStrokeCenterLine ? 1 : 0}
value={showStrokeCenterLine}
onChange={handleStrokeCenterLineChange}
>
<option value={0}>{t('show stroke center line none')}</option>
<option value={1}>{t('show stroke center line always')}</option>
<option value={ShowCenterLine.none}>{t('show stroke center line none')}</option>
<option value={ShowCenterLine.selection}>{t('show stroke center line selection')}</option>
<option value={ShowCenterLine.always}>{t('show stroke center line always')}</option>
</select>

<div>{t('negative mask type')}</div>
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;
5 changes: 3 additions & 2 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@
"mincho style": "Mincho",
"gothic style": "Gothic",
"show stroke center line": "Center Line",
"show stroke center line none": "Hidden",
"show stroke center line always": "Shown",
"show stroke center line none": "Hide",
"show stroke center line selection": "Show Only Selection",
"show stroke center line always": "Always Show",
"negative mask type": "Mask",
"negative mask type none": "None",
"negative mask type circle": "Circle",
Expand Down
3 changes: 2 additions & 1 deletion src/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
"gothic style": "ゴシック",
"show stroke center line": "中心線",
"show stroke center line none": "表示しない",
"show stroke center line always": "表示する",
"show stroke center line selection": "選択のみ表示",
"show stroke center line always": "常に表示",
"negative mask type": "白抜き",
"negative mask type none": "なし",
"negative mask type circle": "",
Expand Down
3 changes: 2 additions & 1 deletion src/locales/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
"gothic style": "고딕",
"show stroke center line": "중심선",
"show stroke center line none": "표시하지 않음",
"show stroke center line always": "표시하다",
"show stroke center line selection": "선택만 표시",
"show stroke center line always": "항상 표시",
"negative mask type": "백을 남김",
"negative mask type none": "없음",
"negative mask type circle": "동그라미",
Expand Down
3 changes: 2 additions & 1 deletion src/locales/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
"gothic style": "黑体",
"show stroke center line": "笔画中线",
"show stroke center line none": "隐藏",
"show stroke center line always": "显示",
"show stroke center line selection": "只显示选取笔画",
"show stroke center line always": "始终显示",
"negative mask type": "蒙板",
"negative mask type none": "",
"negative mask type circle": "圆形",
Expand Down
3 changes: 2 additions & 1 deletion src/locales/zh_TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
"gothic style": "黑體",
"show stroke center line": "筆劃中線",
"show stroke center line none": "隱藏",
"show stroke center line always": "顯示",
"show stroke center line selection": "只顯示選取筆劃",
"show stroke center line always": "始終顯示",
"negative mask type": "遮罩",
"negative mask type none": "",
"negative mask type circle": "圓形",
Expand Down
5 changes: 3 additions & 2 deletions src/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { reducerWithInitialState } from 'typescript-fsa-reducers';

import { ShowCenterLine } from '../actions/display';
import { RectPointPosition, CTMInv } from '../actions/drag';

import { GlyphLine, Glyph, parseGlyph } from '../kageUtils/glyph';
Expand Down Expand Up @@ -38,7 +39,7 @@ export interface AppState {

showOptionModal: boolean;
grid: GridState;
showStrokeCenterLine: boolean;
showStrokeCenterLine: ShowCenterLine;
shotai: KShotai;
xorMaskType: XorMaskType;
}
Expand Down Expand Up @@ -69,7 +70,7 @@ const initialState: AppState = {
spacingX: 20,
spacingY: 20,
},
showStrokeCenterLine: false,
showStrokeCenterLine: ShowCenterLine.selection,
shotai: 0, // kMincho
xorMaskType: "none",
};
Expand Down

0 comments on commit 573fed9

Please sign in to comment.