in packages/ketcher-core/src/application/render/restruct/rebond.ts [140:252]
getSelectionPoints(render: Render, isHighlight = false) {
// please refer to: ketcher-core/docs/data/hover_selection_1.png
const bond: Bond = this.b;
const { ctab: restruct, options } = render;
const { bondThickness, bondSpacingInPx, stereoBondWidth } = options;
const regularSelectionThikness = bondSpacingInPx + bondThickness;
// get half-bond positions, this is where the actual bond
// image on the screen is drawn, it may be different e.g. if the
// bond is connected to an atom with a label as opposed
// to when it is connected to a Carbon atom w/o a label
// please refer to: ketcher-core/docs/data/hover_selection_2.png
const halfBondStart = restruct.molecule.halfBonds.get(bond.hb1!)!.p;
const halfBondEnd = restruct.molecule.halfBonds.get(bond.hb2!)!.p;
const isStereoBond =
bond.stereo !== Bond.PATTERN.STEREO.NONE &&
bond.stereo !== Bond.PATTERN.STEREO.CIS_TRANS;
const highlightPadding = isHighlight ? -1 : 0;
const stereoPadding = isStereoBond ? 0 : -2;
const addPadding = highlightPadding + stereoPadding;
// find the points on the line where we will be drawing the curves
const contourStart = Vec2.getLinePoint(
halfBondEnd,
halfBondStart,
addPadding,
);
const contourEnd = Vec2.getLinePoint(
halfBondStart,
halfBondEnd,
addPadding,
);
const stereoBondStartHeightCoef = 0.5;
const bondPadding = 0.5;
const highlightBondPadding = isHighlight ? 0 : 2;
const addStart =
(isStereoBond
? stereoBondWidth * stereoBondStartHeightCoef
: regularSelectionThikness + bondPadding) + highlightBondPadding;
const stereoBondEndHeightCoef = 1;
const addEnd =
(isStereoBond
? stereoBondWidth +
(regularSelectionThikness * stereoBondEndHeightCoef) / stereoBondWidth
: regularSelectionThikness + bondPadding) + highlightBondPadding;
const contourPaddedStart = Vec2.getLinePoint(
contourStart,
contourEnd,
addEnd,
);
const contourPaddedEnd = Vec2.getLinePoint(
contourEnd,
contourStart,
addStart,
);
// we need four points for each bezier curve
// and two for each line that together form the selection contour
// the padded values are for the curve points and the rest of
// the values are for drawing the lines
// please refer to: ketcher-core/docs/data/hover_selection_3.png
const startPoint = contourStart.add(new Vec2(addEnd, 0));
const endPoint = contourEnd.add(new Vec2(addStart, 0));
const padStartPoint = contourPaddedStart.add(new Vec2(addEnd, 0));
const padEndPoint = contourPaddedEnd.add(new Vec2(addStart, 0));
const { angle } = bond;
// rotate the points +/-90 degrees to find the
// perpendicular points that will be used for actual drawing
// of selection contour on canvas
const startTop = startPoint.rotateAroundOrigin(
angle + 90,
new Vec2(contourStart.x, contourStart.y),
);
const startBottom = startPoint.rotateAroundOrigin(
angle - 90,
new Vec2(contourStart.x, contourStart.y),
);
const startPadTop = padStartPoint.rotateAroundOrigin(
angle + 90,
contourPaddedStart,
);
const startPadBottom = padStartPoint.rotateAroundOrigin(
angle - 90,
contourPaddedStart,
);
const endTop = endPoint.rotateAroundOrigin(angle + 90, contourEnd);
const endBottom = endPoint.rotateAroundOrigin(angle - 90, contourEnd);
const endPadTop = padEndPoint.rotateAroundOrigin(
angle + 90,
contourPaddedEnd,
);
const endPadBottom = padEndPoint.rotateAroundOrigin(
angle - 90,
contourPaddedEnd,
);
return [
startPadTop,
startTop,
endTop,
endPadTop,
endPadBottom,
endBottom,
startPadBottom,
startBottom,
];
}