Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e104eff
add wireframe
MinCrohn Jul 23, 2025
172a8a0
add transformer
MinCrohn Jul 23, 2025
a15d14c
export Transformer
MinCrohn Jul 24, 2025
28237fc
add getter/setter
MinCrohn Jul 24, 2025
8de9ecc
chore
MinCrohn Jul 24, 2025
01c4d1d
fix Transformer
MinCrohn Jul 24, 2025
db4a3fd
chore
MinCrohn Jul 24, 2025
8f94c63
fix
MinCrohn Jul 24, 2025
5ce9ddd
fix getViewport
MinCrohn Jul 24, 2025
50a7a4c
fix event
MinCrohn Jul 24, 2025
49408df
Merge branch 'v0.3.x' into feat/add-transformer
MinCrohn Jul 24, 2025
7d6e375
trigger viewport zoomed
MinCrohn Jul 24, 2025
9609aac
delete lazyMode
MinCrohn Jul 24, 2025
0eee6cb
fix
MinCrohn Jul 24, 2025
36cbaaf
fix relative transform
MinCrohn Aug 12, 2025
9c337bc
temp
MinCrohn Aug 12, 2025
52ed9fc
fix
MinCrohn Aug 12, 2025
88d3562
add SelectionState
MinCrohn Aug 12, 2025
36a7ec9
add TransformState
MinCrohn Aug 12, 2025
4d93cd0
fix
MinCrohn Aug 13, 2025
9a0969c
fix
MinCrohn Aug 14, 2025
a4c3129
delete hitarea
MinCrohn Aug 14, 2025
1b1ef1e
fix
MinCrohn Aug 14, 2025
4a13cb6
add propagate event
MinCrohn Aug 14, 2025
52c7426
fix test
MinCrohn Aug 14, 2025
2084399
docs
MinCrohn Aug 14, 2025
dd8630f
fix
MinCrohn Aug 14, 2025
69708c6
fix
MinCrohn Aug 14, 2025
4bd54a4
add selectionState onpointerover event
MinCrohn Aug 14, 2025
a04137c
fix mouse-edges
MinCrohn Aug 14, 2025
1034535
fix SelectionState
MinCrohn Aug 14, 2025
c03fa45
chore
MinCrohn Aug 14, 2025
3c63151
fix
MinCrohn Aug 14, 2025
e0da6b8
rename
MinCrohn Aug 18, 2025
02dc0ce
add Transformer jsdoc
MinCrohn Aug 18, 2025
8d0bcc0
fix
MinCrohn Aug 18, 2025
5801536
fix
MinCrohn Aug 18, 2025
480dc44
add Wireframe jsdoc
MinCrohn Aug 18, 2025
8535fd3
chore
MinCrohn Aug 18, 2025
a06e9b8
add State jsdoc
MinCrohn Aug 18, 2025
497f0b5
add StateManager jsdoc
MinCrohn Aug 18, 2025
670cb06
chore
MinCrohn Aug 18, 2025
383adf2
add Transformer test
MinCrohn Aug 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 148 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ Therefore, to use this, an understanding of the following two libraries is essen
- [focus(ids)](#focusids)
- [fit(ids)](#fitids)
- [selector(path)](#selectorpath)
- [select(options)](#selectoptions)
- [stateManager](#statemanager)
- [SelectionState](#selectionstate)
- [Transformer](#transformer)
- [undoRedoManager](#undoredomanager)
- [execute(command, options)](#executecommand-options)
- [undo()](#undo)
Expand Down Expand Up @@ -400,43 +402,166 @@ Object explorer following [jsonpath](https://github.com/JSONPath-Plus/JSONPath)
const result = patchmap.selector('$..[?(@.label=="group-label-1")]')
```

### `stateManager`
A `StateManager` instance that manages the event state of the `patchmap` instance. You can define your own states by extending the `State` class and register them with the `stateManager`. This allows for systematic management of complex user interactions.

When `patchmap.draw()` is executed, a `SelectionState` named `selection` is registered by default.

```js
// Activates the 'selection' state to use object selection and drag-selection features.
patchmap.stateManager.setState('selection', {
draggable: true,
selectUnit: 'grid',
filter: (obj) => obj.type !== 'relations',
onSelect: (obj, event) => {
console.log('Selected:', obj);
// Assign the selected object to the transformer
if (patchmap.transformer) {
patchmap.transformer.elements = obj;
}
},
onDragSelect: (objs, event) => {
console.log('Drag Selected:', objs);
if (patchmap.transformer) {
patchmap.transformer.elements = objs;
}
},
});
```

#### Creating Custom States

You can create a new state class by extending `State` and use it by registering it with the `stateManager`.

```js
import { State, PROPAGATE_EVENT } from '@conalog/patch-map';

// 1. Define a new state class
class CustomState extends State {
// Define the events this state will handle as a static property.
static handledEvents = ['onpointerdown', 'onkeydown'];

enter(context, customOptions) {
super.enter(context);
console.log('CustomState has started.', customOptions);
}

exit() {
console.log('CustomState has ended.');
super.exit();
}

onpointerdown(event) {
console.log('Pointer down in CustomState');
// Handle the event here and stop its propagation.
}

onkeydown(event) {
if (event.key === 'Escape') {
// Switch to the 'selection' state (the default state).
this.context.stateManager.setState('selection');
}
// Return PROPAGATE_EVENT to propagate the event to the next state in the stack.
return PROPAGATE_EVENT;
}
}

// 2. Register with the StateManager
patchmap.stateManager.register('custom', CustomState);

// 3. Switch states when needed
patchmap.stateManager.setState('custom', { message: 'Hello World' });
```

<br/>

### `select(options)`
The selection event is activated to detect objects that the user selects on the screen and pass them to a callback function.
This should be executed after the `draw` method.
- `enabled` (optional, boolean): Determines whether the selection event is enabled.
- `draggable` (optional, boolean): Determines whether dragging is enabled.
- `selectUnit` (optional, string): Specifies the logical unit to return when selecting. The default is `'entity'`.
- `'entity'`: Selects individual objects.
- `'closestGroup'`: Selects the closest parent group of the selected object.
- `'highestGroup'`: Selects the highest-level group of the selected object.
### `SelectionState`

The default state that handles user selection and drag events. It is automatically registered with the `stateManager` under the name 'selection' when `patchmap.draw()` is executed. You can activate it and pass configuration by calling `stateManager.setState('selection', options)`.

- `draggable` (optional, boolean): Determines whether to enable multi-selection via dragging.
- `selectUnit` (optional, string): Specifies the logical unit to be returned upon selection. The default is `'entity'`.
- `'entity'`: Selects the individual object.
- `'closestGroup'`: Selects the nearest parent group of the selected object.
- `'highestGroup'`: Selects the topmost parent group of the selected object.
- `'grid'`: Selects the grid to which the selected object belongs.
- `filter` (optional, function): A function that filters the target objects based on specific conditions.
- `onSelect` (optional, function): The callback function that is called when a selection occurs.
- `onOver` (optional, function): The callback function that is called when a pointer-over event occurs.
- `onDragSelect` (optional, function): The callback function that is called when a drag event occurs.
- `filter` (optional, function): A function to filter selectable objects based on a condition.
- `onSelect` (optional, function): A callback function invoked when an object is selected via a single click. It receives the selected object and the event object as arguments.
- `onDragSelect` (optional, function): A callback function invoked when multiple objects are selected via dragging. It receives an array of selected objects and the event object as arguments.
- `selectionBoxStyle` (optional, object): Specifies the style of the selection box displayed during drag-selection.
- `fill` (object): The fill style. Default: `{ color: '#9FD6FF', alpha: 0.2 }`.
- `stroke` (object): The stroke style. Default: `{ width: 2, color: '#1099FF' }`.

```js
patchmap.select({
enabled: true,
patchmap.stateManager.setState('selection', {
draggable: true,
selectUnit: 'grid',
filter: (obj) => obj.type !== 'relations',
onSelect: (obj) => {
console.log(obj);
onSelect: (obj, event) => {
console.log('Selected:', obj);
// Assign the selected object to the transformer
if (patchmap.transformer) {
patchmap.transformer.elements = obj;
}
},
onOver: (obj) => {
console.log(obj);
onDragSelect: (objs, event) => {
console.log('Drag Selected:', objs);
if (patchmap.transformer) {
patchmap.transformer.elements = objs;
}
},
onDragSelect: (objs) => {
console.log(objs);
}
});
```

<br/>

### `Transformer`

A visual tool for displaying an outline around selected elements and performing transformations such as resizing or rotating. It is activated by creating a `Transformer` instance and assigning it to `patchmap.transformer`.

#### new Transformer(options)

You can control the behavior by passing the following options when creating a `Transformer` instance.

- `elements` (optional, Array<PIXI.DisplayObject>): An array of elements to display an outline for initially.
- `wireframeStyle` (optional, object): Specifies the style of the outline.
- `thickness` (number): The thickness of the line (default: `1.5`).
- `color` (string): The color of the line (default: `'#1099FF'`).
- `boundsDisplayMode` (optional, string): Determines the unit for displaying the outline (default: `'all'`).
- `'all'`: Displays both the overall outline of a group and the outlines of individual elements within it.
- `'groupOnly'`: Displays only the overall outline of the group.
- `'elementOnly'`: Displays only the outlines of individual elements within the group.
- `'none'`: Does not display any outline.

<!-- end list -->

```js
import { Patchmap, Transformer } from '@conalog/patch-map';

const patchmap = new Patchmap();
await patchmap.init(element);
patchmap.draw(data);

// 1. Create and assign a Transformer instance
const transformer = new Transformer({
wireframeStyle: {
thickness: 2,
color: '#FF00FF',
},
boundsDisplayMode: 'groupOnly',
});
patchmap.transformer = transformer;

// 2. Assign the selected object to the transformer's elements property to display the outline
const selectedObject = patchmap.selector('$..[?(@.id=="group-id-1")]')[0];
patchmap.transformer.elements = [selectedObject];

// To deselect
patchmap.transformer.elements = [];
```

<br/>

## undoRedoManager
An instance of the `UndoRedoManager` class. This manager records executed commands, allowing for undo and redo functionality.

Expand Down
163 changes: 144 additions & 19 deletions README_KR.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ PATCH MAP์€ PATCH ์„œ๋น„์Šค์˜ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑ์‹œํ‚ค๊ธฐ ์œ„ํ•ด `pixi.js
- [focus(ids)](#focusids)
- [fit(ids)](#fitids)
- [selector(path)](#selectorpath)
- [select(options)](#selectoptions)
- [stateManager](#statemanager)
- [SelectionState](#selectionstate)
- [Transformer](#transformer)
- [undoRedoManager](#undoredomanager)
- [execute(command, options)](#executecommand-options)
- [undo()](#undo)
Expand Down Expand Up @@ -401,41 +403,164 @@ const result = patchmap.selector('$..[?(@.label=="group-label-1")]')

<br/>

### `select(options)`
์„ ํƒ ์ด๋ฒคํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•˜์—ฌ, ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ์„ ํƒํ•œ ๊ฐ์ฒด๋“ค์„ ๊ฐ์ง€ํ•˜๊ณ  ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
`draw` ๋ฉ”์†Œ๋“œ ์ดํ›„์— ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
- `enabled` (optional, boolean): ์„ ํƒ ์ด๋ฒคํŠธ์˜ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
- `draggable` (optional, boolean): ๋“œ๋ž˜๊ทธ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
- `selectUnit` (optional, string): ์„ ํƒ ์‹œ ๋ฐ˜ํ™˜๋  ๋…ผ๋ฆฌ์  ๋‹จ์œ„๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ 'entity' ์ž…๋‹ˆ๋‹ค.
### `stateManager`

`patchmap` ์ธ์Šคํ„ด์Šค์˜ ์ด๋ฒคํŠธ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” `StateManager` ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. `State` ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ์ž์‹ ๋งŒ์˜ ์ƒํƒœ๋ฅผ ์ •์˜ํ•˜๊ณ , `stateManager`์— ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ๋ณต์žกํ•œ ์ธํ„ฐ๋ž™์…˜์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

`patchmap.draw()`๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ `selection`์ด๋ผ๋Š” ์ด๋ฆ„์˜ `SelectionState`๊ฐ€ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.

```js
// selection ์ƒํƒœ๋ฅผ ํ™œ์„ฑํ™”ํ•˜์—ฌ ๊ฐ์ฒด ์„ ํƒ ๋ฐ ๋“œ๋ž˜๊ทธ ์„ ํƒ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
patchmap.stateManager.setState('selection', {
draggable: true,
selectUnit: 'grid',
filter: (obj) => obj.type !== 'relations',
onSelect: (obj, event) => {
console.log('Selected:', obj);
// ์„ ํƒ๋œ ๊ฐ์ฒด๋ฅผ transformer์— ํ• ๋‹น
if (patchmap.transformer) {
patchmap.transformer.elements = obj;
}
},
onDragSelect: (objs, event) => {
console.log('Drag Selected:', objs);
if (patchmap.transformer) {
patchmap.transformer.elements = objs;
}
},
});
```

#### ์‚ฌ์šฉ์ž ์ •์˜ ์ƒํƒœ ๋งŒ๋“ค๊ธฐ

`State`๋ฅผ ์ƒ์†ํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ƒํƒœ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , `stateManager`์— ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

```js
import { State, PROPAGATE_EVENT } from '@conalog/patch-map';

// 1. ์ƒˆ๋กœ์šด ์ƒํƒœ ํด๋ž˜์Šค ์ •์˜
class CustomState extends State {
// ์ด ์ƒํƒœ๊ฐ€ ์ฒ˜๋ฆฌํ•  ์ด๋ฒคํŠธ๋ฅผ static ์†์„ฑ์œผ๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
static handledEvents = ['onpointerdown', 'onkeydown'];

enter(context, customOptions) {
super.enter(context);
console.log('CustomState๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.', customOptions);
}

exit() {
console.log('CustomState๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
super.exit();
}

onpointerdown(event) {
console.log('Pointer down in CustomState');
// ์ด๋ฒคํŠธ๋ฅผ ์—ฌ๊ธฐ์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ „ํŒŒ๋ฅผ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค.
}

onkeydown(event) {
if (event.key === 'Escape') {
// 'selection' ์ƒํƒœ(๊ธฐ๋ณธ ์ƒํƒœ)๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
this.context.stateManager.setState('selection');
}
// ์ด๋ฒคํŠธ๋ฅผ ์Šคํƒ์˜ ๋‹ค์Œ ์ƒํƒœ๋กœ ์ „ํŒŒํ•˜๋ ค๋ฉด PROPAGATE_EVENT๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
return PROPAGATE_EVENT;
}
}

// 2. StateManager์— ๋“ฑ๋ก
patchmap.stateManager.register('custom', CustomState);

// 3. ํ•„์š”ํ•  ๋•Œ ์ƒํƒœ ์ „ํ™˜
patchmap.stateManager.setState('custom', { message: 'Hello World' });
```

<br/>

### `SelectionState`
์‚ฌ์šฉ์ž์˜ ์„ ํƒ ๋ฐ ๋“œ๋ž˜๊ทธ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋ณธ ์ƒํƒœ(State)์ž…๋‹ˆ๋‹ค. `patchmap.draw()`๊ฐ€ ์‹คํ–‰๋˜๋ฉด 'selection'์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ `stateManager`์— ์ž๋™์œผ๋กœ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค. `stateManager.setState('selection', options)`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ™œ์„ฑํ™”ํ•˜๊ณ  ์„ค์ •์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- `draggable` (optional, boolean): ๋“œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•œ ๋‹ค์ค‘ ์„ ํƒ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
- `selectUnit` (optional, string): ์„ ํƒ ์‹œ ๋ฐ˜ํ™˜๋  ๋…ผ๋ฆฌ์  ๋‹จ์œ„๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ `'entity'` ์ž…๋‹ˆ๋‹ค.
- `'entity'`: ๊ฐœ๋ณ„ ๊ฐ์ฒด๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
- `'closestGroup'`: ์„ ํƒ๋œ ๊ฐ์ฒด์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ƒ์œ„ ๊ทธ๋ฃน์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
- `'highestGroup'`: ์„ ํƒ๋œ ๊ฐ์ฒด์—์„œ ๊ฐ€์žฅ ์ตœ์ƒ์œ„ ๊ทธ๋ฃน์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
- `'grid'`: ์„ ํƒ๋œ ๊ฐ์ฒด๊ฐ€ ์†ํ•œ ๊ทธ๋ฆฌ๋“œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
- `filter` (optional, function): ์„ ํƒ ๋Œ€์ƒ ๊ฐ์ฒด๋ฅผ ์กฐ๊ฑด์— ๋”ฐ๋ผ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
- `onSelect` (optional, function): ์„ ํƒ์ด ๋ฐœ์ƒํ•  ๋•Œ ํ˜ธ์ถœ๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
- `onOver` (optional, function): ํฌ์ธํ„ฐ ์˜ค๋ฒ„๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ํ˜ธ์ถœ๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
- `onDragSelect` (optional, function): ๋“œ๋ž˜๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ํ˜ธ์ถœ๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
- `onSelect` (optional, function): ๋‹จ์ผ ํด๋ฆญ์œผ๋กœ ๊ฐ์ฒด ์„ ํƒ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์„ ํƒ๋œ ๊ฐ์ฒด์™€ ์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
- `onDragSelect` (optional, function): ๋“œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•ด ๋‹ค์ˆ˜์˜ ๊ฐ์ฒด๊ฐ€ ์„ ํƒ๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœ๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์„ ํƒ๋œ ๊ฐ์ฒด ๋ฐฐ์—ด๊ณผ ์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
- `selectionBoxStyle` (optional, object): ๋“œ๋ž˜๊ทธ ์„ ํƒ ์‹œ ํ‘œ์‹œ๋˜๋Š” ์‚ฌ๊ฐํ˜•์˜ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
- `fill` (object): ์ฑ„์šฐ๊ธฐ ์Šคํƒ€์ผ. ๊ธฐ๋ณธ๊ฐ’: `{ color: '#9FD6FF', alpha: 0.2 }`.
- `stroke` (object): ํ…Œ๋‘๋ฆฌ ์Šคํƒ€์ผ. ๊ธฐ๋ณธ๊ฐ’: `{ width: 2, color: '#1099FF' }`.

```js
patchmap.select({
enabled: true,
patchmap.stateManager.setState('selection', {
draggable: true,
selectUnit: 'grid',
filter: (obj) => obj.type !== 'relations',
onSelect: (obj) => {
console.log(obj);
onSelect: (obj, event) => {
console.log('Selected:', obj);
// ์„ ํƒ๋œ ๊ฐ์ฒด๋ฅผ transformer์— ํ• ๋‹น
if (patchmap.transformer) {
patchmap.transformer.elements = obj;
}
},
onOver: (obj) => {
console.log(obj);
onDragSelect: (objs, event) => {
console.log('Drag Selected:', objs);
if (patchmap.transformer) {
patchmap.transformer.elements = objs;
}
},
onDragSelect: (objs) => {
console.log(objs);
}
});
```

<br/>

### `Transformer`

์„ ํƒ๋œ ์š”์†Œ์˜ ์™ธ๊ณฝ์„ ์„ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๊ณ , ํฌ๊ธฐ ์กฐ์ ˆ์ด๋‚˜ ํšŒ์ „๊ณผ ๊ฐ™์€ ๋ณ€ํ˜• ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์‹œ๊ฐ์  ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. `Transformer` ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ `patchmap.transformer`์— ํ• ๋‹นํ•˜๋ฉด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

#### new Transformer(options)

`Transformer` ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ต์…˜์„ ์ „๋‹ฌํ•˜์—ฌ ๋™์ž‘์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- `elements` (optional, Array<PIXI.DisplayObject>): ์ดˆ๊ธฐ์— ์™ธ๊ณฝ์„ ์„ ํ‘œ์‹œํ•  ์š”์†Œ๋“ค์˜ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค.
- `wireframeStyle` (optional, object): ์™ธ๊ณฝ์„ ์˜ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
- `thickness` (number): ์„ ์˜ ๋‘๊ป˜ (๊ธฐ๋ณธ๊ฐ’: `1.5`).
- `color` (string): ์„ ์˜ ์ƒ‰์ƒ (๊ธฐ๋ณธ๊ฐ’: `'#1099FF'`).
- `boundsDisplayMode` (optional, string): ์™ธ๊ณฝ์„ ์„ ํ‘œ์‹œํ•  ๋‹จ์œ„๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค (๊ธฐ๋ณธ๊ฐ’: `'all'`).
- `'all'`: ๊ทธ๋ฃน์˜ ์ „์ฒด ์™ธ๊ณฝ์„ ๊ณผ ๊ทธ๋ฃน ๋‚ด ๊ฐœ๋ณ„ ์š”์†Œ์˜ ์™ธ๊ณฝ์„ ์„ ๋ชจ๋‘ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
- `'groupOnly'`: ๊ทธ๋ฃน์˜ ์ „์ฒด ์™ธ๊ณฝ์„ ๋งŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
- `'elementOnly'`: ๊ทธ๋ฃน ๋‚ด ๊ฐœ๋ณ„ ์š”์†Œ์˜ ์™ธ๊ณฝ์„ ๋งŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
- `'none'`: ์™ธ๊ณฝ์„ ์„ ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

```js
import { Patchmap, Transformer } from '@conalog/patch-map';

const patchmap = new Patchmap();
await patchmap.init(element);
patchmap.draw(data);

// 1. Transformer ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฐ ํ• ๋‹น
const transformer = new Transformer({
wireframeStyle: {
thickness: 2,
color: '#FF00FF',
},
boundsDisplayMode: 'groupOnly',
});
patchmap.transformer = transformer;

// 2. ์„ ํƒ๋œ ๊ฐ์ฒด๋ฅผ transformer์˜ elements ์†์„ฑ์— ํ• ๋‹นํ•˜์—ฌ ์™ธ๊ณฝ์„  ํ‘œ์‹œ
const selectedObject = patchmap.selector('$..[?(@.id=="group-id-1")]')[0];
patchmap.transformer.elements = [selectedObject];

// ์„ ํƒ ํ•ด์ œ ์‹œ
patchmap.transformer.elements = [];
```

<br/>

## undoRedoManager
`UndoRedoManager` ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. ์ด ๋งค๋‹ˆ์ €๋Š” ์‹คํ–‰๋œ ๋ช…๋ น์„ ๊ธฐ๋กํ•˜๊ณ , ์ด๋ฅผ ํ†ตํ•ด ์‹คํ–‰ ์ทจ์†Œ(undo) ๋ฐ ์žฌ์‹คํ–‰(redo) ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Expand Down
Loading