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>