{
const renderer = new THREE.WebGLRenderer({antialias: true});
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableZoom = false;
controls.enablePan = false;
invalidation.then(() => (controls.dispose(), renderer.dispose()));
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
controls.addEventListener("change", () => {
renderer.render(scene, camera);
colorPositions.forEach((positionObject, i) => {
const clone = positionObject.group.clone();
const projectedVec = clone.position.project(camera);
const x = ( projectedVec.x + 1) * width / 2;
const y = ( Math.abs(projectedVec.y - 1)) * height / 2;
const indicatorElement = document.getElementById(`indicator-${i}`);
indicatorElement.style.left = `${x}px`
indicatorElement.style.top = `${y}px`
})
});
renderer.render(scene, camera);
const circleSize = 24;
return html`
<style>
.overlay {
position: absolute;
top: 0;
pointer-events: none;
width: 100%;
height: 100%;
}
.indicator {
position: absolute;
left: 0;
top: 0;
pointer-events: all;
}
.indicator-inner {
width: ${circleSize}px;
height: ${circleSize}px;
border-radius: ${circleSize / 2}px;
margin-left: -${circleSize / 2}px;
margin-top: -${circleSize / 2}px;
cursor: pointer;
}
}
</style>
<div style="width: ${width}px; height: ${height}px;">
${renderer.domElement}
<div class="overlay">
${colorPositions.map((positionObject, i) => {
const clone = positionObject.group.clone();
const projectedVec = clone.position.project(camera);
const x = ( projectedVec.x + 1) * width / 2;
const y = ( Math.abs(projectedVec.y - 1)) * height / 2;
return`
<div
class="indicator"
style="left: ${x}px; top: ${y}px;"
id="indicator-${i}"
>
<div
class="indicator-inner"
style="background-color: ${positionObject.color}"
>${positionObject.color}</div>
</div>
`;
})}
</div>
</div>
` ;
}