Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(draw): add cloud shape #WIK-15004 #802

Merged
merged 2 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/flat-brooms-know.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@plait/draw': patch
---

add cloud shape
7 changes: 7 additions & 0 deletions packages/draw/src/constants/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ export const DefaultBasicShapeProperty = {
strokeWidth: 2
};

export const DefaultCloudShapeProperty = {
width: 120,
height: 100,
strokeColor: '#333',
strokeWidth: 2
};

export const DefaultTextProperty = {
width: 36,
height: 20,
Expand Down
62 changes: 62 additions & 0 deletions packages/draw/src/engines/basic-shapes/cloud.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { PlaitBoard, Point, PointOfRectangle, RectangleClient, drawRectangle, getNearestPointBetweenPointAndSegments, setPathStrokeLinecap } from '@plait/core';
import { PlaitGeometry, ShapeEngine } from '../../interfaces';
import { Options } from 'roughjs/bin/core';
import { getPolygonEdgeByConnectionPoint } from '../../utils/polygon';
import { getStrokeWidthByElement } from '../../utils';
import { ShapeDefaultSpace } from '../../constants';

export const CloudEngine: ShapeEngine = {
draw(board: PlaitBoard, rectangle: RectangleClient, options: Options) {
const rs = PlaitBoard.getRoughSVG(board);
const divisionWidth = rectangle.width / 7;
const divisionHeight = rectangle.height / 3.2;
const xRadius = divisionWidth / 8.5;
const yRadius = divisionHeight / 20;
const svgElement = rs.path(
`M ${rectangle.x + divisionWidth} ${rectangle.y + divisionHeight}
A ${xRadius} ${yRadius * 1.2} 0 1 1 ${rectangle.x + divisionWidth * 2} ${rectangle.y + divisionHeight / 2}
A ${xRadius} ${yRadius} 0 1 1 ${rectangle.x + divisionWidth * 4.2} ${rectangle.y + divisionHeight / 2.2}
A ${xRadius} ${yRadius} 0 1 1 ${rectangle.x + divisionWidth * 5.8} ${rectangle.y + divisionHeight}
A ${xRadius} ${yRadius * 1.3} 0 1 1 ${rectangle.x + divisionWidth * 6} ${rectangle.y + divisionHeight * 2.2}
A ${xRadius} ${yRadius * 1.2} 0 1 1 ${rectangle.x + divisionWidth * 5} ${rectangle.y + divisionHeight * 2.8}
A ${xRadius} ${yRadius / 1.2} 0 1 1 ${rectangle.x + divisionWidth * 2.8} ${rectangle.y + divisionHeight * 2.8}
A ${xRadius} ${yRadius} 0 1 1 ${rectangle.x + divisionWidth} ${rectangle.y + divisionHeight * 2.2}
A ${xRadius} ${yRadius * 1.42} 0 1 1 ${rectangle.x + divisionWidth} ${rectangle.y + divisionHeight}
Z`,
{ ...options, fillStyle: 'solid' }
);
setPathStrokeLinecap(svgElement, 'round');
return svgElement;
},
isInsidePoint(rectangle: RectangleClient, point: Point) {
const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
return RectangleClient.isHit(rectangle, rangeRectangle);
},
getCornerPoints(rectangle: RectangleClient) {
return RectangleClient.getCornerPoints(rectangle);
},
getNearestPoint(rectangle: RectangleClient, point: Point) {
return getNearestPointBetweenPointAndSegments(point, CloudEngine.getCornerPoints(rectangle));
},
getEdgeByConnectionPoint(rectangle: RectangleClient, pointOfRectangle: PointOfRectangle): [Point, Point] | null {
const corners = CloudEngine.getCornerPoints(rectangle);
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
return getPolygonEdgeByConnectionPoint(corners, point);
},
getConnectorPoints(rectangle: RectangleClient) {
return RectangleClient.getEdgeCenterPoints(rectangle);
},
getTextRectangle(element: PlaitGeometry) {
const elementRectangle = RectangleClient.getRectangleByPoints(element.points!);
const strokeWidth = getStrokeWidthByElement(element);
const height = element.textHeight;
const originWidth = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
const width = originWidth / 1.5;
return {
height,
width: width > 0 ? width : 0,
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth + originWidth / 6,
y: elementRectangle.y + elementRectangle.height / 6 + ((elementRectangle.height * 4) / 6 - height) / 2
};
}
};
4 changes: 3 additions & 1 deletion packages/draw/src/engines/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ManualLoopEngine } from './flowchart/manual-loop';
import { MergeEngine } from './flowchart/merge';
import { DelayEngine } from './flowchart/delay';
import { StoredDataEngine } from './flowchart/stored-data';
import { CloudEngine } from './basic-shapes/cloud';

export const ShapeEngineMap: Record<GeometryShapes, ShapeEngine> = {
[BasicShapes.rectangle]: RectangleEngine,
Expand All @@ -47,6 +48,7 @@ export const ShapeEngineMap: Record<GeometryShapes, ShapeEngine> = {
[BasicShapes.twoWayArrow]: TwoWayArrowEngine,
[BasicShapes.comment]: CommentEngine,
[BasicShapes.roundComment]: RoundCommentEngine,
[BasicShapes.cloud]: CloudEngine,
[FlowchartSymbols.process]: RectangleEngine,
[FlowchartSymbols.decision]: DiamondEngine,
[FlowchartSymbols.connector]: EllipseEngine,
Expand All @@ -57,7 +59,7 @@ export const ShapeEngineMap: Record<GeometryShapes, ShapeEngine> = {
[FlowchartSymbols.manualLoop]: ManualLoopEngine,
[FlowchartSymbols.merge]: MergeEngine,
[FlowchartSymbols.delay]: DelayEngine,
[FlowchartSymbols.storedData]: StoredDataEngine
[FlowchartSymbols.storedData]: StoredDataEngine,
};

export const getEngine = (shape: GeometryShapes) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/draw/src/interfaces/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export enum BasicShapes {
processArrow = 'processArrow',
twoWayArrow = 'twoWayArrow',
comment = 'comment',
roundComment = 'roundComment'
roundComment = 'roundComment',
cloud = 'cloud'
}

export enum FlowchartSymbols {
Expand Down
4 changes: 4 additions & 0 deletions packages/draw/src/utils/geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Alignment, CustomText, DEFAULT_FONT_SIZE, buildText, getTextSize } from
import { Element } from 'slate';
import {
DefaultBasicShapeProperty,
DefaultCloudShapeProperty,
DefaultFlowchartPropertyMap,
DefaultTextProperty,
DrawPointerType,
Expand Down Expand Up @@ -310,6 +311,9 @@ export const getDefaultGeometryProperty = (pointer: DrawPointerType) => {
if (isFlowChart) {
return getDefaultFlowchartProperty(pointer as FlowchartSymbols);
} else {
if(pointer === BasicShapes.cloud){
return DefaultCloudShapeProperty;
}
return DefaultBasicShapeProperty;
}
};
Expand Down
40 changes: 38 additions & 2 deletions src/app/components/main-toolbar/main-toolbar.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@
>
<ng-template [ngTemplateOutlet]="roundComment"></ng-template>
</a>

<a
class="action-item"
[ngClass]="{ active: isPointer(GeometryShapeType.cloud) }"
(mousedown)="setPointer($event, GeometryShapeType.cloud)"
>
<ng-template [ngTemplateOutlet]="cloud"></ng-template>
</a>
</div>
<div class="title">流程图</div>
<div class="shapes-container">
Expand Down Expand Up @@ -263,15 +271,23 @@
</div>
</div>

<a class="action-item" [ngClass]="{ active: isActiveItem(GeometryShapeType.text) }" (mousedown)="setPointer($event, GeometryShapeType.text)">
<a
class="action-item"
[ngClass]="{ active: isActiveItem(GeometryShapeType.text) }"
(mousedown)="setPointer($event, GeometryShapeType.text)"
>
<ng-template [ngTemplateOutlet]="text"></ng-template>
</a>

<a class="action-item" [ngClass]="{ active: isActiveItem(LineShapeType.elbow) }" (mousedown)="setPointer($event, LineShapeType.elbow)">
<ng-template [ngTemplateOutlet]="elbow"></ng-template>
</a>

<a class="action-item" [ngClass]="{ active: isActiveItem(LineShapeType.straight) }" (mousedown)="setPointer($event, LineShapeType.straight)">
<a
class="action-item"
[ngClass]="{ active: isActiveItem(LineShapeType.straight) }"
(mousedown)="setPointer($event, LineShapeType.straight)"
>
<ng-template [ngTemplateOutlet]="straight"></ng-template>
</a>

Expand Down Expand Up @@ -825,6 +841,26 @@
</svg>
</ng-template>

<ng-template #cloud>
<svg
width="16px"
height="16px"
viewBox="0 0 16 16"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>1.Base基础/1.icon图标/11.editor/图形/云</title>
<g id="1.Base基础/1.icon图标/11.editor/图形/云" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path
d="M7.85098404,1.77485762 L7.6558943,1.78162938 C6.94562876,1.8310594 6.29465393,2.14856671 5.82151192,2.65081981 L5.707,2.77885762 L5.53061686,2.72548879 C5.33906922,2.67565487 5.14006514,2.64985762 4.9375,2.64985762 C3.63963084,2.64985762 2.5875,3.70198846 2.5875,4.99985762 L2.59451044,5.18224207 L2.612,5.33485762 L2.52558331,5.35392072 C1.30561771,5.65103478 0.4,6.75093703 0.4,8.06235762 L0.406037394,8.24662403 C0.470129753,9.22228735 1.03960485,10.0784322 1.87906612,10.5239809 L1.933,10.5498576 L1.93125,10.4686076 C1.93125,12.1289137 3.27719397,13.4748576 4.9375,13.4748576 L5.15084339,13.4673765 C5.36296936,13.452456 5.57112569,13.415343 5.77245609,13.3571672 L5.846,13.3328576 L5.85681194,13.3451641 C6.37699392,13.9704129 7.15512112,14.3498576 8,14.3498576 L8.19567329,14.3430472 C8.90816474,14.2933273 9.56222553,13.9738317 10.042,13.4578576 L10.0753825,13.4723335 C10.3870128,13.5903451 10.7204571,13.6523051 11.0625,13.6523051 L11.2328399,13.6471749 C12.4726854,13.5722892 13.4994835,12.6854323 13.7763438,11.5045346 L13.798,11.3938576 C14.8849522,10.8591533 15.6,9.74755092 15.6,8.49985762 L15.5945778,8.31195876 C15.5297854,7.19168657 14.8892587,6.20561851 13.9393021,5.67916679 L13.818,5.61585762 L13.841913,5.42354949 C13.8472894,5.35565526 13.85,5.28729975 13.85,5.21860762 C13.85,3.79992617 12.6999315,2.64985762 11.28125,2.64985762 L11.0786904,2.65776961 C10.743526,2.6840328 10.4215563,2.77512816 10.1280816,2.92279748 L10.111,2.93185762 L10.0303679,2.82373095 C9.51346697,2.17638171 8.72018652,1.77485762 7.85098404,1.77485762 Z M7.85098404,2.97485762 C8.52291753,2.97485762 9.11528785,3.39617358 9.34240319,4.01672524 L9.66157322,4.88879971 L10.3254177,4.23942006 C10.5795126,3.99086177 10.9183879,3.84985762 11.28125,3.84985762 C12.0371898,3.84985762 12.65,4.46266787 12.65,5.21860762 C12.65,5.4025667 12.6140191,5.58046309 12.5450259,5.74562929 L12.2846938,6.36885124 L12.9342511,6.55392908 C13.7945519,6.79905395 14.4,7.59003792 14.4,8.49985762 C14.4,9.36586236 13.8513454,10.127616 13.0478598,10.4105597 L12.6679369,10.5443478 L12.6478946,10.9466399 C12.6059987,11.7875778 11.9091352,12.4523051 11.0625,12.4523051 C10.7498829,12.4523051 10.4521327,12.36239 10.1965943,12.1956581 L9.677265,11.8568095 L9.35570474,12.3870173 C9.07069907,12.8569516 8.56111542,13.1498576 8,13.1498576 C7.40737402,13.1498576 6.87307548,12.8227111 6.59860489,12.3090957 L6.31533542,11.779015 L5.78573748,12.063186 C5.52808703,12.2014357 5.23890292,12.2748576 4.9375,12.2748576 C3.93993567,12.2748576 3.13125,11.466172 3.13125,10.4686076 C3.13125,10.3889828 3.13636556,10.3101581 3.14648666,10.2324076 L3.21220077,9.72759031 L2.72482656,9.58053506 C2.06278469,9.3807774 1.6,8.7665903 1.6,8.06235762 C1.6,7.18560558 2.31074796,6.47485762 3.1875,6.47485762 C3.24753412,6.47485762 3.30703805,6.4781631 3.36586606,6.48471268 L4.57303467,6.61911203 L3.94617683,5.57874263 C3.84289224,5.40732556 3.7875,5.20912262 3.7875,4.99985762 C3.7875,4.36473016 4.30237254,3.84985762 4.9375,3.84985762 C5.16968891,3.84985762 5.39015095,3.91817161 5.57808762,4.04457612 L6.13342218,4.41808916 L6.44429159,3.82540992 C6.71628766,3.30684356 7.254073,2.97485762 7.85098404,2.97485762 Z"
id="形状结合"
fill="#999999"
></path>
</g>
</svg>
</ng-template>

<ng-template #geometry>
<svg
viewBox="0 0 16 16"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@
<option value="twoWayArrow">twoWayArrow</option>
<option value="comment">comment</option>
<option value="roundComment">roundComment</option>
<option value="cloud">cloud</option>
</select>
</div>

Expand Down