three视口助手的three-viewport-gizmo使用,类似于blender右上角的方向控件.
Three Viewport Gizmo官方Three.js视口助手的高度可定制的独立交互式版本,它可以单独使用,也可以与OrbitControls,TrackballControls或自定义摄像机控制器 (如 @ yomotsu/camera-controls) 结合使用。
例子
安装
npm install three-viewport-gizmo
用法
单独使用
将其与相机和渲染器实例一起使用,容器是包含画布的HTMLElement。
import { ViewportGizmo } from "three-viewport-gizmo";
const container = document.body;
const viewportGizmo = new ViewportGizmo(camera, renderer, options);
// Animation loop
function animate() {
viewportGizmo.render();
// ... Your animation logic
renderer.render(scene, camera);
}
混合 OrbitControls or TrackBallControls使用
要正确使用OrbitControls或TrackballControls,您需要按如下方式设置事件侦听器和动画循环。
import { ViewportGizmo } from "three-viewport-gizmo";
const container = document.body;
const viewportGizmo = new ViewportGizmo(camera, renderer, options);
const controls = new OrbitControls(camera, container);
viewportGizmo.target = controls.target;
// listeners
viewportGizmo.addEventListener("start", () => (controls.enabled = false));
viewportGizmo.addEventListener("end", () => (controls.enabled = true));
controls.addEventListener("change", () => {
viewportGizmo.update();
});
// Animation loop
function animate() {
viewportGizmo.render();
// ... Your animation logic
renderer.render(scene, camera);
// Update the OrbitControls
if (controls.enabled) controls.update();
}
和 @yomotsu/camera-controls
要使用相机控件设置three-viewport-gizmo,请设置事件侦听器和动画循环,如下面的示例所示。
import * as THREE from "three";
import { ViewportGizmo } from "three-viewport-gizmo";
import CameraControls from "camera-controls";
CameraControls.install({ THREE });
// init
const container = document.body;
const viewportGizmo = new ViewportGizmo(camera, renderer, options);
const controls = new CameraControls(camera, container);
// listeners
viewportGizmo.addEventListener("start", () => {
// Disable controls on change start
controls.enabled = false;
});
viewportGizmo.addEventListener("end", () => {
// Enable controls on change end
controls.enabled = true;
});
viewportGizmo.addEventListener("change", () => {
// Set the camera new position
controls.setPosition(...camera.position.toArray());
});
controls.addEventListener("update", () => {
// Update the the gizmo on controls update
controls.getTarget(viewportGizmo.target);
viewportGizmo.update();
});
// Animation loop
const clock = new THREE.Clock();
function animate() {
viewportGizmo.render();
// ... Your animation logic
renderer.render(scene, camera);
// Update the CameraControls
if (controls.enabled && !viewportGizmo.animating)
controls.update(clock.getDelta());
}
配置项
可以通过在初始化期间传递选项来自定义gizmo的外观和行为:
const options = {
container: HTMLElement;
size: number;
placement:
| "top-left"
| "top-right"
| "top-center"
| "center-right"
| "center-left"
| "center-center"
| "bottom-left"
| "bottom-right"
| "bottom-center";
lineWidth: number;
offset: {
left: number;
top: number;
right: number;
bottom: number;
};
backgroundSphere: {
enabled: boolean;
color: ColorRepresentation;
opacity: number;
};
font: {
family?: string;
weight?: string | number;
};
resolution: number;
x: GizmoAxisOptions;
y: GizmoAxisOptions;
z: GizmoAxisOptions;
nx: GizmoAxisOptions;
ny: GizmoAxisOptions;
nz: GizmoAxisOptions;
};
type GizmoAxisOptions = {
text?: string;
drawCircle?: boolean;
drawLine?: boolean;
border?: boolean;
colors: Partial<{
main: ColorRepresentation | [ColorRepresentation, ColorRepresentation];
hover?: ColorRepresentation;
text?: ColorRepresentation;
hoverText?: ColorRepresentation;
}>;
};
//示例:
{
"placement": "center-center",
"size": 736,
"lineWidth": 3,
"offset": {
"top": 0,
"left": 0,
"right": 0,
"bottom": 0
},
"font": {
"family": "helvetica",
"weight": 900
},
"resolution": 64,
"backgroundSphere": {
"enabled": true,
"color": 16777215,
"opacity": 0.2
},
"x": {
"text": "X",
"drawLine": true,
"border": false,
"colors": {
"main": "#ff7f9b",
"hover": "#ffffff",
"text": "#000000",
"hoverText": "#000000"
}
},
"y": {
"text": "Y",
"drawLine": true,
"border": false,
"colors": {
"main": "#c2ee00",
"hover": "#ffffff",
"text": "#000000",
"hoverText": "#000000"
}
},
"z": {
"text": "Z",
"drawLine": true,
"border": false,
"colors": {
"main": "#73c5ff",
"hover": "#ffffff",
"text": "#000000",
"hoverText": "#000000"
}
},
"nx": {
"text": "",
"drawLine": false,
"border": false,
"colors": {
"main": "#ff7f9b",
"hover": "#ffffff",
"text": "#000000",
"hoverText": "#000000"
}
},
"ny": {
"text": "",
"drawLine": false,
"border": false,
"colors": {
"main": "#c2ee00",
"hover": "#ffffff",
"text": "#000000",
"hoverText": "#000000"
}
},
"nz": {
"text": "",
"drawLine": false,
"border": false,
"colors": {
"main": "#73c5ff",
"hover": "#ffffff",
"text": "#000000",
"hoverText": "#000000"
}
}
}
const viewportGizmo = new ViewportGizmo(camera, renderer, options);