@edv4h/usketch-plugin-shape-freedraw 3.3.3 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -1
- package/dist/config.d.ts +2 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -4
- package/dist/config.js.map +1 -1
- package/dist/custom-pens.d.ts +68 -0
- package/dist/custom-pens.d.ts.map +1 -0
- package/dist/custom-pens.js +72 -0
- package/dist/custom-pens.js.map +1 -0
- package/dist/draw-tool.d.ts +1 -1
- package/dist/draw-tool.d.ts.map +1 -1
- package/dist/draw-tool.js +14 -8
- package/dist/draw-tool.js.map +1 -1
- package/dist/freedraw-service.d.ts +28 -0
- package/dist/freedraw-service.d.ts.map +1 -0
- package/dist/freedraw-service.js +32 -0
- package/dist/freedraw-service.js.map +1 -0
- package/dist/geometry/hit.d.ts +6 -1
- package/dist/geometry/hit.d.ts.map +1 -1
- package/dist/geometry/hit.js +81 -15
- package/dist/geometry/hit.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/pen-meta.d.ts +10 -3
- package/dist/pen-meta.d.ts.map +1 -1
- package/dist/pen-meta.js +26 -2
- package/dist/pen-meta.js.map +1 -1
- package/dist/plugin.d.ts +10 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +27 -6
- package/dist/plugin.js.map +1 -1
- package/dist/settings-store.d.ts +6 -3
- package/dist/settings-store.d.ts.map +1 -1
- package/dist/settings-store.js +15 -2
- package/dist/settings-store.js.map +1 -1
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +9 -0
- package/dist/shape.js.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/cursor-overlay.d.ts +1 -1
- package/dist/ui/cursor-overlay.d.ts.map +1 -1
- package/dist/ui/cursor-overlay.js +7 -3
- package/dist/ui/cursor-overlay.js.map +1 -1
- package/dist/ui/palette.js +2 -2
- package/dist/ui/palette.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -34,6 +34,36 @@ const plugins = [
|
|
|
34
34
|
一定幅ペンは中点を通る二次ベジェで平滑化、筆ペンは perfect-freehand で塗りアウトラインを生成。
|
|
35
35
|
蛍光ペンは要素単位合成のため、同一ストローク内の交差は二重に濃くならず別ストローク同士は濃くなる。
|
|
36
36
|
|
|
37
|
+
## 外からペンを足す
|
|
38
|
+
|
|
39
|
+
組み込みの 4 種に、別のプラグインやホストがペンを足せる。足したペンのストロークも `freedraw`
|
|
40
|
+
shape なので、選択・移動・拡大縮小(点列だけを伸ばし、太さは変えない)・消しゴム・当たり判定・
|
|
41
|
+
undo・同期はそのまま効く。描画は SVG で、GPU には回さない。
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
createFreedrawPlugin(undefined, {
|
|
45
|
+
pens: [
|
|
46
|
+
{
|
|
47
|
+
id: "road", // shape の pen に入る。組み込みの id とは重ねない
|
|
48
|
+
label: "道路",
|
|
49
|
+
defaultSize: 120,
|
|
50
|
+
sizeRange: { min: 40, max: 400 }, // freedraw:set-size をこの範囲に丸める
|
|
51
|
+
usesColor: false, // ペン先カーソルを色なしで出す
|
|
52
|
+
render: (shape) => <Road shape={shape} />,
|
|
53
|
+
renderDraft: (shape) => <path d={...} />, // 描いている最中(shape.draft === true)
|
|
54
|
+
finalize: (points, { size }) => ({ points: tidy(points), penData: { closed: true } }),
|
|
55
|
+
halfWidth: (size) => size / 2 + 12, // 外接矩形・当たり判定・消しゴムの半幅
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
ペンは shape の描画と当たり判定に効くので、実行中に足し外しせず、プラグインの引数で渡す。
|
|
62
|
+
`getFreedrawApi(app.services)?.listPens()`(または `listPens()`)は組み込み → 足したペンの順で
|
|
63
|
+
一覧を返すので、ペン選択 UI はこれで作れる。`finalize` が返す `penData` は移動・拡大縮小でそのまま
|
|
64
|
+
写されるので、座標は入れない(点列から毎回作る)。
|
|
65
|
+
ペンを登録していないクライアントでは、そのストロークはボールペンの線(色・太さはそのまま)で描かれる。
|
|
66
|
+
|
|
37
67
|
## 消しゴム
|
|
38
68
|
|
|
39
69
|
`mode: "eraser"` のとき、触れた freedraw ストロークを丸ごと削除する(ピクセル消去ではない)。
|
|
@@ -43,10 +73,13 @@ const plugins = [
|
|
|
43
73
|
|
|
44
74
|
```ts
|
|
45
75
|
type PenKind = "ballpoint" | "felt" | "brush" | "highlighter";
|
|
76
|
+
type PenId = PenKind | string; // 外から足したペンの id も入る
|
|
46
77
|
interface StrokePoint { x: number; y: number; p?: number } // p=疑似筆圧 0..1
|
|
47
78
|
interface FreedrawShapeData extends ShapeData {
|
|
48
79
|
points: StrokePoint[];
|
|
49
|
-
pen?:
|
|
80
|
+
pen?: PenId; // 省略時 ballpoint(旧データ後方互換)
|
|
81
|
+
penData?: Record<string, unknown>; // 足したペンの finalize が返したデータ
|
|
82
|
+
draft?: boolean; // 描いている最中だけ true
|
|
50
83
|
}
|
|
51
84
|
```
|
|
52
85
|
|
package/dist/config.d.ts
CHANGED
|
@@ -28,19 +28,14 @@ export declare const TUNING: {
|
|
|
28
28
|
};
|
|
29
29
|
/** プラグイン設定(JSON 可、Zod 検証)。実行時の可変状態は settings-store が持つ。 */
|
|
30
30
|
export declare const FreedrawConfigSchema: z.ZodObject<{
|
|
31
|
-
defaultPen: z.ZodDefault<z.
|
|
32
|
-
ballpoint: "ballpoint";
|
|
33
|
-
brush: "brush";
|
|
34
|
-
felt: "felt";
|
|
35
|
-
highlighter: "highlighter";
|
|
36
|
-
}>>;
|
|
31
|
+
defaultPen: z.ZodDefault<z.ZodString>;
|
|
37
32
|
defaultColor: z.ZodDefault<z.ZodString>;
|
|
38
33
|
defaultSizes: z.ZodDefault<z.ZodObject<{
|
|
39
34
|
ballpoint: z.ZodNumber;
|
|
40
35
|
felt: z.ZodNumber;
|
|
41
36
|
brush: z.ZodNumber;
|
|
42
37
|
highlighter: z.ZodNumber;
|
|
43
|
-
}, z.core.$
|
|
38
|
+
}, z.core.$catchall<z.ZodNumber>>>;
|
|
44
39
|
defaultEraserSize: z.ZodDefault<z.ZodNumber>;
|
|
45
40
|
brushDynamics: z.ZodDefault<z.ZodNumber>;
|
|
46
41
|
hitTest: z.ZodDefault<z.ZodEnum<{
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,uCAAuC;AACvC,eAAO,MAAM,UAAU;aAAK,GAAG,EAAE,CAAC;aAAE,GAAG,EAAE,EAAE;aAAE,IAAI,EAAE,GAAG;CAAW,CAAC;AAClE,eAAO,MAAM,YAAY;aAAK,GAAG,EAAE,EAAE;aAAE,GAAG,EAAE,GAAG;aAAE,IAAI,EAAE,CAAC;CAAW,CAAC;AACpE,eAAO,MAAM,oBAAoB;aAAK,GAAG,EAAE,EAAE;aAAE,GAAG,EAAE,GAAG;aAAE,IAAI,EAAE,CAAC;CAAW,CAAC;AAE5E,qBAAqB;AACrB,eAAO,MAAM,MAAM;IAClB,yCAAyC;aACzC,aAAa,EAAE,GAAG;IAClB,+BAA+B;aAC/B,cAAc,EAAE,GAAG;IACnB,wBAAwB;aACxB,aAAa,EAAE,IAAI;IACnB,wCAAwC;aACxC,iBAAiB,EAAE,GAAG;CACb,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,uCAAuC;AACvC,eAAO,MAAM,UAAU;aAAK,GAAG,EAAE,CAAC;aAAE,GAAG,EAAE,EAAE;aAAE,IAAI,EAAE,GAAG;CAAW,CAAC;AAClE,eAAO,MAAM,YAAY;aAAK,GAAG,EAAE,EAAE;aAAE,GAAG,EAAE,GAAG;aAAE,IAAI,EAAE,CAAC;CAAW,CAAC;AACpE,eAAO,MAAM,oBAAoB;aAAK,GAAG,EAAE,EAAE;aAAE,GAAG,EAAE,GAAG;aAAE,IAAI,EAAE,CAAC;CAAW,CAAC;AAE5E,qBAAqB;AACrB,eAAO,MAAM,MAAM;IAClB,yCAAyC;aACzC,aAAa,EAAE,GAAG;IAClB,+BAA+B;aAC/B,cAAc,EAAE,GAAG;IACnB,wBAAwB;aACxB,aAAa,EAAE,IAAI;IACnB,wCAAwC;aACxC,iBAAiB,EAAE,GAAG;CACb,CAAC;AAYX,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;iBAoB/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEvE,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,mBAAmB,GAAG,cAAc,CAE/E;AAED,uBAAuB;AACvB,eAAO,MAAM,WAAW,+BAA+B,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -15,16 +15,19 @@ export const TUNING = {
|
|
|
15
15
|
/** 確定時の RDP 間引き許容誤差(world px、0 で無効)。 */
|
|
16
16
|
simplifyTolerance: 0.6,
|
|
17
17
|
};
|
|
18
|
-
|
|
18
|
+
// 組み込みの 4 種は必須。外から足したペンの太さも id をキーにして持てる。
|
|
19
|
+
const SizesSchema = z
|
|
20
|
+
.object({
|
|
19
21
|
ballpoint: z.number().positive(),
|
|
20
22
|
felt: z.number().positive(),
|
|
21
23
|
brush: z.number().positive(),
|
|
22
24
|
highlighter: z.number().positive(),
|
|
23
|
-
})
|
|
25
|
+
})
|
|
26
|
+
.catchall(z.number().positive());
|
|
24
27
|
/** プラグイン設定(JSON 可、Zod 検証)。実行時の可変状態は settings-store が持つ。 */
|
|
25
28
|
export const FreedrawConfigSchema = z.object({
|
|
26
|
-
/**
|
|
27
|
-
defaultPen: z.
|
|
29
|
+
/** 既定ペン(組み込みのペンか、外から足したペンの id)。 */
|
|
30
|
+
defaultPen: z.string().default(DEFAULT_PEN),
|
|
28
31
|
/** 既定色。 */
|
|
29
32
|
defaultColor: z.string().default(PRESET_COLORS[0]),
|
|
30
33
|
/** ペンごとの既定太さ。 */
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE1E,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAW,CAAC;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAE5E,qBAAqB;AACrB,MAAM,CAAC,MAAM,MAAM,GAAG;IACrB,yCAAyC;IACzC,aAAa,EAAE,GAAG;IAClB,+BAA+B;IAC/B,cAAc,EAAE,GAAG;IACnB,wBAAwB;IACxB,aAAa,EAAE,IAAI;IACnB,wCAAwC;IACxC,iBAAiB,EAAE,GAAG;CACb,CAAC;AAEX,MAAM,WAAW,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE1E,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAW,CAAC;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAE5E,qBAAqB;AACrB,MAAM,CAAC,MAAM,MAAM,GAAG;IACrB,yCAAyC;IACzC,aAAa,EAAE,GAAG;IAClB,+BAA+B;IAC/B,cAAc,EAAE,GAAG;IACnB,wBAAwB;IACxB,aAAa,EAAE,IAAI;IACnB,wCAAwC;IACxC,iBAAiB,EAAE,GAAG;CACb,CAAC;AAEX,0CAA0C;AAC1C,MAAM,WAAW,GAAG,CAAC;KACnB,MAAM,CAAC;IACP,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC;KACD,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;AAElC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,mCAAmC;IACnC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;IAC3C,WAAW;IACX,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAClD,iBAAiB;IACjB,YAAY,EAAE,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC;IAChD,kBAAkB;IAClB,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACrF,0BAA0B;IAC1B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACjG;;;OAGG;IACH,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IACvD,iBAAiB;IACjB,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACxC,gCAAgC;IAChC,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CAC1C,CAAC,CAAC;AAKH,MAAM,UAAU,mBAAmB,CAAC,KAA2B;IAC9D,OAAO,oBAAoB,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,uBAAuB;AACvB,MAAM,CAAC,MAAM,WAAW,GAAG,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { FreedrawShapeData, StrokePoint } from "./types.js";
|
|
3
|
+
/** 太さの範囲(world px)。 */
|
|
4
|
+
export interface PenSizeRange {
|
|
5
|
+
min: number;
|
|
6
|
+
max: number;
|
|
7
|
+
}
|
|
8
|
+
/** {@link FreedrawPenDefinition.finalize} の戻り値。 */
|
|
9
|
+
export interface FinalizedStroke {
|
|
10
|
+
/** 保存する点列(world 座標)。 */
|
|
11
|
+
points: StrokePoint[];
|
|
12
|
+
/**
|
|
13
|
+
* ペン固有の保存データ。shape の `penData` に入る。移動・拡大縮小では点列だけが
|
|
14
|
+
* 変わり、`penData` はそのまま写されるので、座標(点列から作った形など)は入れない。
|
|
15
|
+
*/
|
|
16
|
+
penData?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 外から足すペンの定義(`createFreedrawPlugin(config, { pens })` で渡す)。
|
|
20
|
+
*
|
|
21
|
+
* 足したペンのストロークも組み込みのペンと同じ `freedraw` shape になるので、選択・移動・
|
|
22
|
+
* 拡大縮小・消しゴム・当たり判定・undo はそのまま効く。描画は SVG(DOM)で行い、GPU には
|
|
23
|
+
* 回さない。ペンを登録していないクライアントでは、そのストロークはボールペンの線で描かれる。
|
|
24
|
+
*/
|
|
25
|
+
export interface FreedrawPenDefinition {
|
|
26
|
+
/** shape の `pen` に入る id。組み込みのペン(ballpoint など)とは重ねない。 */
|
|
27
|
+
id: string;
|
|
28
|
+
label: string;
|
|
29
|
+
/** 既定の太さ(world px)。 */
|
|
30
|
+
defaultSize: number;
|
|
31
|
+
/** 太さの範囲。`freedraw:set-size` はこの範囲に丸める。省略時は丸めない。 */
|
|
32
|
+
sizeRange?: PenSizeRange;
|
|
33
|
+
/** 色を使うか(`false` ならペン先カーソルを色なしで出す)。既定 `true`。 */
|
|
34
|
+
usesColor?: boolean;
|
|
35
|
+
/** 確定したストロークの描画。 */
|
|
36
|
+
render(shape: FreedrawShapeData): ReactElement;
|
|
37
|
+
/** 描いている最中(`shape.draft === true`)の描画。省略時は {@link render}。 */
|
|
38
|
+
renderDraft?(shape: FreedrawShapeData): ReactElement;
|
|
39
|
+
/**
|
|
40
|
+
* 手を離したときに 1 回だけ呼ぶ。間引き後の点列を受け取り、保存する点列と
|
|
41
|
+
* ペン固有のデータを返す。省略時は点列をそのまま保存する。
|
|
42
|
+
*/
|
|
43
|
+
finalize?(points: StrokePoint[], ctx: {
|
|
44
|
+
size: number;
|
|
45
|
+
}): FinalizedStroke;
|
|
46
|
+
/**
|
|
47
|
+
* 点列(中心線)から描画の端までの最大の距離。外接矩形・当たり判定・消しゴムに使う。
|
|
48
|
+
* 省略時は `size / 2`。
|
|
49
|
+
*/
|
|
50
|
+
halfWidth?(size: number): number;
|
|
51
|
+
}
|
|
52
|
+
/** 組み込みのペンの id なら例外にする(登録より前に全部確かめるため分けている)。 */
|
|
53
|
+
export declare function assertCustomPenId(id: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* ペンを登録する(freedraw プラグインの setup から呼ぶ)。同じ定義は登録した数だけ
|
|
56
|
+
* 数え、全部外れたら消す(同じランタイムの複数ボードで共有しても、1 つの teardown で
|
|
57
|
+
* 他のボードから消えない)。同じ id の別の定義は置き換える。戻り値で 1 回ぶん外す。
|
|
58
|
+
*/
|
|
59
|
+
export declare function registerPen(def: FreedrawPenDefinition): () => void;
|
|
60
|
+
/** 登録済みのペン定義(組み込みのペンは含まない)。 */
|
|
61
|
+
export declare function getPenDefinition(id: string | undefined): FreedrawPenDefinition | undefined;
|
|
62
|
+
/** 登録済みのペン定義の一覧(登録順)。 */
|
|
63
|
+
export declare function listPenDefinitions(): FreedrawPenDefinition[];
|
|
64
|
+
/** 登録が変わったら呼ぶ。戻り値で解除。 */
|
|
65
|
+
export declare function onPensChange(listener: () => void): () => void;
|
|
66
|
+
/** `size` を定義の範囲に丸める(範囲が無ければそのまま)。 */
|
|
67
|
+
export declare function clampPenSize(def: FreedrawPenDefinition | undefined, size: number): number;
|
|
68
|
+
//# sourceMappingURL=custom-pens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-pens.d.ts","sourceRoot":"","sources":["../src/custom-pens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAW,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1E,uBAAuB;AACvB,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC/B,wBAAwB;IACxB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACrC,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB;IACpB,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAAC;IAC/C,8DAA8D;IAC9D,WAAW,CAAC,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAAC;IACrD;;;OAGG;IACH,QAAQ,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,CAAC;IACzE;;;OAGG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC;AAkBD,gDAAgD;AAChD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAmBlE;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,qBAAqB,GAAG,SAAS,CAE1F;AAED,yBAAyB;AACzB,wBAAgB,kBAAkB,IAAI,qBAAqB,EAAE,CAE5D;AAED,yBAAyB;AACzB,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAK7D;AAED,sCAAsC;AACtC,wBAAgB,YAAY,CAAC,GAAG,EAAE,qBAAqB,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIzF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// 登録は JS ランタイム単位(同じランタイムの AppInstance で共有)。shape の当たり判定や
|
|
2
|
+
// 外接矩形は shape だけを受け取る純関数から呼ばれるため、ここから引けるようにしている。
|
|
3
|
+
const registry = new Map();
|
|
4
|
+
// 組み込みのペンの id(pen-meta.ts の PEN_KINDS と同じ。循環 import を避けて自前で持つ)。
|
|
5
|
+
const BUILT_IN_IDS = new Set([
|
|
6
|
+
"ballpoint",
|
|
7
|
+
"felt",
|
|
8
|
+
"brush",
|
|
9
|
+
"highlighter",
|
|
10
|
+
]);
|
|
11
|
+
const listeners = new Set();
|
|
12
|
+
const notify = () => {
|
|
13
|
+
for (const l of listeners)
|
|
14
|
+
l();
|
|
15
|
+
};
|
|
16
|
+
/** 組み込みのペンの id なら例外にする(登録より前に全部確かめるため分けている)。 */
|
|
17
|
+
export function assertCustomPenId(id) {
|
|
18
|
+
if (BUILT_IN_IDS.has(id))
|
|
19
|
+
throw new Error(`freedraw: "${id}" is a built-in pen id`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* ペンを登録する(freedraw プラグインの setup から呼ぶ)。同じ定義は登録した数だけ
|
|
23
|
+
* 数え、全部外れたら消す(同じランタイムの複数ボードで共有しても、1 つの teardown で
|
|
24
|
+
* 他のボードから消えない)。同じ id の別の定義は置き換える。戻り値で 1 回ぶん外す。
|
|
25
|
+
*/
|
|
26
|
+
export function registerPen(def) {
|
|
27
|
+
assertCustomPenId(def.id);
|
|
28
|
+
const cur = registry.get(def.id);
|
|
29
|
+
if (cur && cur.def === def)
|
|
30
|
+
cur.count += 1;
|
|
31
|
+
else {
|
|
32
|
+
registry.set(def.id, { def, count: 1 });
|
|
33
|
+
notify();
|
|
34
|
+
}
|
|
35
|
+
let released = false;
|
|
36
|
+
return () => {
|
|
37
|
+
if (released)
|
|
38
|
+
return;
|
|
39
|
+
released = true;
|
|
40
|
+
const entry = registry.get(def.id);
|
|
41
|
+
if (!entry || entry.def !== def)
|
|
42
|
+
return;
|
|
43
|
+
entry.count -= 1;
|
|
44
|
+
if (entry.count > 0)
|
|
45
|
+
return;
|
|
46
|
+
registry.delete(def.id);
|
|
47
|
+
notify();
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** 登録済みのペン定義(組み込みのペンは含まない)。 */
|
|
51
|
+
export function getPenDefinition(id) {
|
|
52
|
+
return id === undefined ? undefined : registry.get(id)?.def;
|
|
53
|
+
}
|
|
54
|
+
/** 登録済みのペン定義の一覧(登録順)。 */
|
|
55
|
+
export function listPenDefinitions() {
|
|
56
|
+
return [...registry.values()].map((e) => e.def);
|
|
57
|
+
}
|
|
58
|
+
/** 登録が変わったら呼ぶ。戻り値で解除。 */
|
|
59
|
+
export function onPensChange(listener) {
|
|
60
|
+
listeners.add(listener);
|
|
61
|
+
return () => {
|
|
62
|
+
listeners.delete(listener);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** `size` を定義の範囲に丸める(範囲が無ければそのまま)。 */
|
|
66
|
+
export function clampPenSize(def, size) {
|
|
67
|
+
const r = def?.sizeRange;
|
|
68
|
+
if (!r)
|
|
69
|
+
return size;
|
|
70
|
+
return Math.min(r.max, Math.max(r.min, size));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=custom-pens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-pens.js","sourceRoot":"","sources":["../src/custom-pens.ts"],"names":[],"mappings":"AAqDA,yDAAyD;AACzD,iDAAiD;AACjD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyD,CAAC;AAClF,gEAAgE;AAChE,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAU;IAC1D,WAAW;IACX,MAAM;IACN,OAAO;IACP,aAAa;CACb,CAAC,CAAC;AACH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;AAExC,MAAM,MAAM,GAAG,GAAG,EAAE;IACnB,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,CAAC,EAAE,CAAC;AAChC,CAAC,CAAC;AAEF,gDAAgD;AAChD,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC3C,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;AACrF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAA0B;IACrD,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,GAAG;QAAE,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;SACtC,CAAC;QACL,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,EAAE,CAAC;IACV,CAAC;IACD,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,OAAO,GAAG,EAAE;QACX,IAAI,QAAQ;YAAE,OAAO;QACrB,QAAQ,GAAG,IAAI,CAAC;QAChB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG;YAAE,OAAO;QACxC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;QACjB,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC;YAAE,OAAO;QAC5B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxB,MAAM,EAAE,CAAC;IACV,CAAC,CAAC;AACH,CAAC;AAED,+BAA+B;AAC/B,MAAM,UAAU,gBAAgB,CAAC,EAAsB;IACtD,OAAO,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC;AAC7D,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,kBAAkB;IACjC,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,YAAY,CAAC,QAAoB;IAChD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,OAAO,GAAG,EAAE;QACX,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC,CAAC;AACH,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,YAAY,CAAC,GAAsC,EAAE,IAAY;IAChF,MAAM,CAAC,GAAG,GAAG,EAAE,SAAS,CAAC;IACzB,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/draw-tool.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CanvasPointerEvent, type ToolContext } from "@edv4h/usketch-shared";
|
|
2
|
-
import type
|
|
2
|
+
import { type FreedrawSettingsStore } from "./settings-store.js";
|
|
3
3
|
import type { PointerStore } from "./ui/cursor-overlay.js";
|
|
4
4
|
export interface DrawController {
|
|
5
5
|
onPointerDown(toolCtx: ToolContext, event: CanvasPointerEvent): void;
|
package/dist/draw-tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draw-tool.d.ts","sourceRoot":"","sources":["../src/draw-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,kBAAkB,EAIvB,KAAK,WAAW,EAChB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"draw-tool.d.ts","sourceRoot":"","sources":["../src/draw-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,kBAAkB,EAIvB,KAAK,WAAW,EAChB,MAAM,uBAAuB,CAAC;AAS/B,OAAO,EAAE,KAAK,qBAAqB,EAAW,MAAM,qBAAqB,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAyC3D,MAAM,WAAW,cAAc;IAC9B,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrE,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrE,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnE,uBAAuB;IACvB,KAAK,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,YAAY,GACnB,cAAc,CAuLhB"}
|
package/dist/draw-tool.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { DEFAULT_STYLE, generateId, } from "@edv4h/usketch-shared";
|
|
2
2
|
import { createAddShapeCommand } from "@edv4h/usketch-store";
|
|
3
3
|
import { TUNING } from "./config.js";
|
|
4
|
+
import { getPenDefinition } from "./custom-pens.js";
|
|
4
5
|
import { createEraseStrokesCommand, findErasedStrokes } from "./eraser.js";
|
|
5
6
|
import { smoothPressure, speedPressure } from "./geometry/brush-outline.js";
|
|
7
|
+
import { penHalfWidth } from "./geometry/hit.js";
|
|
6
8
|
import { simplifyPoints } from "./geometry/simplify.js";
|
|
7
9
|
import { penMeta } from "./pen-meta.js";
|
|
8
|
-
|
|
9
|
-
return variable ? (size * 1.55) / 2 : size / 2;
|
|
10
|
-
}
|
|
10
|
+
import { penSize } from "./settings-store.js";
|
|
11
11
|
function boundsOf(points, pad) {
|
|
12
12
|
let minX = Number.POSITIVE_INFINITY;
|
|
13
13
|
let minY = Number.POSITIVE_INFINITY;
|
|
@@ -45,7 +45,7 @@ export function createDrawController(settings, pointer) {
|
|
|
45
45
|
raf = 0;
|
|
46
46
|
if (!stroke)
|
|
47
47
|
return;
|
|
48
|
-
const pad =
|
|
48
|
+
const pad = penHalfWidth(stroke.pen, stroke.size);
|
|
49
49
|
const b = boundsOf(stroke.points, pad);
|
|
50
50
|
toolCtx.store.updateShape(stroke.id, {
|
|
51
51
|
x: b.x,
|
|
@@ -80,7 +80,7 @@ export function createDrawController(settings, pointer) {
|
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
82
|
const pen = s.pen;
|
|
83
|
-
const size = s
|
|
83
|
+
const size = penSize(s, pen);
|
|
84
84
|
const m = penMeta(pen);
|
|
85
85
|
const id = generateId();
|
|
86
86
|
const first = {
|
|
@@ -111,6 +111,7 @@ export function createDrawController(settings, pointer) {
|
|
|
111
111
|
style: buildStyle(s.color, size, m.alpha),
|
|
112
112
|
points: [first],
|
|
113
113
|
pen,
|
|
114
|
+
draft: true,
|
|
114
115
|
};
|
|
115
116
|
toolCtx.store.addShape(shape);
|
|
116
117
|
},
|
|
@@ -170,10 +171,14 @@ export function createDrawController(settings, pointer) {
|
|
|
170
171
|
}
|
|
171
172
|
const cur = stroke;
|
|
172
173
|
stroke = null;
|
|
173
|
-
// 確定: scratch を削除 → 間引き
|
|
174
|
+
// 確定: scratch を削除 → 間引き →(外から足したペンは finalize)→ undo 可能な追加コマンド。
|
|
174
175
|
toolCtx.store.deleteShape(cur.id);
|
|
175
|
-
const
|
|
176
|
-
const
|
|
176
|
+
const simplified = simplifyPoints(cur.points, TUNING.simplifyTolerance);
|
|
177
|
+
const finalized = getPenDefinition(cur.pen)?.finalize?.(simplified, { size: cur.size });
|
|
178
|
+
const points = finalized?.points ?? simplified;
|
|
179
|
+
if (points.length === 0)
|
|
180
|
+
return;
|
|
181
|
+
const pad = penHalfWidth(cur.pen, cur.size);
|
|
177
182
|
const b = boundsOf(points, pad);
|
|
178
183
|
const shape = {
|
|
179
184
|
id: cur.id,
|
|
@@ -185,6 +190,7 @@ export function createDrawController(settings, pointer) {
|
|
|
185
190
|
style: buildStyle(cur.color, cur.size, cur.alpha),
|
|
186
191
|
points,
|
|
187
192
|
pen: cur.pen,
|
|
193
|
+
...(finalized?.penData ? { penData: finalized.penData } : {}),
|
|
188
194
|
};
|
|
189
195
|
toolCtx.commands.execute(createAddShapeCommand(toolCtx.store, shape));
|
|
190
196
|
},
|
package/dist/draw-tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"draw-tool.js","sourceRoot":"","sources":["../src/draw-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,aAAa,EACb,UAAU,GAGV,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"draw-tool.js","sourceRoot":"","sources":["../src/draw-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ServiceRegistry } from "@edv4h/usketch-shared";
|
|
2
|
+
import { type PenSizeRange } from "./custom-pens.js";
|
|
3
|
+
import type { PenId } from "./types.js";
|
|
4
|
+
/** ペン選択 UI 向けの、ペン 1 種の情報。 */
|
|
5
|
+
export interface FreedrawPenInfo {
|
|
6
|
+
id: PenId;
|
|
7
|
+
label: string;
|
|
8
|
+
defaultSize: number;
|
|
9
|
+
sizeRange?: PenSizeRange;
|
|
10
|
+
/** 色を使うか。 */
|
|
11
|
+
usesColor: boolean;
|
|
12
|
+
/** 組み込みのペンか。 */
|
|
13
|
+
builtIn: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface FreedrawApi {
|
|
16
|
+
/** 選べるペン(組み込み → 外から足したペンの登録順)。 */
|
|
17
|
+
listPens(): FreedrawPenInfo[];
|
|
18
|
+
/** ペンの登録が変わったら呼ぶ。戻り値で解除。 */
|
|
19
|
+
onPensChange(listener: () => void): () => void;
|
|
20
|
+
}
|
|
21
|
+
/** 組み込み + 登録済みのペンの一覧。 */
|
|
22
|
+
export declare function listPens(): FreedrawPenInfo[];
|
|
23
|
+
export declare const freedrawApi: FreedrawApi;
|
|
24
|
+
/** freedraw の API のサービス。`setup` で provide する。 */
|
|
25
|
+
export declare const freedrawService: import("@edv4h/usketch-shared").ServiceHandle<FreedrawApi>;
|
|
26
|
+
/** ホスト用: `getFreedrawApi(app.services)?.listPens()`。freedraw が無ければ `undefined`。 */
|
|
27
|
+
export declare function getFreedrawApi(services: ServiceRegistry): FreedrawApi | undefined;
|
|
28
|
+
//# sourceMappingURL=freedraw-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freedraw-service.d.ts","sourceRoot":"","sources":["../src/freedraw-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEvF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,6BAA6B;AAC7B,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,aAAa;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB;IAChB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC3B,kCAAkC;IAClC,QAAQ,IAAI,eAAe,EAAE,CAAC;IAC9B,4BAA4B;IAC5B,YAAY,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC/C;AAED,yBAAyB;AACzB,wBAAgB,QAAQ,IAAI,eAAe,EAAE,CAiB5C;AAED,eAAO,MAAM,WAAW,EAAE,WAAwC,CAAC;AAEnE,iDAAiD;AACjD,eAAO,MAAM,eAAe,4DAA8D,CAAC;AAE3F,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,WAAW,GAAG,SAAS,CAEjF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// freedraw のホスト向け API(`ctx.services`)。ペンの一覧を読む(ペンを足すのは
|
|
2
|
+
// `createFreedrawPlugin(config, { pens })`)。
|
|
3
|
+
import { defineService } from "@edv4h/usketch-shared";
|
|
4
|
+
import { listPenDefinitions, onPensChange } from "./custom-pens.js";
|
|
5
|
+
import { PEN_KINDS, PEN_META } from "./pen-meta.js";
|
|
6
|
+
/** 組み込み + 登録済みのペンの一覧。 */
|
|
7
|
+
export function listPens() {
|
|
8
|
+
const builtIn = PEN_KINDS.map((id) => ({
|
|
9
|
+
id,
|
|
10
|
+
label: PEN_META[id].label,
|
|
11
|
+
defaultSize: PEN_META[id].defaultSize,
|
|
12
|
+
usesColor: true,
|
|
13
|
+
builtIn: true,
|
|
14
|
+
}));
|
|
15
|
+
const custom = listPenDefinitions().map((d) => ({
|
|
16
|
+
id: d.id,
|
|
17
|
+
label: d.label,
|
|
18
|
+
defaultSize: d.defaultSize,
|
|
19
|
+
...(d.sizeRange ? { sizeRange: d.sizeRange } : {}),
|
|
20
|
+
usesColor: d.usesColor !== false,
|
|
21
|
+
builtIn: false,
|
|
22
|
+
}));
|
|
23
|
+
return [...builtIn, ...custom];
|
|
24
|
+
}
|
|
25
|
+
export const freedrawApi = { listPens, onPensChange };
|
|
26
|
+
/** freedraw の API のサービス。`setup` で provide する。 */
|
|
27
|
+
export const freedrawService = defineService("usketch-plugin-shape-freedraw");
|
|
28
|
+
/** ホスト用: `getFreedrawApi(app.services)?.listPens()`。freedraw が無ければ `undefined`。 */
|
|
29
|
+
export function getFreedrawApi(services) {
|
|
30
|
+
return freedrawService.get(services);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=freedraw-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freedraw-service.js","sourceRoot":"","sources":["../src/freedraw-service.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,6CAA6C;AAC7C,OAAO,EAAE,aAAa,EAAwB,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAqB,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAsBpD,yBAAyB;AACzB,MAAM,UAAU,QAAQ;IACvB,MAAM,OAAO,GAAsB,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACzD,EAAE;QACF,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK;QACzB,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW;QACrC,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,IAAI;KACb,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAsB,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClE,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,SAAS,EAAE,CAAC,CAAC,SAAS,KAAK,KAAK;QAChC,OAAO,EAAE,KAAK;KACd,CAAC,CAAC,CAAC;IACJ,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAgB,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAEnE,iDAAiD;AACjD,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAc,+BAA+B,CAAC,CAAC;AAE3F,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,QAAyB;IACvD,OAAO,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC"}
|
package/dist/geometry/hit.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { BoundingBox, Point } from "@edv4h/usketch-shared";
|
|
2
|
-
import type { FreedrawShapeData } from "../types.js";
|
|
2
|
+
import type { FreedrawShapeData, PenId } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* ペンの最大半幅(world px)。外から足したペンは `halfWidth`(省略時 size/2)、
|
|
5
|
+
* 可変ペンは size×1.55/2、一定ペンは size/2。
|
|
6
|
+
*/
|
|
7
|
+
export declare function penHalfWidth(pen: PenId | undefined, size: number): number;
|
|
3
8
|
/** ストロークの最大半幅。 */
|
|
4
9
|
export declare function maxHalfWidth(data: FreedrawShapeData): number;
|
|
5
10
|
/** 点列 + 最大半幅で bbox を算出(細い線でも掴める)。 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hit.d.ts","sourceRoot":"","sources":["../../src/geometry/hit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"hit.d.ts","sourceRoot":"","sources":["../../src/geometry/hit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAe,MAAM,aAAa,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,KAAK,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIzE;AAgBD,kBAAkB;AAClB,wBAAgB,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAE5D;AAED,qCAAqC;AACrC,wBAAgB,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW,CAsBjE;AAoED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,SAAI,GAAG,OAAO,CAuBvF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAcrF"}
|
package/dist/geometry/hit.js
CHANGED
|
@@ -1,20 +1,31 @@
|
|
|
1
|
+
import { getPenDefinition } from "../custom-pens.js";
|
|
1
2
|
import { penMeta } from "../pen-meta.js";
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return
|
|
3
|
+
/**
|
|
4
|
+
* ペンの最大半幅(world px)。外から足したペンは `halfWidth`(省略時 size/2)、
|
|
5
|
+
* 可変ペンは size×1.55/2、一定ペンは size/2。
|
|
6
|
+
*/
|
|
7
|
+
export function penHalfWidth(pen, size) {
|
|
8
|
+
const custom = getPenDefinition(pen);
|
|
9
|
+
if (custom)
|
|
10
|
+
return custom.halfWidth ? custom.halfWidth(size) : size / 2;
|
|
11
|
+
return penMeta(pen).variable ? (size * 1.55) / 2 : size / 2;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 点ごとの実効半幅(world px)を返す関数。可変ペンは p×size、それ以外は点によらず一定。
|
|
15
|
+
* ペンの解決はストロークごとに 1 回だけにする(点のループの外で呼ぶ)。
|
|
16
|
+
*/
|
|
17
|
+
function halfWidthFn(pen, size) {
|
|
18
|
+
if (getPenDefinition(pen) || !penMeta(pen).variable) {
|
|
19
|
+
const half = penHalfWidth(pen, size);
|
|
20
|
+
return () => half;
|
|
10
21
|
}
|
|
11
|
-
|
|
22
|
+
const min = Math.max(0.6, size * 0.22);
|
|
23
|
+
const max = size * 1.55;
|
|
24
|
+
return (pt) => (min + (max - min) * (pt.p ?? 0.5)) / 2;
|
|
12
25
|
}
|
|
13
26
|
/** ストロークの最大半幅。 */
|
|
14
27
|
export function maxHalfWidth(data) {
|
|
15
|
-
|
|
16
|
-
const m = penMeta(data.pen);
|
|
17
|
-
return m.variable ? (size * 1.55) / 2 : size / 2;
|
|
28
|
+
return penHalfWidth(data.pen, data.style?.strokeWidth ?? 1);
|
|
18
29
|
}
|
|
19
30
|
/** 点列 + 最大半幅で bbox を算出(細い線でも掴める)。 */
|
|
20
31
|
export function strokeBounds(data) {
|
|
@@ -44,6 +55,50 @@ export function strokeBounds(data) {
|
|
|
44
55
|
height: maxY - minY + pad * 2,
|
|
45
56
|
};
|
|
46
57
|
}
|
|
58
|
+
// ストアは未変更の shape のオブジェクト参照を保つ(更新は新オブジェクトに差し替え)ので、
|
|
59
|
+
// shape 参照をキーにすれば、ホバーや消しゴムのドラッグ中に同じストロークの範囲を作り直さずに済む。
|
|
60
|
+
const strokeReachCache = new WeakMap();
|
|
61
|
+
/** {@link StrokeReach} をキャッシュ付きで返す。点が無ければ null。 */
|
|
62
|
+
function strokeReach(data) {
|
|
63
|
+
const cached = strokeReachCache.get(data);
|
|
64
|
+
if (cached !== undefined)
|
|
65
|
+
return cached;
|
|
66
|
+
const points = data.points ?? [];
|
|
67
|
+
const size = data.style?.strokeWidth ?? 1;
|
|
68
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
69
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
70
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
71
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
72
|
+
let maxHalf = 0;
|
|
73
|
+
const halfWidthAt = halfWidthFn(data.pen, size);
|
|
74
|
+
for (const pt of points) {
|
|
75
|
+
if (pt.x < minX)
|
|
76
|
+
minX = pt.x;
|
|
77
|
+
if (pt.y < minY)
|
|
78
|
+
minY = pt.y;
|
|
79
|
+
if (pt.x > maxX)
|
|
80
|
+
maxX = pt.x;
|
|
81
|
+
if (pt.y > maxY)
|
|
82
|
+
maxY = pt.y;
|
|
83
|
+
const half = halfWidthAt(pt);
|
|
84
|
+
if (half > maxHalf)
|
|
85
|
+
maxHalf = half;
|
|
86
|
+
}
|
|
87
|
+
const reach = points.length === 0
|
|
88
|
+
? null
|
|
89
|
+
: { minX: minX - maxHalf, minY: minY - maxHalf, maxX: maxX + maxHalf, maxY: maxY + maxHalf };
|
|
90
|
+
strokeReachCache.set(data, reach);
|
|
91
|
+
return reach;
|
|
92
|
+
}
|
|
93
|
+
/** `point` が {@link StrokeReach} を `margin` だけ広げた箱の外にあれば true(点が無いときも true)。 */
|
|
94
|
+
function outsideReach(data, point, margin) {
|
|
95
|
+
const reach = strokeReach(data);
|
|
96
|
+
return (reach === null ||
|
|
97
|
+
point.x < reach.minX - margin ||
|
|
98
|
+
point.x > reach.maxX + margin ||
|
|
99
|
+
point.y < reach.minY - margin ||
|
|
100
|
+
point.y > reach.maxY + margin);
|
|
101
|
+
}
|
|
47
102
|
/** 点 p から線分 ab までの距離の2乗。 */
|
|
48
103
|
function distToSegment2(p, a, b) {
|
|
49
104
|
const dx = b.x - a.x;
|
|
@@ -66,8 +121,14 @@ export function hitStroke(data, point, tolerance = 2) {
|
|
|
66
121
|
const size = data.style?.strokeWidth ?? 1;
|
|
67
122
|
if (points.length === 0)
|
|
68
123
|
return false;
|
|
124
|
+
// ホバーは毎 pointermove で盤面の全ストロークに対して呼ばれる。線分ごとの判定半径
|
|
125
|
+
// (両端の半幅の大きい方 + tolerance)は「点の範囲を最大半幅で広げた箱」を tolerance だけ
|
|
126
|
+
// 広げた外には届かないので、箱の外なら線分を調べずに false を返す。
|
|
127
|
+
if (outsideReach(data, point, tolerance))
|
|
128
|
+
return false;
|
|
129
|
+
const halfWidthAt = halfWidthFn(data.pen, size);
|
|
69
130
|
if (points.length === 1) {
|
|
70
|
-
const r = halfWidthAt(points[0]
|
|
131
|
+
const r = halfWidthAt(points[0]) + tolerance;
|
|
71
132
|
const dx = point.x - points[0].x;
|
|
72
133
|
const dy = point.y - points[0].y;
|
|
73
134
|
return dx * dx + dy * dy <= r * r;
|
|
@@ -75,7 +136,7 @@ export function hitStroke(data, point, tolerance = 2) {
|
|
|
75
136
|
for (let i = 1; i < points.length; i++) {
|
|
76
137
|
const a = points[i - 1];
|
|
77
138
|
const b = points[i];
|
|
78
|
-
const half = Math.max(halfWidthAt(a
|
|
139
|
+
const half = Math.max(halfWidthAt(a), halfWidthAt(b));
|
|
79
140
|
const r = half + tolerance;
|
|
80
141
|
if (distToSegment2(point, a, b) <= r * r)
|
|
81
142
|
return true;
|
|
@@ -88,9 +149,14 @@ export function hitStroke(data, point, tolerance = 2) {
|
|
|
88
149
|
*/
|
|
89
150
|
export function eraserHits(data, cursor, r) {
|
|
90
151
|
const points = data.points ?? [];
|
|
152
|
+
// 点ごとの判定 |pt − cursor| ≤ r + half は、各軸で |pt − cursor| ≤ r + half を含意する。
|
|
153
|
+
// 箱(点の範囲を最大半幅で広げたもの)を r だけ広げた外にカーソルがあれば、どの点も当たらない。
|
|
154
|
+
if (outsideReach(data, cursor, r))
|
|
155
|
+
return false;
|
|
91
156
|
const size = data.style?.strokeWidth ?? 1;
|
|
157
|
+
const halfWidthAt = halfWidthFn(data.pen, size);
|
|
92
158
|
for (const pt of points) {
|
|
93
|
-
const half = halfWidthAt(pt
|
|
159
|
+
const half = halfWidthAt(pt);
|
|
94
160
|
const dx = pt.x - cursor.x;
|
|
95
161
|
const dy = pt.y - cursor.y;
|
|
96
162
|
if (Math.hypot(dx, dy) <= r + half)
|