CylinderLink

DragControls

HTML

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/controls/DragControls.js"></script>
<script type="x-shader/x-vertex" id="vertexShader">
		uniform float scaleZ;
    uniform vec3 pos;
		uniform vec4 rotation;
    
    vec3 rotateVector(vec4 q, vec3 v) {
    	return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
		}

    void main() {
    		vec3 scale = vec3( 1, 1, scaleZ );
    		vec3 vPos = rotateVector(rotation, position * scale ) + pos;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(vPos, 1.0);
    }
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
    void main() {
        gl_FragColor = vec4(1.0, 1.0, 0.0, 0.0);
    }
</script>

CSS

body {
  overflow: hidden;
  margin: 0;
  padding: 0;
}

JavaScript

var camera, scene, renderer;
var cube1, cube2;
var link;

init();
animate();

function init() {

  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.set(1, 1, 1);
  //camera.lookAt(scene.position);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  controls = new THREE.OrbitControls(camera, renderer.domElement);

  //fill the scene
  scene.add(new THREE.GridHelper(10,20));
  scene.add(new THREE.AxisHelper());
  
	var cubegeom = new THREE.BoxGeometry(0.5, 0.5, 0.5);
  cube1 = new THREE.Mesh(cubegeom, new THREE.MeshBasicMaterial({color: 'red'}));
  cube1.position.set(0, 1, 1);
  scene.add(cube1);
	cube2 = new THREE.Mesh(cubegeom, new THREE.MeshBasicMaterial({color: 'red'}));
	cube2.position.set(3, 1, 1);
  scene.add(cube2);

	var linkGeom = new THREE.CylinderGeometry(0.12, 0.12, 1);
  //var linkGeom = new THREE.BoxGeometry(0.1, 0.75, 1);
	linkGeom.rotateX(Math.PI / 2);
	//link = new THREE.Mesh(linkGeom, new THREE.MeshBasicMaterial({color: "yellow"}));
  
  const m = new THREE.Matrix4();
	var up = new THREE.Vector3(0, 1, 0);
  m.lookAt(cube2.position, cube1.position, up);
	var rotation = new THREE.Quaternion();
  rotation.setFromRotationMatrix(m);
  var scaleZ = cube1.position.distanceTo(cube2.position);
  
  const midPoint = new THREE.Vector3();
  midPoint.copy( cube1.position ).add( cube2.position ).divideScalar( 2 );
  
  var material = new THREE.ShaderMaterial({
		uniforms: {
    	'pos': { type: 'v3', value: midPoint },
			'rotation': { type: 'v4', value: rotation },
      'scaleZ': { type: 'f', value: scaleZ }
    }, 
    vertexShader: document.getElementById('vertexShader').textContent, 
    fragmentShader: document.getElementById('fragmentShader').textContent 
    });
  
  link = new THREE.Mesh(linkGeom, material);
  scene.add(link);
}

function...