@adecore/drawing 0.17.0-beta.1 → 0.17.0

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/LICENSE CHANGED
@@ -6,7 +6,7 @@ FSL-1.1-MIT
6
6
 
7
7
  ## Notice
8
8
 
9
- Copyright 2026 Bas Milius
9
+ Copyright 2026 - present Bas Milius
10
10
 
11
11
  ## Terms and Conditions
12
12
 
package/README.md CHANGED
@@ -1,42 +1,49 @@
1
1
  # @adecore/drawing
2
2
 
3
- Drawing schemas, world-coordinate geometry, deterministic paths, SVG export and reading order. The core needs no DOM or React canvas. Zod, Rough.js and perfect-freehand are declared dependencies.
3
+ [![npm](https://img.shields.io/npm/v/@adecore/drawing)](https://www.npmjs.com/package/@adecore/drawing)
4
+ [![Docs](https://img.shields.io/badge/docs-adecore.dev-blue)](https://adecore.dev/drawing/)
4
5
 
5
- The package is private at `0.0.0` pending initial publication. Use this checkout with the `source` condition or build compiled JavaScript/declarations in `dist`. The transferred code retains FSL-1.1-MIT in [LICENSE](./LICENSE); dependencies retain their own terms.
6
+ Hand-drawn shapes, arrows, freehand strokes, text and sticky notes as plain JSON, with hit tests and resizing for an editor, paths for a painter, an SVG export and a reading of a drawing as lines of text. It needs no DOM, so a backend exports a stored drawing the same way a page draws it.
7
+
8
+ **[Documentation with live demos](https://adecore.dev/drawing/)**
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ bun add @adecore/drawing
14
+ ```
15
+
16
+ ## Use
6
17
 
7
18
  ```ts
8
19
  import { DEFAULT_PALETTE, readingOrder, toSvg } from '@adecore/drawing';
9
- import { DrawingDocumentSchema, duplicateElementIdIn } from '@adecore/drawing/protocol';
10
-
11
- const document = DrawingDocumentSchema.parse({
12
- version: 1,
13
- rev: 0,
14
- elements: [
15
- {
16
- kind: 'note',
17
- id: 'note',
18
- x: 0,
19
- y: 0,
20
- w: 180,
21
- h: 100,
22
- stroke: 'ink',
23
- strokeWidth: 1,
24
- seed: 7,
25
- fillColor: 'yellow',
26
- text: 'Review the result',
27
- size: 20
28
- }
29
- ]
30
- });
31
- if (duplicateElementIdIn(document.elements) !== null) {
32
- throw new Error('Element ids must be unique');
20
+ import { duplicateElementIdIn, migrateDrawing } from '@adecore/drawing/protocol';
21
+
22
+ const drawing = migrateDrawing(JSON.parse(file));
23
+ if (drawing === null || duplicateElementIdIn(drawing.elements) !== null) {
24
+ throw new Error('Not a drawing');
33
25
  }
34
- const svg = toSvg(document.elements, { palette: DEFAULT_PALETTE });
35
- const lines = readingOrder(document.elements);
26
+
27
+ const svg = toSvg(drawing.elements, { palette: DEFAULT_PALETTE });
28
+ const lines = readingOrder(drawing.elements);
36
29
  ```
37
30
 
38
- The host owns persistence, revision checks, selection, gestures, fonts and theme resolution. Parsing does not check duplicate ids. Bounds use stored unrotated boxes; verify rotated SVG output and clipping as described in the rendering guide. Colors supplied through SVG options are trusted host values.
31
+ ## Entry points
32
+
33
+ | Import | What it holds |
34
+ |---|---|
35
+ | `@adecore/drawing` | Geometry, paths, SVG export, text and reading order |
36
+ | `@adecore/drawing/protocol` | The Zod schemas and types of a drawing; loads nothing else |
37
+
38
+ ## Documentation
39
+
40
+ | Page | What it covers |
41
+ |---|---|
42
+ | [Documents](https://adecore.dev/drawing/documents) | The document, the seven element kinds and reading a file |
43
+ | [Geometry](https://adecore.dev/drawing/geometry) | Bounds, hit tests, selection and resizing |
44
+ | [Paths and SVG](https://adecore.dev/drawing/rendering) | `toSvg` and the paths of one element for a painter of your own |
45
+ | [Text and reading order](https://adecore.dev/drawing/text) | Wrapping, measuring and `readingOrder` |
39
46
 
40
- Read the [overview](https://adecore.dev/drawing/), [getting started](https://adecore.dev/drawing/getting-started), [geometry guide](https://adecore.dev/drawing/geometry), [paths/SVG guide](https://adecore.dev/drawing/rendering), [text guide](https://adecore.dev/drawing/text), [API reference](https://adecore.dev/drawing/api), [protocol](https://adecore.dev/drawing/protocol) and [integration/testing guide](https://adecore.dev/drawing/migration).
47
+ ## License
41
48
 
42
- From the repository root, run `bun run --cwd packages/drawing test`, `typecheck` or `build`. The [standalone example](./examples/export-drawing.ts) exports one validated note. Rough.js uses its official package entry for compiled Node execution.
49
+ FSL-1.1-MIT, see [LICENSE](./LICENSE). Rough.js and perfect-freehand keep their own licenses.
package/dist/svg.js CHANGED
@@ -1,4 +1,4 @@
1
- import { boundsOfElements, centerOf, boundsOf } from './geometry.js';
1
+ import { boundsOfElements } from './geometry.js';
2
2
  import { pathsOfElement } from './paths.js';
3
3
  import { DEFAULT_FONT_STACKS, LINE_HEIGHT, approximateMeasure, fontOf, linesOf, writingFrameOf } from './text.js';
4
4
  export const DEFAULT_SVG_MARGIN = 32;
@@ -51,8 +51,8 @@ function round(value) {
51
51
  return Math.round(value * 100) / 100;
52
52
  }
53
53
  function transformOf(element) {
54
- const center = centerOf(boundsOf(element));
55
- const turn = element.angle ? ` rotate(${round((element.angle * 180) / Math.PI)} ${round(center.x)} ${round(center.y)})` : '';
54
+ // After the translate the paths are in the element's own frame, so its center is half its size.
55
+ const turn = element.angle ? ` rotate(${round((element.angle * 180) / Math.PI)} ${round(element.w / 2)} ${round(element.h / 2)})` : '';
56
56
  return `translate(${round(element.x)} ${round(element.y)})${turn}`;
57
57
  }
58
58
  function textSvg(element, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/drawing",
3
- "version": "0.17.0-beta.1",
3
+ "version": "0.17.0",
4
4
  "description": "Drawing schemas, geometry, deterministic paths, SVG export and reading order.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "author": "Bas Milius",
package/src/svg.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { DrawingColor, DrawingElement, DrawingFont } from './protocol.ts';
2
- import { boundsOfElements, centerOf, boundsOf, type Rect } from './geometry.ts';
2
+ import { boundsOfElements, type Rect } from './geometry.ts';
3
3
  import { pathsOfElement } from './paths.ts';
4
4
  import { DEFAULT_FONT_STACKS, LINE_HEIGHT, approximateMeasure, fontOf, linesOf, writingFrameOf, type MeasureLine, type WrittenElement } from './text.ts';
5
5
 
@@ -76,8 +76,8 @@ function round(value: number): number {
76
76
  }
77
77
 
78
78
  function transformOf(element: DrawingElement): string {
79
- const center = centerOf(boundsOf(element));
80
- const turn = element.angle ? ` rotate(${round((element.angle * 180) / Math.PI)} ${round(center.x)} ${round(center.y)})` : '';
79
+ // After the translate the paths are in the element's own frame, so its center is half its size.
80
+ const turn = element.angle ? ` rotate(${round((element.angle * 180) / Math.PI)} ${round(element.w / 2)} ${round(element.h / 2)})` : '';
81
81
  return `translate(${round(element.x)} ${round(element.y)})${turn}`;
82
82
  }
83
83