three视口助手的three-viewport-gizmo使用

798 阅读2分钟

three视口助手的three-viewport-gizmo使用,类似于blender右上角的方向控件.

1722301022097.png

three-viewport-gizmo.png

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);