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