0

Could someone help me understand what I am doing wrong here please. I doing some particles in three.js and I want to pop-up a tooltip at the mouse position using the d3-annotation extension from Susie Lu. The annotation (if I understand correctly) looks to be created, however it is stuck at the top-left corner of the screen, it doesnt follow the mouse.

Inside the dev-tools for example, under elements, when I move the mouse I see a transform like transform="translate(728, 1168)", the annotation however remains stuck at [0, 0], the top left corner.

Maybe I am missing something really basic but i got stuck on this for 2days now.

Any help massively appreciated

<!DOCTYPE html>
<html>
<head>
    <title>Title</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r124/three.min.js"></script>
    <script src='https://unpkg.com/three@0.124.0/examples/js/controls/OrbitControls.js'></script>
    
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://rawgit.com/susielu/d3-annotation/master/d3-annotation.min.js"></script>

</head>
<body>


<div>
<!--    <svg id='example1' style="position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; "></svg>-->
    <canvas class="webgl">
        <svg id='example1' style="position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; "></svg>
    </canvas>
</div>

<script>
const mouse = new THREE.Vector2()

const canvas = document.querySelector('canvas.webgl')
const scene = new THREE.Scene()

const particleGeometry = new THREE.BufferGeometry()
const count = 10000

const positions = new Float32Array(count * 3)
const colors = new Float32Array(count * 3)
for (let i=0; i<count*3; i++){
    positions[i] = (Math.random() - 0.5) * 4
    colors[i] = Math.random()
}

particleGeometry.setAttribute(
    'position', new THREE.BufferAttribute(positions, 3),
)

particleGeometry.setAttribute(
     'color', new THREE.BufferAttribute(colors, 3)
)


const particlesMaterial = new THREE.PointsMaterial()
particlesMaterial.size = 0.01
particlesMaterial.vertexColors = true

const particles = new THREE.Points(particleGeometry, particlesMaterial)
scene.add(particles)

const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})

// mouse move
window.addEventListener('mousemove', onMouseMove, false);

function onMouseMove(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  console.log('x: ' + mouse.x + 'y: ' + mouse.y)

  if (d3.select('.anno-capture').empty()){
    svg = d3.select("#example1")
    svg.append("g")
      .attr("class", "annotation-group")
      .append("rect")
      .attr("class","anno-capture")
      .attr("width","900px")
      .attr("height","900px")
      }
      annotate(mouse)
   }

function annotate(coords){
    console.log('in annotate')
    console.log('x:' + coords.x + ' y: ' + coords.y)
    const anno_template = [{
        note: {
            title:"This is the title",
            bgPadding: 5,
            label:"x:" + coords.x + " y:" + coords.y,
        },
        x:coords.x,
        y:coords.y,
        dx:20,
        dy:20
    }];

    const make_anno= d3.annotation()
        .type(d3.annotationCallout)
        .annotations(anno_template)
        .editMode(true)

    d3.select('.annotation-group')
      .call(make_anno)
}
  
camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.z = 3

controls = new THREE.OrbitControls(camera, canvas)
controls.enableDamping = true

const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

const clock = new THREE.Clock()

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()
    controls.update()
    renderer.render(scene, camera)
    window.requestAnimationFrame(tick)
}

tick()
</script>


</body>
</html>
Aenaon
  • 3,169
  • 4
  • 32
  • 60

0 Answers0