Published
Edited
May 21, 2021
Insert cell
Insert cell
{
const renderer = new THREE.WebGLRenderer({antialias: true});
const controls = new THREE.OrbitControls(camera, renderer.domElement);
invalidation.then(() => renderer.dispose());
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
let fraction = 0;
const up = new THREE.Vector3( 0, 1, 0 );
const axis = new THREE.Vector3( );
while (true) {
const newPosition = pointsPath.getPoint(fraction);
const tangent = pointsPath.getTangent(fraction);
arrow.position.copy(newPosition);
axis.crossVectors( up, tangent ).normalize();
const radians = Math.acos( up.dot( tangent ) );
arrow.quaternion.setFromAxisAngle( axis, radians );
renderer.render(scene, camera);
fraction +=0.001;
if (fraction > 1) {
fraction = 0;
}
yield renderer.domElement;
}
}
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
scene = {
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(arrow);
scene.add( path );
const axesHelper = new THREE.AxesHelper( 0.5 );
axesHelper.translateX(1);
scene.add( axesHelper );
return scene;
}
Insert cell
path = {
const material = new THREE.LineBasicMaterial({
color: 0x9132a8
});
const points = pointsPath.curves.reduce((p, d)=> [...p, ...d.getPoints(20)], []);
const geometry = new THREE.BufferGeometry().setFromPoints( points );

return new THREE.Line( geometry, material );
}
Insert cell
pointsPath = {
const pointsPath = new THREE.CurvePath();
const firstLine = new THREE.LineCurve3(
new THREE.Vector3( 1, 0, 0 ),
new THREE.Vector3( -1, 0, 0 )
);
const secondLine = new THREE.LineCurve3(
new THREE.Vector3(-1, 0, 0 ),
new THREE.Vector3( -1, 1, 0 )
);
const thirdLine = new THREE.LineCurve3(
new THREE.Vector3( -1, 1, 0 ),
new THREE.Vector3(-1, 1, 1 ),
);

const bezierLine = new THREE.CubicBezierCurve3(
new THREE.Vector3( -1, 0, 4 ),
new THREE.Vector3( -0.5, 0, 4 ),
new THREE.Vector3( 2.0, 0, 4 ),
new THREE.Vector3( -1, 0, 9 ),
new THREE.Vector3( -1, 0, 17 ),
new THREE.Vector3( -0.5, 0, 10 ),
new THREE.Vector3( 2.0, 0, 6 ),
new THREE.Vector3( -1, 0, 4),

);
const bezierLine2 = new THREE.CubicBezierCurve3(
new THREE.Vector3( 1, -1, -1 ),
new THREE.Vector3( 0.5, -1.5, -0 ),
new THREE.Vector3( -2.0, -1.5, -0 ),
new THREE.Vector3( 1, -0, -1 )
);
pointsPath.add(bezierLine);
return pointsPath;
}
Insert cell
arrow = {
//inject model
const material = new THREE.MeshNormalMaterial();
const coneGeom = new THREE.ConeGeometry(1, 2, 10);
coneGeom.translate(0, 2.5, 0);
const cone = new THREE.Mesh(coneGeom, material);
const cylinder = new THREE.CylinderGeometry(0.4, 0.6, 3, 10);
cylinder.merge(cone.geometry, cone.matrix);
cylinder.scale(0.05, 0.05, 0.05);
return new THREE.Mesh(cylinder, material);
}
Insert cell
camera = {
const fov = 45;
const aspect = width / height;
const near = 1;
const far = 10000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 0, -0.1);

return camera;
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more