Skip to content

Commit

Permalink
feat(freehand): initialize freehand #2
Browse files Browse the repository at this point in the history
  • Loading branch information
pubuzhixing8 committed Nov 28, 2024
1 parent cc645a8 commit 417f973
Show file tree
Hide file tree
Showing 14 changed files with 501 additions and 41 deletions.
52 changes: 26 additions & 26 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
"private": true,
"dependencies": {
"@floating-ui/react": "^0.26.24",
"@plait/common": "^0.71.0",
"@plait/core": "^0.71.0",
"@plait/draw": "^0.71.0",
"@plait/layouts": "^0.71.0",
"@plait/mind": "^0.71.0",
"@plait/text-plugins": "^0.71.0",
"@plait/common": "^0.72.0",
"@plait/core": "^0.72.0",
"@plait/draw": "^0.72.0",
"@plait/layouts": "^0.72.0",
"@plait/mind": "^0.72.0",
"@plait/text-plugins": "^0.72.0",
"ahooks": "^3.8.0",
"browser-fs-access": "^0.35.0",
"classnames": "^2.5.1",
Expand Down
19 changes: 17 additions & 2 deletions packages/drawnix/src/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ export const RedoIcon = createIcon(
);

export const TrashIcon = createIcon(
<svg role="img" viewBox="0 0 20 20" fill="none" stroke="currentColor">
<svg viewBox="0 0 20 20" fill="none" stroke="currentColor">
<path
strokeWidth="1.25"
d="M3.333 5.833h13.334M8.333 9.167v5M11.667 9.167v5M4.167 5.833l.833 10c0 .92.746 1.667 1.667 1.667h6.666c.92 0 1.667-.746 1.667-1.667l.833-10M7.5 5.833v-2.5c0-.46.373-.833.833-.833h3.334c.46 0 .833.373.833.833v2.5"
Expand All @@ -426,10 +426,25 @@ export const TrashIcon = createIcon(
);

export const DuplicateIcon = createIcon(
<svg role="img" viewBox="0 0 20 20" fill="none" stroke="currentColor">
<svg
viewBox="0 0 20 20"
fill="none"
stroke="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g strokeWidth="1.25">
<path d="M14.375 6.458H8.958a2.5 2.5 0 0 0-2.5 2.5v5.417a2.5 2.5 0 0 0 2.5 2.5h5.417a2.5 2.5 0 0 0 2.5-2.5V8.958a2.5 2.5 0 0 0-2.5-2.5Z"></path>
<path d="M11.667 3.125c.517 0 .986.21 1.325.55.34.338.55.807.55 1.325v1.458H8.333c-.485 0-.927.185-1.26.487-.343.312-.57.75-.609 1.24l-.005 5.357H5a1.87 1.87 0 0 1-1.326-.55 1.87 1.87 0 0 1-.549-1.325V5c0-.518.21-.987.55-1.326.338-.34.807-.549 1.325-.549h6.667Z"></path>
</g>
</svg>
);

export const FeltTipPenIcon = createIcon(
<svg
viewBox="0 0 1024 1024"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M170.794667 896c3.456 0 6.912-0.426667 10.325333-1.28l170.666667-42.666667c7.509333-1.877333 14.378667-5.76 19.84-11.221333L896.128 316.330667c16.128-16.128 25.002667-37.546667 25.002667-60.330667s-8.874667-44.202667-25.002667-60.330667L828.458667 128c-32.256-32.256-88.405333-32.256-120.661334 0L183.296 652.501333a42.794667 42.794667 0 0 0-11.221333 19.797334l-42.666667 170.666666A42.666667 42.666667 0 0 0 170.794667 896z m597.333333-707.669333L835.797333 256l-67.669333 67.669333L700.458667 256l67.669333-67.669333zM251.989333 704.469333l388.138667-388.138666L707.797333 384l-388.181333 388.138667-90.197333 22.528 22.570666-90.197334z"></path>
</svg>
);
7 changes: 7 additions & 0 deletions packages/drawnix/src/components/toolbar/creation-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ShapeIcon,
TextIcon,
StraightArrowLineIcon,
FeltTipPenIcon,
} from '../icons';
import { useBoard } from '@plait/react-board';
import {
Expand All @@ -25,6 +26,7 @@ import { ShapePicker } from '../shape-picker';
import { ArrowPicker } from '../arrow-picker';
import { useState } from 'react';
import { Popover, PopoverContent, PopoverTrigger } from '../popover/popover';
import { FreehandShape } from '../../plugins/freehand/type';

export enum PopupKey {
'shape' = 'shape',
Expand Down Expand Up @@ -66,6 +68,11 @@ export const BUTTONS: AppToolButtonProps[] = [
pointer: BasicShapes.text,
title: 'Text',
},
{
icon: FeltTipPenIcon,
pointer: FreehandShape.feltTipPen,
title: 'Freehand',
},
{
icon: StraightArrowLineIcon,
title: 'Arrow Line',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
} from '../../icons';
import { Popover, PopoverContent, PopoverTrigger } from '../../popover/popover';
import Stack from '../../stack';
import { PropertyTransforms } from '@plait/common';
import { getMemorizeKey, StrokeStyle } from '@plait/draw';
import { PropertyTransforms, StrokeStyle } from '@plait/common';
import { getMemorizeKey } from '@plait/draw';

export type PopupStrokeButtonProps = {
board: PlaitBoard;
Expand Down
6 changes: 5 additions & 1 deletion packages/drawnix/src/drawnix.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { AppToolbar } from './components/toolbar/app-toolbar/app-toolbar';
import classNames from 'classnames';
import './styles/index.scss';
import { withDrawnixHotkey } from './plugins/with-hotkey';
import { FreehandShape } from './plugins/freehand/type';
import { withFreehand } from './plugins/freehand/with-freehand';

export type DrawnixProps = {
value: PlaitElement[];
Expand All @@ -38,7 +40,8 @@ export type DrawnixProps = {
export type DrawnixPointerType =
| PlaitPointerType
| MindPointerType
| DrawPointerType;
| DrawPointerType
| FreehandShape;

export type DrawnixState = {
pointer: DrawnixPointerType;
Expand All @@ -58,6 +61,7 @@ export const Drawnix: React.FC<DrawnixProps> = ({
withMindExtend,
withCommonPlugin,
withDrawnixHotkey,
withFreehand
];
const options: PlaitBoardOptions = {};
const [appState, setAppState] = useState<DrawnixState>(() => {
Expand Down
76 changes: 76 additions & 0 deletions packages/drawnix/src/plugins/freehand/freehand.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {
PlaitBoard,
PlaitPluginElementContext,
OnContextChanged,
RectangleClient,
isSelectionMoving,
ACTIVE_STROKE_WIDTH,
} from '@plait/core';
import { ActiveGenerator, CommonElementFlavour } from '@plait/common';
import { Freehand } from './type';
import { FreehandGenerator } from './freehand.generator';

export class FreehandComponent
extends CommonElementFlavour<Freehand, PlaitBoard>
implements OnContextChanged<Freehand, PlaitBoard>
{
constructor() {
super();
}

activeGenerator!: ActiveGenerator<Freehand>;

generator!: FreehandGenerator;

initializeGenerator() {
this.activeGenerator = new ActiveGenerator<Freehand>(this.board, {
getRectangle: (element: Freehand) => {
return RectangleClient.getRectangleByPoints(element.points);
},
getStrokeWidth: () => ACTIVE_STROKE_WIDTH,
getStrokeOpacity: () => 1,
hasResizeHandle: () => {
return !isSelectionMoving(this.board);
},
});
this.generator = new FreehandGenerator(this.board);
}

initialize(): void {
super.initialize();
this.initializeGenerator();
this.generator.processDrawing(this.element, this.getElementG());
}

onContextChanged(
value: PlaitPluginElementContext<Freehand, PlaitBoard>,
previous: PlaitPluginElementContext<Freehand, PlaitBoard>
) {
if (value.element !== previous.element || value.hasThemeChanged) {
this.generator.processDrawing(this.element, this.getElementG());
this.activeGenerator.processDrawing(
this.element,
PlaitBoard.getElementActiveHost(this.board),
{
selected: this.selected,
}
);
} else {
const needUpdate = value.selected !== previous.selected;
if (needUpdate) {
this.activeGenerator.processDrawing(
this.element,
PlaitBoard.getElementActiveHost(this.board),
{
selected: this.selected,
}
);
}
}
}

destroy(): void {
super.destroy();
this.activeGenerator?.destroy();
}
}
22 changes: 22 additions & 0 deletions packages/drawnix/src/plugins/freehand/freehand.generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Generator } from '@plait/common';
import { PlaitBoard, setStrokeLinecap } from '@plait/core';
import { Options } from 'roughjs/bin/core';
import { DefaultFreehand, Freehand } from './type';

export interface FreehandData {}

export class FreehandGenerator extends Generator<Freehand, FreehandData> {
protected draw(
element: Freehand,
data?: FreehandData | undefined
): SVGGElement | undefined {
let option: Options = { ...DefaultFreehand };
const g = PlaitBoard.getRoughSVG(this.board).curve(element.points, option);
setStrokeLinecap(g, 'round');
return g;
}

canDraw(element: Freehand, data: FreehandData): boolean {
return true;
}
}
25 changes: 25 additions & 0 deletions packages/drawnix/src/plugins/freehand/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DEFAULT_COLOR, Point } from '@plait/core';
import { PlaitCustomGeometry } from '@plait/draw';

export const DefaultFreehand = {
strokeColor: DEFAULT_COLOR,
strokeWidth: 4,
};

export enum FreehandShape {
nibPen = 'nibPen',
feltTipPen = 'feltTipPen',
artisticBrush = 'artisticBrush',
markerHighlight = 'markerHighlight',
}

export const FREEHAND_TYPE = 'freehand';

export interface Freehand
extends PlaitCustomGeometry<typeof FREEHAND_TYPE, Point[], FreehandShape> {}

export const Freehand = {
isFreehand: (value: any): value is Freehand => {
return value.type === FREEHAND_TYPE;
},
};
Loading

0 comments on commit 417f973

Please sign in to comment.