@plait/mind 0.16.0 → 0.18.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/base/image-base.component.d.ts +16 -0
- package/base/index.d.ts +1 -0
- package/constants/node-style.d.ts +9 -4
- package/drawer/node-image.drawer.d.ts +16 -0
- package/esm2020/base/image-base.component.mjs +28 -0
- package/esm2020/base/index.mjs +2 -1
- package/esm2020/constants/node-style.mjs +11 -6
- package/esm2020/drawer/node-active.drawer.mjs +10 -9
- package/esm2020/drawer/node-image.drawer.mjs +61 -0
- package/esm2020/interfaces/element-data.mjs +1 -1
- package/esm2020/interfaces/element.mjs +9 -1
- package/esm2020/interfaces/options.mjs +1 -1
- package/esm2020/node.component.mjs +12 -1
- package/esm2020/plugins/with-mind-image.mjs +49 -0
- package/esm2020/plugins/with-mind.mjs +4 -11
- package/esm2020/transforms/emoji.mjs +2 -2
- package/esm2020/transforms/image.mjs +10 -0
- package/esm2020/transforms/index.mjs +4 -2
- package/esm2020/transforms/node.mjs +2 -6
- package/esm2020/utils/draw/abstract-outline.mjs +44 -2
- package/esm2020/utils/draw/node-dnd.mjs +8 -1
- package/esm2020/utils/draw/node-link/logic-link.mjs +2 -2
- package/esm2020/utils/draw/node-shape.mjs +5 -5
- package/esm2020/utils/mind.mjs +2 -2
- package/esm2020/utils/node-style/shape.mjs +8 -4
- package/esm2020/utils/position/emoji.mjs +8 -8
- package/esm2020/utils/position/image.mjs +21 -0
- package/esm2020/utils/position/index.mjs +2 -1
- package/esm2020/utils/space/node-space.mjs +23 -5
- package/fesm2015/plait-mind.mjs +283 -42
- package/fesm2015/plait-mind.mjs.map +1 -1
- package/fesm2020/plait-mind.mjs +280 -42
- package/fesm2020/plait-mind.mjs.map +1 -1
- package/interfaces/element-data.d.ts +9 -0
- package/interfaces/element.d.ts +2 -1
- package/interfaces/options.d.ts +3 -1
- package/node.component.d.ts +3 -0
- package/package.json +1 -1
- package/plugins/with-mind-image.d.ts +2 -0
- package/transforms/image.d.ts +3 -0
- package/transforms/index.d.ts +1 -0
- package/utils/draw/abstract-outline.d.ts +2 -0
- package/utils/node-style/shape.d.ts +1 -0
- package/utils/position/emoji.d.ts +4 -4
- package/utils/position/image.d.ts +6 -0
- package/utils/position/index.d.ts +1 -0
- package/utils/space/node-space.d.ts +1 -0
package/fesm2020/plait-mind.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, ChangeDetectionStrategy, NgModule, NgZone,
|
|
2
|
+
import { Directive, Input, Component, ChangeDetectionStrategy, NgModule, NgZone, HostListener } from '@angular/core';
|
|
3
3
|
import * as i2 from '@plait/core';
|
|
4
|
-
import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Path, PlaitBoard, depthFirstRecursion, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject,
|
|
4
|
+
import { DefaultThemeColor, ColorfulThemeColor, SoftThemeColor, RetroThemeColor, DarkThemeColor, StarryThemeColor, RectangleClient, PlaitElement, idCreator, isNullOrUndefined, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Path, PlaitBoard, depthFirstRecursion, drawLinearPath, drawBezierPath, createG, updateForeignObject, drawRoundRectangle, getRectangleByElements, getSelectedElements, NODE_TO_PARENT, distanceBetweenPointAndRectangle, createForeignObject, createText, PlaitPointerType, PlaitPluginElementComponent, NODE_TO_INDEX, PlaitModule, transformPoint, toPoint, getHitElements, distanceBetweenPointAndPoint, CLIP_BOARD_FORMAT_KEY, isMainPointer, BOARD_TO_HOST, PlaitPluginKey, throttleRAF, BoardTransforms, removeSelectedElement, PlaitHistoryBoard, hotkeys } from '@plait/core';
|
|
5
5
|
import { MindLayoutType, isIndentedLayout, AbstractNode, getNonAbstractChildren, isStandardLayout, isLeftLayout, isRightLayout, isVerticalLogicLayout, isHorizontalLogicLayout, isTopLayout, isBottomLayout, isHorizontalLayout, getCorrectStartEnd, getAbstractLayout, ConnectingPosition, GlobalLayout } from '@plait/layouts';
|
|
6
6
|
import { TEXT_DEFAULT_HEIGHT, buildText, getTextSize, TextManage, ExitOrigin, TextModule, getTextFromClipboard } from '@plait/text';
|
|
7
7
|
import { fromEvent, Subject } from 'rxjs';
|
|
@@ -216,7 +216,9 @@ const NodeDefaultSpace = {
|
|
|
216
216
|
emojiAndText: BASE * 1.5
|
|
217
217
|
},
|
|
218
218
|
vertical: {
|
|
219
|
-
nodeAndText: BASE * 1.5
|
|
219
|
+
nodeAndText: BASE * 1.5,
|
|
220
|
+
nodeAndImage: BASE,
|
|
221
|
+
imageAndText: BASE * 1.5
|
|
220
222
|
}
|
|
221
223
|
};
|
|
222
224
|
const RootDefaultSpace = {
|
|
@@ -246,17 +248,25 @@ const getSpaceEmojiAndText = (element) => {
|
|
|
246
248
|
const NodeSpace = {
|
|
247
249
|
getNodeWidth(board, element) {
|
|
248
250
|
const nodeAndText = getHorizontalSpaceBetweenNodeAndText(board, element);
|
|
251
|
+
const imageWidth = MindElement.hasImage(element) ? element.data.image?.width : 0;
|
|
249
252
|
if (MindElement.hasEmojis(element)) {
|
|
250
253
|
return (NodeSpace.getEmojiLeftSpace(board, element) +
|
|
251
254
|
getEmojisWidthHeight(board, element).width +
|
|
252
255
|
getSpaceEmojiAndText(element) +
|
|
253
|
-
element.width +
|
|
256
|
+
Math.max(element.width, imageWidth) +
|
|
254
257
|
nodeAndText);
|
|
255
258
|
}
|
|
256
|
-
return nodeAndText + element.width + nodeAndText;
|
|
259
|
+
return nodeAndText + Math.max(element.width, imageWidth) + nodeAndText;
|
|
257
260
|
},
|
|
258
261
|
getNodeHeight(board, element) {
|
|
259
262
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
263
|
+
if (MindElement.hasImage(element)) {
|
|
264
|
+
return (NodeDefaultSpace.vertical.nodeAndImage +
|
|
265
|
+
element.data.image.height +
|
|
266
|
+
NodeDefaultSpace.vertical.imageAndText +
|
|
267
|
+
element.height +
|
|
268
|
+
nodeAndText);
|
|
269
|
+
}
|
|
260
270
|
return nodeAndText + element.height + nodeAndText;
|
|
261
271
|
},
|
|
262
272
|
getTextLeftSpace(board, element) {
|
|
@@ -270,7 +280,15 @@ const NodeSpace = {
|
|
|
270
280
|
},
|
|
271
281
|
getTextTopSpace(element) {
|
|
272
282
|
const nodeAndText = getVerticalSpaceBetweenNodeAndText(element);
|
|
273
|
-
|
|
283
|
+
if (MindElement.hasImage(element)) {
|
|
284
|
+
return element.data.image.height + NodeDefaultSpace.vertical.nodeAndImage + NodeDefaultSpace.vertical.imageAndText;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
return nodeAndText;
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
getImageTopSpace(element) {
|
|
291
|
+
return NodeDefaultSpace.vertical.nodeAndImage;
|
|
274
292
|
},
|
|
275
293
|
getEmojiLeftSpace(board, element) {
|
|
276
294
|
const options = board.getPluginOptions(WithMindPluginKey);
|
|
@@ -297,12 +315,12 @@ function getEmojiRectangle(board, element) {
|
|
|
297
315
|
function getEmojiForeignRectangle(board, element) {
|
|
298
316
|
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
299
317
|
x = x + NodeSpace.getEmojiLeftSpace(board, element);
|
|
300
|
-
const { width
|
|
318
|
+
const { width } = getEmojisWidthHeight(board, element);
|
|
301
319
|
return {
|
|
302
320
|
x,
|
|
303
321
|
y,
|
|
304
322
|
width,
|
|
305
|
-
height:
|
|
323
|
+
height: NodeSpace.getNodeHeight(board, element)
|
|
306
324
|
};
|
|
307
325
|
}
|
|
308
326
|
const isHitEmojis = (board, element, point) => {
|
|
@@ -324,6 +342,23 @@ function getTopicRectangleByElement(board, nodeRectangle, element) {
|
|
|
324
342
|
return { height, width, x, y };
|
|
325
343
|
}
|
|
326
344
|
|
|
345
|
+
function getImageForeignRectangle(board, element) {
|
|
346
|
+
let { x, y } = getRectangleByNode(MindElement.getNode(element));
|
|
347
|
+
x = x + NodeSpace.getTextLeftSpace(board, element);
|
|
348
|
+
y = NodeSpace.getImageTopSpace(element) + y;
|
|
349
|
+
const { width, height } = element.data.image;
|
|
350
|
+
return {
|
|
351
|
+
x,
|
|
352
|
+
y,
|
|
353
|
+
width,
|
|
354
|
+
height
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
const isHitImage = (board, element, range) => {
|
|
358
|
+
const client = getImageForeignRectangle(board, element);
|
|
359
|
+
return RectangleClient.isHit(RectangleClient.toRectangleClient([range.anchor, range.focus]), client);
|
|
360
|
+
};
|
|
361
|
+
|
|
327
362
|
const NODE_MIN_WIDTH = 18;
|
|
328
363
|
|
|
329
364
|
function editTopic(element) {
|
|
@@ -433,7 +468,7 @@ const copyNewNode = (node) => {
|
|
|
433
468
|
const extractNodesText = (node) => {
|
|
434
469
|
let str = '';
|
|
435
470
|
if (node) {
|
|
436
|
-
str += Node.string(node.data.topic
|
|
471
|
+
str += Node.string(node.data.topic) + ' ';
|
|
437
472
|
for (const childNode of node.children) {
|
|
438
473
|
str += extractNodesText(childNode);
|
|
439
474
|
}
|
|
@@ -624,15 +659,20 @@ const adjustNodeToRoot = (board, node) => {
|
|
|
624
659
|
};
|
|
625
660
|
|
|
626
661
|
const DefaultAbstractNodeStyle = {
|
|
627
|
-
strokeColor: GRAY_COLOR,
|
|
628
|
-
strokeWidth: 2,
|
|
629
662
|
branchColor: GRAY_COLOR,
|
|
630
|
-
branchWidth: 2
|
|
663
|
+
branchWidth: 2,
|
|
664
|
+
shape: {
|
|
665
|
+
strokeColor: GRAY_COLOR,
|
|
666
|
+
strokeWidth: 2
|
|
667
|
+
}
|
|
631
668
|
};
|
|
632
669
|
const DefaultNodeStyle = {
|
|
633
|
-
strokeWidth: 3,
|
|
634
670
|
branchWidth: 3,
|
|
635
|
-
|
|
671
|
+
shape: {
|
|
672
|
+
rectangleRadius: 4,
|
|
673
|
+
strokeWidth: 3,
|
|
674
|
+
fill: 'none'
|
|
675
|
+
}
|
|
636
676
|
};
|
|
637
677
|
|
|
638
678
|
const getAvailableProperty = (board, element, propertyKey) => {
|
|
@@ -867,11 +907,15 @@ const getStrokeByMindElement = (board, element) => {
|
|
|
867
907
|
return element.strokeColor || defaultRootStroke;
|
|
868
908
|
}
|
|
869
909
|
if (AbstractNode.isAbstract(element) || isChildOfAbstract(board, element)) {
|
|
870
|
-
return element.strokeColor || DefaultAbstractNodeStyle.strokeColor;
|
|
871
|
-
;
|
|
910
|
+
return element.strokeColor || DefaultAbstractNodeStyle.shape.strokeColor;
|
|
872
911
|
}
|
|
873
912
|
return getAvailableProperty(board, element, 'strokeColor') || getDefaultBranchColor(board, element);
|
|
874
913
|
};
|
|
914
|
+
const getStrokeWidthByElement = (board, element) => {
|
|
915
|
+
const strokeWidth = element.strokeWidth ||
|
|
916
|
+
(AbstractNode.isAbstract(element) ? DefaultAbstractNodeStyle.shape.strokeWidth : DefaultNodeStyle.shape.strokeWidth);
|
|
917
|
+
return strokeWidth;
|
|
918
|
+
};
|
|
875
919
|
const getShapeByElement = (board, element) => {
|
|
876
920
|
const shape = getAvailableProperty(board, element, 'shape');
|
|
877
921
|
return shape || MindElementShape.roundRectangle;
|
|
@@ -1310,7 +1354,7 @@ function drawLogicLink(board, parent, node, isHorizontal, defaultStroke = null,
|
|
|
1310
1354
|
const branchWidth = defaultStrokeWidth || getBranchWidthByMindElement(board, parent.origin);
|
|
1311
1355
|
const hasStraightLine = branchShape === BranchShape.polyline ? true : !parent.origin.isRoot;
|
|
1312
1356
|
const parentShape = getShapeByElement(board, parent.origin);
|
|
1313
|
-
const shape =
|
|
1357
|
+
const shape = getShapeByElement(board, node.origin);
|
|
1314
1358
|
const hasUnderlineShape = shape === MindElementShape.underline;
|
|
1315
1359
|
const hasUnderlineShapeOfParent = parentShape === MindElementShape.underline;
|
|
1316
1360
|
const nodeClient = getRectangleByNode(node);
|
|
@@ -1393,6 +1437,12 @@ const drawFakeDragNode = (board, element, offsetX, offsetY) => {
|
|
|
1393
1437
|
updateForeignObject(fakeEmojisG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
|
|
1394
1438
|
dragFakeNodeG?.append(fakeEmojisG);
|
|
1395
1439
|
}
|
|
1440
|
+
if (MindElement.hasImage(element)) {
|
|
1441
|
+
const fakeImageG = activeComponent.imageDrawer.g.cloneNode(true);
|
|
1442
|
+
const foreignRectangle = getImageForeignRectangle(board, element);
|
|
1443
|
+
updateForeignObject(fakeImageG, foreignRectangle.width, foreignRectangle.height, foreignRectangle.x + offsetX, foreignRectangle.y + offsetY);
|
|
1444
|
+
dragFakeNodeG?.append(fakeImageG);
|
|
1445
|
+
}
|
|
1396
1446
|
return dragFakeNodeG;
|
|
1397
1447
|
};
|
|
1398
1448
|
const drawFakeDropNode = (board, dropTarget, path) => {
|
|
@@ -1923,6 +1973,14 @@ const MindElement = {
|
|
|
1923
1973
|
return false;
|
|
1924
1974
|
}
|
|
1925
1975
|
},
|
|
1976
|
+
hasImage(element) {
|
|
1977
|
+
if (element.data.image) {
|
|
1978
|
+
return true;
|
|
1979
|
+
}
|
|
1980
|
+
else {
|
|
1981
|
+
return false;
|
|
1982
|
+
}
|
|
1983
|
+
},
|
|
1926
1984
|
getEmojis(element) {
|
|
1927
1985
|
return element.data.emojis;
|
|
1928
1986
|
},
|
|
@@ -1986,15 +2044,15 @@ function drawRoundRectangleByNode(board, node) {
|
|
|
1986
2044
|
}
|
|
1987
2045
|
function drawRoundRectangleByElement(board, nodeRectangle, element) {
|
|
1988
2046
|
const defaultRootFill = getMindThemeColor(board).rootFill;
|
|
1989
|
-
const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.fill;
|
|
2047
|
+
const fill = element.fill ? element.fill : element.isRoot ? defaultRootFill : DefaultNodeStyle.shape.fill;
|
|
1990
2048
|
const stroke = getStrokeByMindElement(board, element);
|
|
1991
|
-
const strokeWidth =
|
|
2049
|
+
const strokeWidth = getStrokeWidthByElement(board, element);
|
|
1992
2050
|
const nodeG = drawRoundRectangle(PlaitBoard.getRoughSVG(board), nodeRectangle.x, nodeRectangle.y, nodeRectangle.x + nodeRectangle.width, nodeRectangle.y + nodeRectangle.height, {
|
|
1993
2051
|
stroke,
|
|
1994
2052
|
strokeWidth,
|
|
1995
2053
|
fill,
|
|
1996
2054
|
fillStyle: 'solid'
|
|
1997
|
-
});
|
|
2055
|
+
}, false, DefaultNodeStyle.shape.rectangleRadius);
|
|
1998
2056
|
return nodeG;
|
|
1999
2057
|
}
|
|
2000
2058
|
|
|
@@ -2207,12 +2265,9 @@ const normalizeWidthAndHeight = (board, width, height) => {
|
|
|
2207
2265
|
};
|
|
2208
2266
|
const setTopic = (board, element, topic, width, height) => {
|
|
2209
2267
|
const newElement = {
|
|
2210
|
-
data: { topic },
|
|
2268
|
+
data: { ...element.data, topic },
|
|
2211
2269
|
...normalizeWidthAndHeight(board, width, height)
|
|
2212
2270
|
};
|
|
2213
|
-
if (MindElement.hasEmojis(element)) {
|
|
2214
|
-
newElement.data.emojis = element.data.emojis;
|
|
2215
|
-
}
|
|
2216
2271
|
const path = PlaitBoard.findPath(board, element);
|
|
2217
2272
|
Transforms.setNode(board, newElement, path);
|
|
2218
2273
|
};
|
|
@@ -2291,7 +2346,7 @@ const removeEmoji = (board, element, emojiItem) => {
|
|
|
2291
2346
|
};
|
|
2292
2347
|
const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
2293
2348
|
const newElement = {
|
|
2294
|
-
data: {
|
|
2349
|
+
data: { ...element.data }
|
|
2295
2350
|
};
|
|
2296
2351
|
const newEmojis = element.data.emojis.map(value => {
|
|
2297
2352
|
if (value === oldEmoji) {
|
|
@@ -2304,6 +2359,15 @@ const replaceEmoji = (board, element, oldEmoji, newEmoji) => {
|
|
|
2304
2359
|
Transforms.setNode(board, newElement, path);
|
|
2305
2360
|
};
|
|
2306
2361
|
|
|
2362
|
+
const removeImage = (board, element) => {
|
|
2363
|
+
const newElement = {
|
|
2364
|
+
data: { ...element.data }
|
|
2365
|
+
};
|
|
2366
|
+
delete newElement.data.image;
|
|
2367
|
+
const path = PlaitBoard.findPath(board, element);
|
|
2368
|
+
Transforms.setNode(board, newElement, path);
|
|
2369
|
+
};
|
|
2370
|
+
|
|
2307
2371
|
const MindTransforms = {
|
|
2308
2372
|
setLayout,
|
|
2309
2373
|
setTopic,
|
|
@@ -2317,7 +2381,8 @@ const MindTransforms = {
|
|
|
2317
2381
|
removeElements,
|
|
2318
2382
|
insertNodes,
|
|
2319
2383
|
insertAbstractNodes,
|
|
2320
|
-
setRightNodeCountByRefs
|
|
2384
|
+
setRightNodeCountByRefs,
|
|
2385
|
+
removeImage
|
|
2321
2386
|
};
|
|
2322
2387
|
|
|
2323
2388
|
class BaseDrawer {
|
|
@@ -2505,6 +2570,48 @@ function handleBoardClass(board, activeHandlePosition, isHorizontal) {
|
|
|
2505
2570
|
PlaitBoard.getBoardContainer(board).classList.remove('abstract-resizing-vertical');
|
|
2506
2571
|
}
|
|
2507
2572
|
}
|
|
2573
|
+
function drawAbstractRoundRectangle(rs, x1, y1, x2, y2, isHorizontal, options) {
|
|
2574
|
+
const width = Math.abs(x1 - x2);
|
|
2575
|
+
const height = Math.abs(y1 - y2);
|
|
2576
|
+
const radius = 5;
|
|
2577
|
+
const handleGap = 4;
|
|
2578
|
+
const handleLength = 10;
|
|
2579
|
+
const handleSpace = handleLength + handleGap * 2;
|
|
2580
|
+
if (isHorizontal) {
|
|
2581
|
+
const handleSideLine = (width - handleSpace - radius * 2) / 2;
|
|
2582
|
+
const sideLine = height - radius * 2;
|
|
2583
|
+
return rs.path(`M${x1 + radius},${y1}
|
|
2584
|
+
l${handleSideLine},0
|
|
2585
|
+
m${handleSpace},0
|
|
2586
|
+
l${handleSideLine},0
|
|
2587
|
+
a${radius},${radius},0,0,1,${radius},${radius}
|
|
2588
|
+
l0,${sideLine}
|
|
2589
|
+
a${radius},${radius},0,0,1,-${radius},${radius}
|
|
2590
|
+
l-${handleSideLine},0
|
|
2591
|
+
m-${handleSpace},0
|
|
2592
|
+
l-${handleSideLine},0
|
|
2593
|
+
a${radius},${radius},0,0,1,-${radius},-${radius}
|
|
2594
|
+
l0,-${sideLine}
|
|
2595
|
+
a${radius},${radius},0,0,1,${radius},-${radius}`, options);
|
|
2596
|
+
}
|
|
2597
|
+
else {
|
|
2598
|
+
const handleSideLine = (height - handleSpace - radius * 2) / 2;
|
|
2599
|
+
const sideLine = width - radius * 2;
|
|
2600
|
+
return rs.path(`M${x1 + radius},${y1}
|
|
2601
|
+
l${sideLine},0
|
|
2602
|
+
a${radius},${radius},0,0,1,${radius},${radius}
|
|
2603
|
+
l0,${handleSideLine}
|
|
2604
|
+
m0,${handleSpace}
|
|
2605
|
+
l0,${handleSideLine}
|
|
2606
|
+
a${radius},${radius},0,0,1,-${radius},${radius}
|
|
2607
|
+
l-${sideLine},0
|
|
2608
|
+
a${radius},${radius},0,0,1,-${radius},-${radius}
|
|
2609
|
+
l0,-${handleSideLine}
|
|
2610
|
+
m0,-${handleSpace}
|
|
2611
|
+
l0,-${handleSideLine}
|
|
2612
|
+
a${radius},${radius},0,0,1,${radius},-${radius}`, options);
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2508
2615
|
|
|
2509
2616
|
class NodeActiveDrawer extends BaseDrawer {
|
|
2510
2617
|
canDraw(element, data) {
|
|
@@ -2523,14 +2630,13 @@ class NodeActiveDrawer extends BaseDrawer {
|
|
|
2523
2630
|
activeG.append(this.abstractOutlineG);
|
|
2524
2631
|
}
|
|
2525
2632
|
const node = MindElement.getNode(element);
|
|
2526
|
-
|
|
2527
|
-
const
|
|
2633
|
+
const rectangle = getRectangleByNode(node);
|
|
2634
|
+
const activeStrokeWidth = 2;
|
|
2635
|
+
// add 0.1 to avoid white gap
|
|
2636
|
+
const offset = (getStrokeWidthByElement(this.board, element) + activeStrokeWidth) / 2 - 0.1;
|
|
2637
|
+
const activeRectangle = RectangleClient.getOutlineRectangle(rectangle, -offset);
|
|
2638
|
+
const strokeG = drawRoundRectangle(PlaitBoard.getRoughSVG(this.board), activeRectangle.x, activeRectangle.y, activeRectangle.x + activeRectangle.width, activeRectangle.y + activeRectangle.height, { stroke: PRIMARY_COLOR, strokeWidth: activeStrokeWidth, fill: '' }, true, DefaultNodeStyle.shape.rectangleRadius + offset);
|
|
2528
2639
|
this.g.appendChild(strokeG);
|
|
2529
|
-
if (!data.isEditing) {
|
|
2530
|
-
const fillG = drawRoundRectangle(PlaitBoard.getRoughSVG(this.board), x - 2, y - 2, x + width + 2, y + height + 2, { stroke: PRIMARY_COLOR, fill: PRIMARY_COLOR, fillStyle: 'solid' }, true);
|
|
2531
|
-
fillG.style.opacity = '0.15';
|
|
2532
|
-
this.g.appendChild(fillG);
|
|
2533
|
-
}
|
|
2534
2640
|
return activeG;
|
|
2535
2641
|
}
|
|
2536
2642
|
updateAbstractOutline(element, activeHandlePosition, resizingLocation) {
|
|
@@ -2636,6 +2742,88 @@ class CollapseDrawer extends BaseDrawer {
|
|
|
2636
2742
|
}
|
|
2637
2743
|
}
|
|
2638
2744
|
|
|
2745
|
+
class MindImageBaseComponent {
|
|
2746
|
+
get nativeElement() {
|
|
2747
|
+
return this.elementRef.nativeElement;
|
|
2748
|
+
}
|
|
2749
|
+
constructor(elementRef) {
|
|
2750
|
+
this.elementRef = elementRef;
|
|
2751
|
+
}
|
|
2752
|
+
ngOnInit() { }
|
|
2753
|
+
}
|
|
2754
|
+
MindImageBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2755
|
+
MindImageBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: MindImageBaseComponent, inputs: { imageItem: "imageItem", board: "board", element: "element" }, host: { classAttribute: "mind-node-image" }, ngImport: i0 });
|
|
2756
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: MindImageBaseComponent, decorators: [{
|
|
2757
|
+
type: Directive,
|
|
2758
|
+
args: [{
|
|
2759
|
+
host: {
|
|
2760
|
+
class: 'mind-node-image'
|
|
2761
|
+
}
|
|
2762
|
+
}]
|
|
2763
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { imageItem: [{
|
|
2764
|
+
type: Input
|
|
2765
|
+
}], board: [{
|
|
2766
|
+
type: Input
|
|
2767
|
+
}], element: [{
|
|
2768
|
+
type: Input
|
|
2769
|
+
}] } });
|
|
2770
|
+
|
|
2771
|
+
class NodeImageDrawer {
|
|
2772
|
+
constructor(board, viewContainerRef) {
|
|
2773
|
+
this.board = board;
|
|
2774
|
+
this.viewContainerRef = viewContainerRef;
|
|
2775
|
+
this.componentRef = null;
|
|
2776
|
+
}
|
|
2777
|
+
drawImage(element) {
|
|
2778
|
+
this.destroy();
|
|
2779
|
+
if (MindElement.hasImage(element)) {
|
|
2780
|
+
this.g = createG();
|
|
2781
|
+
const foreignRectangle = getImageForeignRectangle(this.board, element);
|
|
2782
|
+
const foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
|
|
2783
|
+
this.g.append(foreignObject);
|
|
2784
|
+
if (this.componentRef) {
|
|
2785
|
+
this.componentRef.destroy();
|
|
2786
|
+
this.componentRef = null;
|
|
2787
|
+
}
|
|
2788
|
+
const componentType = this.board.getPluginOptions(WithMindPluginKey).imageComponentType || MindImageBaseComponent;
|
|
2789
|
+
if (!componentType) {
|
|
2790
|
+
throw new Error('Not implement drawEmoji method error.');
|
|
2791
|
+
}
|
|
2792
|
+
this.componentRef = this.viewContainerRef.createComponent(componentType);
|
|
2793
|
+
this.componentRef.instance.board = this.board;
|
|
2794
|
+
this.componentRef.instance.element = element;
|
|
2795
|
+
this.componentRef.instance.imageItem = element.data.image;
|
|
2796
|
+
foreignObject.append(this.componentRef.instance.nativeElement);
|
|
2797
|
+
return this.g;
|
|
2798
|
+
}
|
|
2799
|
+
return undefined;
|
|
2800
|
+
}
|
|
2801
|
+
drawActive(element) {
|
|
2802
|
+
this.destroyActive();
|
|
2803
|
+
const imageRectangle = getImageForeignRectangle(this.board, element);
|
|
2804
|
+
const rectangle = RectangleClient.getOutlineRectangle(imageRectangle, -1);
|
|
2805
|
+
const roughSVG = PlaitBoard.getRoughSVG(this.board);
|
|
2806
|
+
this.activeG = roughSVG.rectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height, {
|
|
2807
|
+
stroke: PRIMARY_COLOR,
|
|
2808
|
+
fill: '',
|
|
2809
|
+
fillStyle: 'solid'
|
|
2810
|
+
});
|
|
2811
|
+
this.g?.append(this.activeG);
|
|
2812
|
+
}
|
|
2813
|
+
destroyActive() {
|
|
2814
|
+
this.activeG?.remove();
|
|
2815
|
+
}
|
|
2816
|
+
destroy() {
|
|
2817
|
+
if (this.g) {
|
|
2818
|
+
this.g.remove();
|
|
2819
|
+
}
|
|
2820
|
+
if (this.componentRef) {
|
|
2821
|
+
this.componentRef.destroy();
|
|
2822
|
+
this.componentRef = null;
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2639
2827
|
// 1. When the text at the end has an italic attribute, the text is partially covered
|
|
2640
2828
|
// 2. There will be some differences in the width measured by different browsers
|
|
2641
2829
|
const WIDTH_BUFFER = 4;
|
|
@@ -2655,6 +2843,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2655
2843
|
this.nodeInsertDrawer = new NodeInsertDrawer(this.board);
|
|
2656
2844
|
this.activeDrawer = new NodeActiveDrawer(this.board);
|
|
2657
2845
|
this.collapseDrawer = new CollapseDrawer(this.board);
|
|
2846
|
+
this.imageDrawer = new NodeImageDrawer(this.board, this.viewContainerRef);
|
|
2658
2847
|
const plugins = this.board.getPluginOptions(WithMindPluginKey).textPlugins;
|
|
2659
2848
|
this.textManage = new TextManage(this.board, this.viewContainerRef, () => {
|
|
2660
2849
|
const rect = getTopicRectangleByNode(this.board, this.node);
|
|
@@ -2685,6 +2874,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2685
2874
|
this.activeDrawer.draw(this.element, this.g, { selected: this.selected, isEditing: this.textManage.isEditing });
|
|
2686
2875
|
this.drawEmojis();
|
|
2687
2876
|
this.drawExtend();
|
|
2877
|
+
this.drawImage();
|
|
2688
2878
|
if (PlaitMind.isMind(this.context.parent)) {
|
|
2689
2879
|
this.g.classList.add('branch');
|
|
2690
2880
|
}
|
|
@@ -2707,6 +2897,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2707
2897
|
this.drawShape();
|
|
2708
2898
|
this.drawLink();
|
|
2709
2899
|
this.drawEmojis();
|
|
2900
|
+
this.drawImage();
|
|
2710
2901
|
this.drawExtend();
|
|
2711
2902
|
this.textManage.updateText(this.element.data.topic);
|
|
2712
2903
|
this.textManage.updateRectangle();
|
|
@@ -2728,6 +2919,12 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2728
2919
|
this.g.append(g);
|
|
2729
2920
|
}
|
|
2730
2921
|
}
|
|
2922
|
+
drawImage() {
|
|
2923
|
+
const image = this.imageDrawer.drawImage(this.element);
|
|
2924
|
+
if (image) {
|
|
2925
|
+
this.g.append(image);
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2731
2928
|
drawShape() {
|
|
2732
2929
|
this.destroyShape();
|
|
2733
2930
|
const shape = getShapeByElement(this.board, this.node.origin);
|
|
@@ -2796,6 +2993,7 @@ class MindNodeComponent extends PlaitPluginElementComponent {
|
|
|
2796
2993
|
super.ngOnDestroy();
|
|
2797
2994
|
this.textManage.destroy();
|
|
2798
2995
|
this.nodeEmojisDrawer.destroy();
|
|
2996
|
+
this.imageDrawer.destroy();
|
|
2799
2997
|
this.destroy$.next();
|
|
2800
2998
|
this.destroy$.complete();
|
|
2801
2999
|
if (ELEMENT_TO_NODE.get(this.element) === this.node) {
|
|
@@ -3622,6 +3820,52 @@ const removeHovered = (element) => {
|
|
|
3622
3820
|
}
|
|
3623
3821
|
};
|
|
3624
3822
|
|
|
3823
|
+
const withMindImage = (board) => {
|
|
3824
|
+
let selectedImageElement = null;
|
|
3825
|
+
const { keydown, mousedown } = board;
|
|
3826
|
+
board.mousedown = (event) => {
|
|
3827
|
+
if (PlaitBoard.isReadonly(board) || !isMainPointer(event) || !PlaitBoard.isPointer(board, PlaitPointerType.selection)) {
|
|
3828
|
+
mousedown(event);
|
|
3829
|
+
return;
|
|
3830
|
+
}
|
|
3831
|
+
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
3832
|
+
const range = { anchor: point, focus: point };
|
|
3833
|
+
const hitElements = getHitElements(board, { ranges: [range] });
|
|
3834
|
+
const hasImage = hitElements.length && MindElement.hasImage(hitElements[0]);
|
|
3835
|
+
const hitImage = hasImage && isHitImage(board, hitElements[0], range);
|
|
3836
|
+
if (hitImage) {
|
|
3837
|
+
const currentOptions = board.getPluginOptions(PlaitPluginKey.withSelection);
|
|
3838
|
+
board.setPluginOptions(PlaitPluginKey.withSelection, {
|
|
3839
|
+
isDisabledSelect: true
|
|
3840
|
+
});
|
|
3841
|
+
setTimeout(() => {
|
|
3842
|
+
board.setPluginOptions(PlaitPluginKey.withSelection, { ...currentOptions });
|
|
3843
|
+
}, 0);
|
|
3844
|
+
selectedImageElement = hitElements[0];
|
|
3845
|
+
const component = PlaitElement.getComponent(selectedImageElement);
|
|
3846
|
+
component.imageDrawer.drawActive(selectedImageElement);
|
|
3847
|
+
clearSelectedElement(board);
|
|
3848
|
+
}
|
|
3849
|
+
else {
|
|
3850
|
+
if (selectedImageElement) {
|
|
3851
|
+
const component = PlaitElement.getComponent(selectedImageElement);
|
|
3852
|
+
component && component.imageDrawer.destroyActive();
|
|
3853
|
+
}
|
|
3854
|
+
selectedImageElement = null;
|
|
3855
|
+
}
|
|
3856
|
+
mousedown(event);
|
|
3857
|
+
};
|
|
3858
|
+
board.keydown = (event) => {
|
|
3859
|
+
if (!PlaitBoard.isReadonly(board) && selectedImageElement && (hotkeys.isDeleteBackward(event) || hotkeys.isDeleteForward(event))) {
|
|
3860
|
+
MindTransforms.removeImage(board, selectedImageElement);
|
|
3861
|
+
selectedImageElement = null;
|
|
3862
|
+
return;
|
|
3863
|
+
}
|
|
3864
|
+
keydown(event);
|
|
3865
|
+
};
|
|
3866
|
+
return board;
|
|
3867
|
+
};
|
|
3868
|
+
|
|
3625
3869
|
const withMind = (board) => {
|
|
3626
3870
|
const { drawElement, dblclick, keydown, insertFragment, setFragment, deleteFragment, isHitSelection, getRectangle, isMovable, isRecursion } = board;
|
|
3627
3871
|
board.drawElement = (context) => {
|
|
@@ -3636,15 +3880,9 @@ const withMind = (board) => {
|
|
|
3636
3880
|
board.applyTheme = (element) => {
|
|
3637
3881
|
const mindElement = element;
|
|
3638
3882
|
const shouldClearProperty = !PlaitBoard.isBoard(element) && (mindElement?.branchColor || mindElement?.fill || mindElement?.strokeColor);
|
|
3639
|
-
const isAbstract = AbstractNode.isAbstract(element);
|
|
3640
3883
|
if (shouldClearProperty) {
|
|
3641
3884
|
const path = PlaitBoard.findPath(board, element);
|
|
3642
|
-
|
|
3643
|
-
Transforms.setNode(board, { fill: null, strokeColor: DefaultAbstractNodeStyle.strokeColor, branchColor: DefaultAbstractNodeStyle.branchColor }, path);
|
|
3644
|
-
}
|
|
3645
|
-
else {
|
|
3646
|
-
Transforms.setNode(board, { fill: null, strokeColor: null, branchColor: null }, path);
|
|
3647
|
-
}
|
|
3885
|
+
Transforms.setNode(board, { fill: null, strokeColor: null, branchColor: null }, path);
|
|
3648
3886
|
}
|
|
3649
3887
|
};
|
|
3650
3888
|
board.getRectangle = element => {
|
|
@@ -3739,7 +3977,7 @@ const withMind = (board) => {
|
|
|
3739
3977
|
MindTransforms.removeElements(board, selectedElements);
|
|
3740
3978
|
deleteFragment(data);
|
|
3741
3979
|
};
|
|
3742
|
-
return withNodeHover(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board))))));
|
|
3980
|
+
return withMindImage(withNodeHover(withMindHotkey(withMindExtend(withCreateMind(withAbstract(withNodeDnd(board)))))));
|
|
3743
3981
|
};
|
|
3744
3982
|
|
|
3745
3983
|
class MindEmojiBaseComponent {
|
|
@@ -3793,5 +4031,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
|
|
|
3793
4031
|
* Generated bundle index. Do not edit.
|
|
3794
4032
|
*/
|
|
3795
4033
|
|
|
3796
|
-
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_FONT_FAMILY, BRANCH_WIDTH, BaseDrawer, BranchShape, DEFAULT_FONT_FAMILY, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, ROOT_TOPIC_HEIGHT, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, WithMindPluginKey, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
|
|
4034
|
+
export { ABSTRACT_HANDLE_COLOR, ABSTRACT_HANDLE_LENGTH, ABSTRACT_HANDLE_MASK_WIDTH, ABSTRACT_INCLUDED_OUTLINE_OFFSET, AbstractHandlePosition, AbstractResizeState, BASE, BRANCH_FONT_FAMILY, BRANCH_WIDTH, BaseDrawer, BranchShape, DEFAULT_FONT_FAMILY, DefaultAbstractNodeStyle, DefaultNodeStyle, ELEMENT_TO_NODE, EXTEND_DIAMETER, EXTEND_OFFSET, GRAY_COLOR, INHERIT_ATTRIBUTE_KEYS, IS_DRAGGING, LayoutDirection, LayoutDirectionsMap, MindColorfulThemeColor, MindDarkThemeColor, MindDefaultThemeColor, MindElement, MindElementShape, MindEmojiBaseComponent, MindImageBaseComponent, MindModule, MindNode, MindNodeComponent, MindPointerType, MindQueries, MindRetroThemeColor, MindSoftThemeColor, MindStarryThemeColor, MindThemeColor, MindThemeColors, MindTransforms, NODE_MIN_WIDTH, PRIMARY_COLOR, PlaitMind, PlaitMindComponent, QUICK_INSERT_CIRCLE_COLOR, QUICK_INSERT_CIRCLE_OFFSET, QUICK_INSERT_INNER_CROSS_COLOR, ROOT_TOPIC_FONT_SIZE, ROOT_TOPIC_HEIGHT, STROKE_WIDTH, TOPIC_COLOR, TOPIC_DEFAULT_MAX_WORD_COUNT, TOPIC_FONT_SIZE, TRANSPARENT, WithMindPluginKey, addActiveOnDragOrigin, adjustAbstractToNode, adjustNodeToRoot, adjustRootToNode, canSetAbstract, copyNewNode, correctLayoutByDirection, createDefaultMind, createEmptyMind, createMindElement, deleteElementHandleAbstract, deleteElementsHandleRightNodeCount, detectDropTarget, directionCorrector, directionDetector, divideElementByParent, drawFakeDragNode, drawFakeDropNode, editTopic, extractNodesText, findLastChild, findLocationLeftIndex, getAbstractBranchColor, getAbstractBranchWidth, getAbstractHandleRectangle, getAllowedDirection, getAvailableSubLayoutsByLayoutDirections, getBehindAbstracts, getBranchColorByMindElement, getBranchDirectionsByLayouts, getBranchShapeByMindElement, getBranchWidthByMindElement, getChildrenCount, getCorrespondingAbstract, getDefaultBranchColor, getDefaultBranchColorByIndex, getDefaultLayout, getEmojiForeignRectangle, getEmojiRectangle, getFirstLevelElement, getHitAbstractHandle, getImageForeignRectangle, getInCorrectLayoutDirection, getLayoutDirection$1 as getLayoutDirection, getLayoutReverseDirection, getLocationScope, getMindThemeColor, getNextBranchColor, getOverallAbstracts, getPathByDropTarget, getRectangleByElement, getRectangleByNode, getRectangleByResizingLocation, getRelativeStartEndByAbstractRef, getRootLayout, getShapeByElement, getStrokeByMindElement, getStrokeWidthByElement, getTopicRectangleByElement, getTopicRectangleByNode, getValidAbstractRefs, handleTouchedAbstract, hasAfterDraw, hasPreviousOrNextOfDropPath, insertElementHandleAbstract, insertElementHandleRightNodeCount, insertMindElement, isChildElement, isChildOfAbstract, isChildRight, isChildUp, isCorrectLayout, isDragging, isDropStandardRight, isHitEmojis, isHitImage, isHitMindElement, isInRightBranchOfStandardLayout, isMixedLayout, isSetAbstract, isValidTarget, isVirtualKey, removeActiveOnDragOrigin, separateChildren, setIsDragging, withMind, withMindExtend };
|
|
3797
4035
|
//# sourceMappingURL=plait-mind.mjs.map
|