my proposal is to not use groups but transformations and events, which additionally has a flavor of analytical geometry.
First we start start with vectors vA0 and vB0 through the origin. These vectors are fixed, vA and vB will be translates of vA0 and vB0,
defined through the points pa1 (resp. pb1) and the translation [0, pa1] (resp. [0, pb1]).
The points pa2 and pb2 are free points having drag event listener which again move pa1 resp. pb1.
The only drawback is that only points can be dragged, not the arrows. Here is the code:
var a1 = [2,2],
a2 = [2,4],
b1 = [1,3],
b2 = [3,3],
c1 = [2,1],
c2 = [4,1],
vA0 = brd.create("arrow", [[0,0], [0,2]], {fixed: true, strokeColor:'gray'}),
vB0 = brd.create("arrow", [[0,0], [2,0]], {fixed: true, strokeColor:'gray'}),
tA = brd.create('transform', [()=>pa1.X(),()=>pa1.Y()], {type:'translate'}),
vA = brd.create("arrow", [vA0, tA]),
pb1 = brd.create("point", b1, {name:'B1', attractors: [pa1, pa2], label: {offset: [0, 10]}}),
tB = brd.create('transform', [()=>pb1.X(),()=>pb1.Y()], {type:'translate'}),
vB = brd.create("arrow", [vB0, tB]),
pb2 = brd.create("point", b2, {name: 'B2', attractors: [pa1, pa2], label: {offset: [0, 10]}}),
pc1 = brd.create("point", c1, {name:'C1', attractors: [pa1, pa2, pb1, pb2], label: {offset: [0, -10]}}),
pc2 = brd.create("point", c2, {name:'C2', attractors: [pa1, pa2, pb1, pb2], label: {offset: [0, -10]}}),
vC = brd.create("arrow", [pc1, pc2], {color: 'red'});
pa1.setAttribute({attractors: [pb1, pb2]});
pa2.setAttribute({attractors: [pb1, pb2]});
pa1.on('drag', function() {
pa2.moveTo([pa1.X(), pa1.Y() + 2]);
});
pa2.on('drag', function() {
pa1.moveTo([pa2.X(), pa2.Y() - 2]);
});
pb1.on('drag', function() {
pb2.moveTo([pb1.X() + 2, pb1.Y()]);
});
pb2.on('drag', function() {
pb1.moveTo([pb2.X() - 2, pb2.Y()]);
});