<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
</head>
<body>
<div id="mydiv" style="width: 600px;height: 500px;margin:auto;">
</div>
<script>
const pointer = new THREE.Vector2();
const raycaster = new THREE.Raycaster();
const WIDTH = 600;
const HEIGHT = 500;
const data = [
[55 + 10, 20],
[50 + 10, 10],
[60 + 10, 10],
[10 + 10, 20],
[40 + 10, 30],
[0 + 10, 40],
];
let maxY = 0n
data.forEach(d => {
if (d[0] + d[1] > maxY) {
maxY = d[0] + d[1]
}
});
var scene = new THREE.Scene();
const light = new THREE.DirectionalLight(0xffffff, 0.6)
light.lookAt(0, 0, 0)
light.position.setX(WIDTH + 300)
light.position.setY(0)
light.position.setZ(380)
scene.add(light);
const light2 = new THREE.DirectionalLight(0xffffff, 0.6)
light2.lookAt(0, 0, 0)
light2.position.setX(0)
light2.position.setY(HEIGHT + 400)
light2.position.setZ(400)
scene.add(light2);
const light3 = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light3);
const barWidth = Math.floor(WIDTH / data.length * 0.691 * 0.70721);
data.forEach((d, i) => {
const group = new THREE.Group()
let box1 = new THREE.BoxBufferGeometry(barWidth, HEIGHT / maxY * d[0], barWidth, 1, 1, 1)
let box2 = new THREE.BoxBufferGeometry(barWidth, HEIGHT / maxY * d[1], barWidth, 1, 1, 1)
box1.computeBoundingBox();
box2.computeBoundingBox();
const count = box1.attributes.position.count;
const color1 = new THREE.Color()
const color2 = new THREE.Color()
box1.addAttribute('color', new THREE.BufferAttribute(new Float32Array(count * 3), 3));
box2.addAttribute('color', new THREE.BufferAttribute(new Float32Array(count * 3), 3));
const colors1 = box1.attributes.color;
const colors2 = box2.attributes.color;
for (let i = 0; i < count; i++) {
const x = box1.attributes.position.getX(i);
const y = box1.attributes.position.getY(i);
const z = box1.attributes.position.getZ(i);
//console.log(i, x, y, z)
if (y > 0) {
color1.setHex(0x1C8CFF)
color2.setHex(0x00FFC2)
} else {
color1.setHex(0x093783)
color2.setHex(0x117B5C)
}
colors1.setXYZ(i, color1.r, color1.g, color1.b)
colors2.setXYZ(i, color2.r, color2.g, color2.b)
}
const material1 = new THREE.MeshLambertMaterial({
transparent: true,
opacity: 0.91,
// side: THREE.DoubleSide,
vertexColors: THREE.VertexColors
})
const boxMesh1 = new THREE.Mesh(box1, material1)
const boxMesh2 = new THREE.Mesh(box2, material1.clone())
boxMesh1.morphTargetInfluences
boxMesh2.position.y = HEIGHT / maxY * d[0] / 2 + HEIGHT / maxY * d[1] / 2
group.add(boxMesh1)
group.add(boxMesh2)
group.position.x = i * WIDTH / data.length + (WIDTH / data.length / 2)
group.position.y = HEIGHT / maxY * d[0] / 2
group.position.z = -barWidth / 2
group.rotateY(-Math.PI / 4)
scene.add(group);
})
// var axes = new THREE.AxisHelper(1030);
// scene.add(axes);
const camera = new THREE.OrthographicCamera(0, WIDTH, HEIGHT, 0)
camera.position.z = 1000
camera.position.y = 412
camera.rotateX(-Math.PI / 8)
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
})
renderer.setSize(WIDTH, HEIGHT)
document.getElementById('mydiv').appendChild(renderer.domElement);
//document.body.appendChild(renderer.domElement);
const controls = new THREE.OrbitControls(camera, renderer.domElement)
const rayCastOrigin = new THREE.Vector3(WIDTH / 2, HEIGHT, 800)
let INTERSECTED = null;
function animate() {
requestAnimationFrame(animate)
rayCastOrigin.transformDirection
raycaster.setFromCamera(pointer, camera)
//console.log(scene.children,'scene.children');
const intersects = raycaster.intersectObjects(scene.children, true);
//console.log(intersects,'intersects');
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = intersects[0].object;
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex(0x444444);
}
} else {
if (INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = null;
}
controls.update()
renderer.render(scene, camera)
}
animate();
document.getElementById('mydiv').addEventListener('pointermove', e => {
pointer.x = (e.offsetX - WIDTH / 2) / (WIDTH / 2)
pointer.y = (e.offsetY - HEIGHT / 2) / (HEIGHT / 2) * -1
})
</script>
</body>
</html>