I’m creating a network diagram using three. So far I’ve been able to do:
- Added 2 objects which are my network devices
- Add a link between the two devices using a line
- Add device interface labels using canvas and sprites.
- I’m able to move the devices around the scene and update the line positions
My issue is:
-When adding the interface labels I need to align them on the line between network devices. I want them aligned halfway between the line boundingSphere.center and the network devices which will represent each devices local connecting interface.
NOTE: I’m using dragControls for the scene
Simple Example:
[object]----[label/sprite]------[boundingSpere.center]-----[label/sprite]----[object]
Basic Scene:
The only way ive got close was to create two new lines using the BoundingSphere of the line between network devices and the boundingBox of min/max of the new line. This almost gave me what i need positioning became and issue depending on the line direction.
Code:
export const setLinkLabels = (linkLabelOne, linkLabelTwo,
multiSelect, line, position, postion2) => {
linkLabelOne.direction = 'from'
linkLabelOne.to = multiSelect.current[0].uuid
linkLabelOne.position.x = position.center.x
linkLabelOne.position.y = position.center.y
linkLabelTwo.direction = 'to'
linkLabelTwo.to = multiSelect.current[1].uuid
linkLabelTwo.position.x = postion2.center.x
linkLabelTwo.position.y = postion2.center.y
}
export const canvas = (deviceName) => {
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
const ctx = canvas.getContext("2d");
if (deviceName === 'interface') {
ctx.font = "20pt Arial"
} else {
ctx.font = "33pt Arial"
}
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.strokeStyle = "black";
ctx.lineWidth = 8;
if (deviceName !== undefined) {
ctx.strokeText(deviceName, 128, 46);
ctx.fillText(deviceName, 128, 46);
} else {
ctx.strokeText('device', 128, 46);
ctx.fillText('device', 128, 46);
}
return canvas
}
const addLink = (operation) => {
const points = [];
const group = new THREE.Group()
group.isLine = true
points.push(multiSelect.current[0].position);
points.push(multiSelect.current[1].position);
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({color: 0xffffff, depthTest: false});
const line = new THREE.Line(geometry, material);
line.links = {from: multiSelect.current[0].uuid, to: multiSelect.current[1].uuid}
line.renderOrder = 0
line.geometry.attributes.position.needsUpdate = true;
line.geometry.computeBoundingBox();
line.geometry.computeBoundingSphere();
let tempPoints = []
tempPoints.push(new THREE.Vector3(line.geometry.boundingBox.max.x, line.geometry.boundingBox.max.y, 0));
tempPoints.push(new THREE.Vector3(line.geometry.boundingSphere.center.x, line.geometry.boundingSphere.center.y, 0));
const tempGeometry = new THREE.BufferGeometry().setFromPoints(tempPoints);
const tempMaterial = new THREE.LineBasicMaterial();
const Templine = new THREE.Line(tempGeometry, tempMaterial);
Templine.geometry.computeBoundingSphere();
tempPoints = []
tempPoints.push(new THREE.Vector3(line.geometry.boundingBox.min.x, line.geometry.boundingBox.min.y, 0));
tempPoints.push(new THREE.Vector3(line.geometry.boundingSphere.center.x, line.geometry.boundingSphere.center.y, 0));
const tempGeometry1 = new THREE.BufferGeometry().setFromPoints(tempPoints);
const tempMaterial1 = new THREE.LineBasicMaterial();
const Templine1 = new THREE.Line(tempGeometry1, tempMaterial1);
Templine1.geometry.computeBoundingSphere();
//
const linkLabelOne = modifyDeviceName(multiSelect.current[0].interface, 'dynamicBuilder', multiSelect.current[0].position)
const linkLabelTwo = modifyDeviceName(multiSelect.current[1].interface, 'dynamicBuilder', multiSelect.current[1].position)
setLinkLabels(linkLabelOne, linkLabelTwo, multiSelect, Templine.geometry.boundingSphere, Templine1.geometry.boundingSphere)
multiSelect.current.push(linkLabelOne)
multiSelect.current.push(linkLabelTwo)
group.add(linkLabelOne, linkLabelTwo)
}
I’m thinking though there has to be a better way if if the code above was modified to work. I’ve thought of getting the line angle and distance to place the labels.
Any nudge in the right direction would help