Skip to content

Commit

Permalink
#5055 - Fixing multitail arrow design
Browse files Browse the repository at this point in the history
  • Loading branch information
daniil-sloboda authored and rrodionov91 committed Sep 2, 2024
1 parent d0cbde8 commit 3edb26c
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 22 deletions.
37 changes: 26 additions & 11 deletions packages/ketcher-core/src/application/render/pathBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ export class PathBuilder {
return this;
}

addLine(to: Point2D): PathBuilder;
addLine(to: Point2D, from: Point2D): PathBuilder;

addLine(to: Point2D, from?: Point2D): PathBuilder {
if (from) {
this.addMovement(from);
Expand All @@ -36,18 +33,20 @@ export class PathBuilder {
return this;
}

addClosedLine(to: Point2D, from?: Point2D): PathBuilder {
this.addLine(to, from);
const index = this.pathParts.length - 1;
this.pathParts[index] = this.pathParts[index].concat('Z');
return this;
}

addQuadraticBezierCurve(control: Point2D, to: Point2D): PathBuilder {
this.pathParts.push(
`Q${PathBuilder.generatePoint(control)} ${PathBuilder.generatePoint(to)}`,
);
return this;
}

addPathParts(pathParts: Array<string>): PathBuilder {
this.pathParts = this.pathParts.concat(pathParts);
return this;
}

addOpenArrowPathParts(
start: Vec2,
arrowLength: number,
Expand All @@ -59,16 +58,32 @@ export class PathBuilder {
const tipX = endX - tipXOffset;

return this.addLine(end, start)
.addLine({ x: tipX, y: start.y - tipYOffset })
.addLine({ x: tipX, y: start.y + tipYOffset }, end);
.addLine({ x: tipX, y: end.y - tipYOffset })
.addLine({ x: tipX, y: end.y + tipYOffset }, end);
}

addFilledTriangleArrowPathParts(
start: Vec2,
arrowLength: number,
triangleLength = 8,
triangleWidth = 4,
): PathBuilder {
const endX = start.x + arrowLength;
const end = new Vec2(endX, start.y);
const triangleBottom = new Vec2(endX - triangleLength, end.y);
const tipX = endX - triangleLength;

return this.addLine(start, triangleBottom)
.addLine({ x: tipX, y: end.y - triangleWidth }, end)
.addClosedLine({ x: tipX, y: end.y + triangleWidth });
}

addMultitailArrowBase(
topY: number,
bottomY: number,
spineX: number,
tailLength: number,
cubicBezierOffset = 3,
cubicBezierOffset = 6,
): PathBuilder {
const tailX = spineX - tailLength;
const tailStart = spineX - cubicBezierOffset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type RenderOptions = {

/* styles */
lineattr: RenderOptionStyles;
multitailArrow: RenderOptionStyles;
arrowSnappingStyle: RenderOptionStyles;
bondSnappingStyle: RenderOptionStyles;
selectionStyle: RenderOptionStyles;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export class ReMultitailArrow extends ReObject {
show(reStruct: ReStruct, renderOptions: RenderOptions) {
reStruct.clearVisel(this.visel);
const pathBuilder = new PathBuilder();
const headPathBuilder = new PathBuilder();
const {
topTailPosition,
topSpinePosition,
Expand All @@ -83,16 +84,20 @@ export class ReMultitailArrow extends ReObject {
topSpinePosition.x,
topTailOffsetX,
);
pathBuilder.addOpenArrowPathParts(arrowStart, arrowLength);
headPathBuilder.addFilledTriangleArrowPathParts(arrowStart, arrowLength);
tails.forEach((tail) => {
pathBuilder.addLine(tail, { x: topSpinePosition.x, y: tail.y });
});

const path = reStruct.render.paper.path(pathBuilder.build());
path.attr({
...renderOptions.lineattr,
const header = reStruct.render.paper.path(headPathBuilder.build());
path.attr(renderOptions.multitailArrow);
header.attr({
...renderOptions.multitailArrow,
fill: '#000',
});
this.visel.add(path, Box2Abs.fromRelBox(util.relBox(path.getBBox())));
this.visel.add(header, Box2Abs.fromRelBox(util.relBox(header.getBBox())));
}

calculateDistanceToPoint(
Expand Down
11 changes: 6 additions & 5 deletions packages/ketcher-core/src/domain/entities/multitailArrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ export interface MultitailArrowsReferenceLines {
export class MultitailArrow extends BaseMicromoleculeEntity {
static fromTwoPoints(topLeft: Vec2, bottomRight: Vec2) {
const center = Vec2.centre(topLeft, bottomRight);
const spineTop = new Vec2(center.x, topLeft.y);
const spineX = topLeft.x + (bottomRight.x - topLeft.x) * 0.33;
const spineTop = new Vec2(spineX, topLeft.y);
const headOffset = new Vec2(bottomRight.x, center.y).sub(spineTop);
return new MultitailArrow(
spineTop,
bottomRight.y - topLeft.y,
headOffset,
center.x - topLeft.x,
spineX - topLeft.x,
new Pool<number>(),
);
}
Expand Down Expand Up @@ -74,7 +75,7 @@ export class MultitailArrow extends BaseMicromoleculeEntity {
getReferenceLines(
referencePositions: MultitailArrowsReferencePositions,
): MultitailArrowsReferenceLines {
const spineX = referencePositions.topTailPosition.x;
const spineX = referencePositions.topSpinePosition.x;
const headSpinePosition = new Vec2(
spineX,
referencePositions.headPosition.y,
Expand All @@ -87,11 +88,11 @@ export class MultitailArrow extends BaseMicromoleculeEntity {
return {
topTail: [
referencePositions.topTailPosition,
referencePositions.topTailPosition,
referencePositions.topSpinePosition,
],
bottomTail: [
referencePositions.bottomTailPosition,
referencePositions.bottomTailPosition,
referencePositions.bottomSpinePosition,
],
spine: [
referencePositions.topSpinePosition,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type MultitailArrowAddDragContext = InitialDragContext | ProgressDragContext;

export class MultitailArrowAddTool implements ArrowAddTool {
static MIN_HEIGHT = 2.5;
static MIN_WIDTH = 1;
static MIN_WIDTH = 1.25;

// private dragContext: MultitailArrowAddDragContext | null = null;

Expand Down Expand Up @@ -57,7 +57,8 @@ export class MultitailArrowAddTool implements ArrowAddTool {
}

mouseup(event: MouseEvent) {
const start = CoordinateTransformation.pageToModel(event, this.render);
const click = CoordinateTransformation.pageToModel(event, this.render);
const start = new Vec2(click.x, click.y - MultitailArrowAddTool.MIN_HEIGHT);
const end = this.getArrowWithMinimalSizeEnd(start);

this.editor.update(fromMultitailArrowCreation(this.reStruct, start, end));
Expand Down
2 changes: 1 addition & 1 deletion packages/ketcher-react/src/script/ui/action/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ const toolActions = {
isHidden(options, 'reaction-arrow-elliptical-arc-arrow-open-half-angle'),
},
[MULTITAIL_ARROW_TOOL_NAME]: {
title: 'Multitail Arrow',
title: 'Multi-Tail Arrow',
action: {
tool: 'reactionarrow',
opts: MULTITAIL_ARROW_TOOL_NAME,
Expand Down

0 comments on commit 3edb26c

Please sign in to comment.