mousemove()

in packages/ketcher-react/src/script/editor/tool/template.ts [302:444]


  mousemove(event) {
    if (!this.dragCtx) {
      this.editor.hover(
        this.editor.findItem(event, this.findItems),
        null,
        event,
      );

      this.templatePreview?.movePreview(event);

      return true;
    }

    if (this.isSaltOrSolvent) {
      delete this.dragCtx.item;
      return true;
    }

    const eventPosition = this.editor.render.page2obj(event);
    const dragCtx = this.dragCtx;
    const ci = dragCtx.item;
    let targetPos: Vec2 | null | undefined = null;
    /* moving when attached to bond */
    if (ci && ci.map === 'bonds' && !this.isModeFunctionalGroup) {
      const bond = this.struct.bonds.get(ci.id);
      let sign = getSign(this.struct, bond, eventPosition);

      if (dragCtx.sign1 * this.template.sign > 0) {
        sign = -sign;
      }

      if (sign !== dragCtx.sign2 || !dragCtx.action) {
        if (dragCtx.action) {
          dragCtx.action.perform(this.editor.render.ctab);
        } // undo previous action

        dragCtx.sign2 = sign;
        const [action, pasteItems] = fromTemplateOnBondAction(
          this.editor.render.ctab,
          this.template,
          ci.id,
          this.editor.event,
          dragCtx.sign1 * dragCtx.sign2 > 0,
          false,
        ) as Array<any>;

        dragCtx.action = action;
        this.editor.update(dragCtx.action, true);

        dragCtx.mergeItems = getItemsToFuse(this.editor, pasteItems);
        this.editor.hover(getHoverToFuse(dragCtx.mergeItems));
      }
      return true;
    }
    /* end */

    let extraBond: boolean | null = null;
    // calc initial pos and is extra bond needed
    if (!ci) {
      //  ci.type == 'Canvas'
      targetPos = dragCtx.xy0;
    } else if (ci.map === 'atoms' || ci.map === 'functionalGroups') {
      const atomId = getTargetAtomId(this.struct, ci);

      if (atomId !== undefined) {
        const atom = this.struct.atoms.get(atomId);
        targetPos = atom?.pp;

        if (targetPos) {
          extraBond = this.isModeFunctionalGroup
            ? true
            : Vec2.dist(targetPos, eventPosition) > 1;
        }
      }
    }

    if (!targetPos) {
      return true;
    }

    // calc angle
    let angle = vectorUtils.calcAngle(targetPos, eventPosition);

    if (!event.ctrlKey) {
      angle = vectorUtils.fracAngle(angle, null);
    }

    const degrees = vectorUtils.degrees(angle);
    this.editor.event.message.dispatch({ info: degrees + 'º' });

    // check if anything changed since last time
    if (
      // eslint-disable-next-line no-prototype-builtins
      dragCtx.hasOwnProperty('angle') &&
      dragCtx.angle === degrees &&
      // eslint-disable-next-line no-prototype-builtins
      (!dragCtx.hasOwnProperty('extra_bond') ||
        dragCtx.extra_bond === extraBond)
    ) {
      return true;
    }

    // undo previous action
    if (dragCtx.action) {
      dragCtx.action.perform(this.editor.render.ctab);
    }

    // create new action
    dragCtx.angle = degrees;
    let action: Action | null = null;

    if (!ci) {
      const isAddingFunctionalGroup = this.template?.molecule?.sgroups.size;
      if (isAddingFunctionalGroup) {
        // skip, b/c we dont want to do any additional actions (e.g. rotating for s-groups)
        return true;
      }
      [action] = fromTemplateOnCanvas(
        this.editor.render.ctab,
        this.template,
        targetPos,
        angle,
      );
    } else if (ci?.map === 'atoms' || ci?.map === 'functionalGroups') {
      const atomId = getTargetAtomId(this.struct, ci);
      [action] = fromTemplateOnAtom(
        this.editor.render.ctab,
        this.template,
        atomId,
        angle,
        extraBond,
      );
      dragCtx.extra_bond = extraBond;
    }
    dragCtx.action = action;

    this.editor.update(dragCtx.action, true);

    // TODO: refactor after #2195 comes into effect
    if (this.targetGroupsIds.length) this.targetGroupsIds.length = 0;

    return true;
  }