@@ -472,6 +472,62 @@ export class DiscourseRelationUtil extends ShapeUtil<DiscourseRelationShape> {
472472 const atTranslationStart = shapeAtTranslationStart . get ( initialShape ) ;
473473 if ( ! atTranslationStart ) return ;
474474
475+ const bindings = getArrowBindings ( this . editor , shape ) ;
476+
477+ // If both ends are bound, convert translation to bend changes instead of moving the arrow
478+ if ( bindings . start && bindings . end ) {
479+ const shapePageTransform = this . editor . getShapePageTransform ( shape . id ) ;
480+ const pageDelta = Vec . Sub (
481+ shapePageTransform . applyToPoint ( shape ) ,
482+ atTranslationStart . pagePosition ,
483+ ) ;
484+
485+ const initialBindings = getArrowBindings ( this . editor , initialShape ) ;
486+ const { start : initialStart , end : initialEnd } =
487+ getArrowTerminalsInArrowSpace (
488+ this . editor ,
489+ initialShape ,
490+ initialBindings ,
491+ ) ;
492+
493+ const delta = Vec . Sub ( initialEnd , initialStart ) ;
494+ const v = Vec . Per ( delta ) ;
495+ const med = Vec . Med ( initialEnd , initialStart ) ;
496+
497+ const initialPageTransform = this . editor . getShapePageTransform (
498+ initialShape . id ,
499+ ) ;
500+ const arrowSpaceDelta = Vec . Rot (
501+ pageDelta ,
502+ - initialPageTransform . rotation ( ) ,
503+ ) ;
504+
505+ const translatedMidpoint = Vec . Add ( med , arrowSpaceDelta ) ;
506+ const A = Vec . Sub ( med , v ) ;
507+ const B = Vec . Add ( med , v ) ;
508+ const point = Vec . NearestPointOnLineSegment (
509+ A ,
510+ B ,
511+ translatedMidpoint ,
512+ false ,
513+ ) ;
514+
515+ // Calculate new bend based on distance from midpoint
516+ let newBend = Vec . Dist ( point , med ) ;
517+ if ( Vec . Clockwise ( point , initialEnd , med ) ) {
518+ newBend *= - 1 ;
519+ }
520+
521+ return {
522+ id : shape . id ,
523+ type : shape . type ,
524+ x : initialShape . x ,
525+ y : initialShape . y ,
526+ props : { bend : newBend } ,
527+ } ;
528+ }
529+
530+ // If not both ends are bound, use normal translation behavior
475531 const shapePageTransform = this . editor . getShapePageTransform ( shape . id ) ;
476532 const pageDelta = Vec . Sub (
477533 shapePageTransform . applyToPoint ( shape ) ,
@@ -540,6 +596,27 @@ export class DiscourseRelationUtil extends ShapeUtil<DiscourseRelationShape> {
540596 ) ;
541597 const shapePageTransform = this . editor . getShapePageTransform ( shape . id ) ;
542598
599+ // If both ends are bound, we'll convert translation to bend changes
600+ // So we don't need to update bindings or unbind
601+ if ( bindings . start && bindings . end ) {
602+ shapeAtTranslationStart . set ( shape , {
603+ pagePosition : shapePageTransform . applyToPoint ( shape ) ,
604+ terminalBindings : mapObjectMapValues (
605+ terminalsInArrowSpace ,
606+ ( terminalName , point ) => {
607+ const binding = bindings [ terminalName ] ;
608+ if ( ! binding ) return null ;
609+ return {
610+ binding,
611+ shapePosition : point ,
612+ pagePosition : shapePageTransform . applyToPoint ( point ) ,
613+ } ;
614+ } ,
615+ ) ,
616+ } ) ;
617+ return ;
618+ }
619+
543620 // If at least one bound shape is in the selection, do nothing;
544621 // If no bound shapes are in the selection, unbind any bound shapes
545622
0 commit comments