getSelectionPoints()

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,
    ];
  }