原文鏈接: threejs 3d 動態螺旋線繪製 BufferGeometry 動態折線圖
主要思路是用BufferGeometry 繪製折線圖, 每次向點集中添加點的座標, 然後動態去修改
還是官網靠譜
https://threejs.org/docs/index.html#manual/en/introduction/How-to-update-things
http://www.yanhuangxueyuan.com/Three.js/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../build/three.js"></script>
<script src="../examples/js/controls/OrbitControls.js"></script>
</head>
<body>
<script>
const scene = new THREE.Scene();
const speed = 1; // 移動速度
const initX = 0;
const initY = 0;
const limit = 2000; // 點的個數限制
const radius = 100;
const MAX_POINTS = 5000;
// geometry
const geometry = new THREE.BufferGeometry();
// attributes
const positions = new Float32Array(MAX_POINTS * 3); // 3 vertices per point
geometry.setAttribute(
"position",
new THREE.BufferAttribute(positions, 3)
);
// draw range
const drawCount = 2; // draw the first 2 points, only
geometry.setDrawRange(0, 0);
// material
const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
// line
const line = new THREE.Line(geometry, material);
scene.add(line);
//點光源
const point = new THREE.PointLight(0xffffff);
point.position.set(0, 0, 300); //點光源位置
scene.add(point); //點光源添加到場景中
//環境光
const ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);
const width = window.innerWidth; //窗口寬度
const height = window.innerHeight; //窗口高度
const k = width / height; //窗口寬高比
const s = 200; //三維場景顯示範圍控制係數,係數越大,顯示的範圍越大
//創建相機對象
const camera = new THREE.OrthographicCamera(
-s * k,
s * k,
s,
-s,
1,
1000
);
camera.position.set(200, 200, 200); //設置相機位置
camera.lookAt(0, 0, 0); //設置相機方向(指向的場景對象)
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //設置渲染區域尺寸
renderer.setClearColor(0xb9d3ff, 1); //設置背景顏色
document.body.appendChild(renderer.domElement); //body元素中插入canvas對象
const axisHelper = new THREE.AxesHelper(500);
scene.add(axisHelper);
let degree = 0;
let z = 0;
let index = 0;
let count = 0;
function render() {
const positions = line.geometry.attributes.position.array;
if (index >= MAX_POINTS) {
return;
}
const d = (++degree * Math.PI) / 180;
const x = 200 * Math.cos(d);
const y = 200 * Math.sin(d);
z++;
const i = index * 3;
positions[i] = x;
positions[i + 1] = y;
positions[i + 2] = z;
index++;
line.geometry.setDrawRange(0, index);
line.geometry.attributes.position.needsUpdate = true; // required after the first render
renderer.render(scene, camera); //執行渲染操作
}
setInterval(render, 16);
const controls = new THREE.OrbitControls(camera, renderer.domElement); //創建控件對象
controls.addEventListener("change", render); //監聽鼠標、鍵盤事件
</script>
</body>
</html>