Skip to content

Commit

Permalink
feat: pencil tool
Browse files Browse the repository at this point in the history
  • Loading branch information
F-star committed May 18, 2024
1 parent d2c6e8e commit 55860dd
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 76 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"clonedeep",
"Dists",
"Formatjs",
"IRGB",
"IRGBA",
"isequal",
"outfile",
Expand Down
16 changes: 12 additions & 4 deletions packages/common/src/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@ interface IRGBA extends IRGB {
a: number;
}

export function parseRGBAStr({ r, g, b, a }: IRGBA) {
export const parseRGBAStr = ({ r, g, b, a }: IRGBA) => {
return `rgba(${r},${g},${b},${a})`;
}
};

export function parseRGBStr({ r, g, b }: { r: number; g: number; b: number }) {
export const parseRGBStr = ({
r,
g,
b,
}: {
r: number;
g: number;
b: number;
}) => {
return `rgb(${r},${g},${b})`;
}
};
/**
* normalize hex to `RRGGBB` string format
*
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/tools/tool_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DrawRegularPolygon } from './tool_draw_regular_polygon';
import { DrawStar } from './tool_draw_star';
import { DrawTextTool } from './tool_draw_text';
import { PathSelectTool } from './tool_path_select/tool_path_select';
import { PencilTool } from './tool_pencil';
import { SelectTool } from './tool_select';
import { type ITool, type IToolClassConstructor } from './type';

Expand Down Expand Up @@ -49,12 +50,14 @@ export class ToolManager {
this.registerToolCtor(DrawPathTool);
this.registerToolCtor(DrawRegularPolygon);
this.registerToolCtor(DrawStar);
this.registerToolCtor(PencilTool);

this.setEnableHotKeyTools([
SelectTool.type,
DrawRectTool.type,
DrawEllipseTool.type,
DrawPathTool.type,
PencilTool.type,
DrawLineTool.type,
DrawRegularPolygon.type,
DrawStar.type,
Expand Down Expand Up @@ -100,6 +103,7 @@ export class ToolManager {
this.hotkeySet.add(hotkey);

const keyCode = `Key${toolCtor.hotkey.toUpperCase()}`;
// TODO: support complex hotkey
const token = this.editor.keybindingManager.register({
key: { keyCode: keyCode },
actionName: type,
Expand Down Expand Up @@ -157,7 +161,9 @@ export class ToolManager {
}
const dx = e.clientX - startPos.x;
const dy = e.clientY - startPos.y;
const dragBlockStep = this.editor.setting.get('dragBlockStep');
const dragBlockStep =
this.currentTool.getDragBlockStep?.() ??
this.editor.setting.get('dragBlockStep');
if (
!this._isDragging &&
(Math.abs(dx) > dragBlockStep || Math.abs(dy) > dragBlockStep)
Expand Down
91 changes: 91 additions & 0 deletions packages/core/src/tools/tool_pencil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { cloneDeep, noop } from '@suika/common';

import { AddGraphCmd } from '../commands';
import { type ICursor } from '../cursor_manager';
import { type Editor } from '../editor';
import { Path } from '../graphs';
import { type ITool } from './type';

const TYPE = 'pencil';
const HOTKEY = '';

export class PencilTool implements ITool {
static readonly type = TYPE;
static readonly hotkey = HOTKEY;
readonly type = TYPE;
readonly hotkey = HOTKEY;
cursor: ICursor = 'crosshair';
commandDesc = 'draw by Pencil';
private unbindEvent: () => void = noop;

private path: Path | null = null;
private isFirstDrag = true;

constructor(private editor: Editor) {}
onActive() {
// do nothing
}
onInactive() {
this.unbindEvent();
}
onMoveExcludeDrag() {
// do nothing
}

onStart(e: PointerEvent) {
this.path = new Path({
objectName: '',
width: 0,
height: 0,
pathData: [
{
segs: [],
closed: false,
},
],
stroke: [cloneDeep(this.editor.setting.get('firstStroke'))],
strokeWidth: 3,
});

const point = this.editor.getSceneCursorXY(e);
this.path!.addSeg(0, {
point,
in: { x: 0, y: 0 },
out: { x: 0, y: 0 },
});
}

onDrag(e: PointerEvent) {
const point = this.editor.getSceneCursorXY(e);
this.path!.addSeg(0, {
point,
in: { x: 0, y: 0 },
out: { x: 0, y: 0 },
});

if (this.isFirstDrag) {
this.editor.sceneGraph.addItems([this.path!]);
this.isFirstDrag = false;
}
this.editor.render();
}

onEnd(_e: PointerEvent, isDragHappened: boolean) {
if (isDragHappened) {
this.editor.commandManager.pushCommand(
new AddGraphCmd('Add Path by pencil', this.editor, [this.path!]),
);
} else {
this.editor.sceneGraph.removeItems([this.path!]);
}
}

afterEnd() {
this.path = null;
this.isFirstDrag = true;
}

getDragBlockStep() {
return 0;
}
}
1 change: 1 addition & 0 deletions packages/core/src/tools/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface ITool extends IBaseTool {
type: string;
cursor: ICursor;
onMoveExcludeDrag: (event: PointerEvent, isOutsideCanvas: boolean) => void;
getDragBlockStep?: () => number;
}

export interface IBaseTool {
Expand Down
71 changes: 0 additions & 71 deletions packages/core/src/utils/color.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/icons/src/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './i18n-outlined';
export * from './line-width-outlined';
export * from './lock-filled';
export * from './pen-outlined';
export * from './pencil-outlined';
export * from './remove-outlined';
export * from './right-outlined';
export * from './show-outlined';
Expand Down
18 changes: 18 additions & 0 deletions packages/icons/src/icons/pencil-outlined.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';

export const PencilOutlined = React.memo(() => {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.6992 9.30076L8.7158 18.2842C8.66927 18.3307 8.61198 18.3651 8.54902 18.3842L5.3017 19.3687C4.99583 19.4615 4.71011 19.1757 4.80285 18.8699L5.78742 15.6226C5.80651 15.5596 5.84084 15.5023 5.88737 15.4558L14.8708 6.47233M17.6992 9.30076L19.8593 7.14071C20.0155 6.9845 20.0155 6.73123 19.8593 6.57502L17.5966 4.31228C17.4403 4.15607 17.1871 4.15607 17.0309 4.31228L14.8708 6.47233M17.6992 9.30076L14.8708 6.47233"
stroke="currentColor"
/>
</svg>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
EllipseOutlined,
HandOutlined,
LineOutlined,
PencilOutlined,
PenOutlined,
PolygonOutlined,
RectOutlined,
Expand Down Expand Up @@ -89,6 +90,12 @@ export const ToolBar = () => {
intlId: 'tool.pen',
icon: <PenOutlined />,
},
pencil: {
name: 'pencil',
hotkey: '',
intlId: 'tool.pencil',
icon: <PencilOutlined />,
},
drawLine: {
name: 'drawLine',
hotkey: 'L',
Expand Down
1 change: 1 addition & 0 deletions packages/suika/src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"tool.star": "Star",
"tool.text": "Text",
"tool.hand": "Hand",
"tool.pencil": "Pencil",
"command.copy": "Copy",
"command.copyAsSVG": "Copy as SVG",
"command.pasteHere": "Paste here",
Expand Down
1 change: 1 addition & 0 deletions packages/suika/src/locale/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"tool.star": "星形",
"tool.text": "文字",
"tool.hand": "拖拽画布",
"tool.pencil": "铅笔",
"command.copy": "复制",
"command.copyAsSVG": "复制 SVG 代码",
"command.pasteHere": "粘贴到此处",
Expand Down

0 comments on commit 55860dd

Please sign in to comment.