Appearance
控制器(新版)
v2.10.x 版本之后发布了全新的控制器,增加了属性配置、方法、事件等。
并且重构了相机相关的所有方法。setCameraViewpoint、flyToObj 等方法内部都是基于控制器的方法实现。
所有的属性读写、方法调用、事件监听都推荐以下方式。
js
const { controls } = ssp;
// 修改属性
controls.enabled = true;
controls.minDistance = 3;
// 读取属性
controls.active;
// 方法调用
controls.rotateAzimuthTo(Math.PI / 2, true);
// 事件监听
controls.addEventListener('update', () => {
console.log('控制器相机发生变化');
});术语
Orbit 旋转
控制器使用球坐标进行轨道旋转。
Dolly 和 Zoom
- Dolly 实际上是移动相机来改变每一帧中图像的组成(移动)。
- Zoom 包括改变镜头焦距。Zoom 实际上是改变相机的 FOV,而相机是静止的(不移动)。

Truck 和 Pan
- Truck 相机上下左右的平移操作。
- Pan 原地保持不动,只转动镜头。类似第一人称的操作。

属性
样例:
| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| enabled | 启用控制器 | boolean | true | |
| camera | 当前被控制的相机 | 透视或正交相机 | [内置相机] | |
| active | 当前控制器是否是激活状态 | boolean | [只读] | |
| currentAction | 当前 `ACTION` | ACTION | [只读] | |
| distance | 相机 `position` 与 `target` 的距离 | number | ||
| minDistance | Dolly 的最小距离,这个值必须大于0 | number | Number.EPSILON | |
| maxDistance | Dolly 的最大距离 | number | Infinity | |
| minZoom | Zoom 的最小值 | number | 0.01 | |
| maxZoom | Zoom 的最大值 | number | Infinity | |
| polarAngle | 当前的极角弧度 | number | ||
| minPolarAngle | 最小极角弧度 | number | 0 | |
| maxPolarAngle | 最大极角弧度 | number | Math.PI | |
| azimuthAngle | 当前的方位角弧度 | number | ||
| minAzimuthAngle | 最小方位角弧度 | number | -Infinity | |
| maxAzimuthAngle | 最大方位角弧度 | number | Infinity | |
| boundaryFriction | 边界摩擦比 | number | 0 | |
| boundaryEnclosesCamera | 相机位置是否应该被封闭在边界内 | boolean | false | |
| smoothTime | 到达目标的过渡时间,以秒为单位。数值越小,到达目标的速度越快 | number | 0.25 | |
| draggingSmoothTime | 操控时的过渡时间 | number | 0.1 | |
| maxSpeed | 最大速度 | number | Infinity | |
| azimuthRotateSpeed | 方位角旋转速度 | number | 0.5 | |
| polarRotateSpeed | 极角旋转速度 | number | 0.5 | |
| dollySpeed | 鼠标滚轮时的相机移动速度 | number | 0.2 | |
| truckSpeed | 平移速度 | number | 1 | |
| verticalDragToForward | 拖拽时是否前后移动,默认为上下 | boolean | false | |
| dollyToCursor | 是否以光标点为 Dolly 目标 | boolean | false | |
| dollyDragInverted | 当通过拖动触发 Dolly 和 Zoom 时反转方向 | boolean | false | |
| interactiveArea | 在domElement中设置拖拽、触摸和滚轮启用区域。每个值都在0到1之间,其中0表示屏幕的左/上,1表示屏幕的右/下 | DOMRect | ||
| colliderMeshes | 与相机碰撞的场景对象 | Object3D[] | [] | |
| infinityDolly | 启用无限 Dolly。与minDistance和maxDistance一起使用 | boolean | false | |
| restThreshold | 相机减速时rest事件触发的速度 | number | 0.0025 |
- 角度与弧度的相互转换推荐使用
MathUtils
js
import { MathUtils } from 'three';
// 角度转弧度
360 * MathUtils.DEG2RAD;
// 弧度转弧度
Math.PI * MathUtils.RAD2DEG;- 每当 360 度的旋转被添加到
azimuthAngle时,这是累积的。360º = 360 * MathUtils.DEG2RAD = Math.PI * 2,720º = Math.PI * 4。
js
// 将 azimuthAngle 限制到 0 - Math.PI * 2 之间
controls.normalizeRotations();
console.log(controls.azimuthAngle);- 注意
colliderMeshes可能会降低性能。碰撞测试使用来自相机的 4 个光线投射器,因为近平面有 4 个角。 - 如果 Dolly 的距离小于(或大于)minDistance (或 maxDistance ),则 infinityDolly 将保持距离并推动目标(target)位置。
事件
controls 发出以下事件。
订阅方式:通过 controls.addEventListener( 'eventname', function )
如需取消订阅:请使用 controls.removeEventListener( 'eventname', function )
| 事件名称 | 触发时机 |
|---|---|
'controlstart' | 当用户开始通过鼠标或手指操作时 |
'control' | 当用户正在操作时 |
'controlend' | 用户结束操作时 |
'transitionstart' | 任意过渡开始时,用户操作或方法调用 enableTransition = true |
'update' | 当相机 position 发生变化 |
'wake' | 当相机开始移动时 |
'rest' | 当相机将要停止时 由 restThreshold 控制 |
'sleep' | 当相机结束移动 |
mouseButtons.wheel(鼠标滚轮控制)不发出controlstart和controlend。mouseButtons.wheel在内部使用滚动事件,并且滚动事件间歇性地发生。这意味着无法检测到 start 和 end。由于阻尼,
sleep通常会在相机看起来已经停止移动的几秒钟后触发。如果你想在相机停止的时候做一些事情(例如,启用 UI,执行另一个过渡),你可能想要rest事件。这可以使用restthreshold参数进行微调。
用户操作配置
ACTION 常量请从 SoonSpace 中获取
js
import SoonSpace from 'soonspacejs';
const { ACTION } = SoonSpace;
controls.mouseButtons.left = ACTION.ROTATE;
controls.mouseButtons.right = ACTION.TRUCK;
controls.touches.one = ACTION.TOUCH_ROTATE;
controls.touches.two = ACTION.TOUCH_DOLLY_TRUCK;表格中 * 表示默认值
| 鼠标键位 | 行为 |
|---|---|
mouseButtons.left | ACTION.ROTATE* | ACTION.TRUCK | ACTION.OFFSET | ACTION.DOLLY | ACTION.ZOOM | ACTION.NONE |
mouseButtons.right | ACTION.ROTATE | ACTION.TRUCK* | ACTION.OFFSET | ACTION.DOLLY | ACTION.ZOOM | ACTION.NONE |
mouseButtons.wheel | ACTION.ROTATE | ACTION.TRUCK | ACTION.OFFSET | ACTION.DOLLY* | ACTION.ZOOM | ACTION.NONE |
mouseButtons.middle | ACTION.ROTATE | ACTION.TRUCK | ACTION.OFFSET | ACTION.DOLLY* | ACTION.ZOOM | ACTION.NONE |
mouseButtons.wheel的默认行为是:DOLLY用于PerspectiveCameraZOOM用于OrthographicCamera, 并且无法设置DOLLY.
| 触控操作 | 行为 |
|---|---|
touches.one | ACTION.TOUCH_ROTATE* | ACTION.TOUCH_TRUCK | ACTION.TOUCH_OFFSET | ACTION.DOLLY |
touches.two | ACTION.TOUCH_DOLLY_TRUCK | ACTION.TOUCH_DOLLY_OFFSET | ACTION.TOUCH_DOLLY_ROTATE | ACTION.TOUCH_ZOOM_TRUCK | ACTION.TOUCH_ZOOM_OFFSET | ACTION.TOUCH_ZOOM_ROTATE | ACTION.TOUCH_DOLLY | ACTION.TOUCH_ZOOM | ACTION.TOUCH_ROTATE | ACTION.TOUCH_TRUCK | ACTION.TOUCH_OFFSET | ACTION.NONE |
touches.three | ACTION.TOUCH_DOLLY_TRUCK | ACTION.TOUCH_DOLLY_OFFSET | ACTION.TOUCH_DOLLY_ROTATE | ACTION.TOUCH_ZOOM_TRUCK | ACTION.TOUCH_ZOOM_OFFSET | ACTION.TOUCH_ZOOM_ROTATE | ACTION.TOUCH_ROTATE | ACTION.TOUCH_TRUCK | ACTION.TOUCH_OFFSET | ACTION.NONE |
touches.two和touches.three的默认行为分别是:TOUCH_DOLLY_TRUCK用于PerspectiveCameraTOUCH_ZOOM_TRUCK用于OrthographicCamera,并且无法设置TOUCH_DOLLY_TRUCK和TOUCH_DOLLY
方法
样例:
enableTransition = true 时,调整 controls.smoothTime 控制过渡时间
rotate
旋转方位角(水平)和极角(垂直)。每个值都被添加到当前值中。
定义
ts
function rotate(
azimuthAngle: number,
polarAngle: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| azimuthAngle | 方位角旋转(弧度) | number | ||
| polarAngle | 极角旋转(弧度) | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
如果只是要旋转其中一个轴,只需将另一个参数设置为 0
js
controls.rotate(Math.PI / 4, 0, true);rotateAzimuthTo
将方位角(水平)旋转到给定角度,并保持的极角(垂直)不变。
定义
ts
function rotateAzimuthTo(
azimuthAngle: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| azimuthAngle | 方位角旋转(弧度) | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
rotatePolarTo
将极角(垂直)旋转到给定角度,并保持的方位角(水平)不变。
定义
ts
function rotatePolarTo(
polarAngle: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| polarAngle | 极角旋转(弧度) | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
rotateTo
将极角(垂直)和方位角(水平)旋转到给定角度
方位角
0º
\
90º -----+----- -90º
\
180º0º 表示朝向前方, 90º (Math.PI / 2) 表示朝向左边, -90º (- Math.PI / 2) 朝向右边, 180º (Math.PI) 朝向背面
极角
180º
|
90º
|
0º180º (Math.PI) 表示朝向天空/天花板, 90º (Math.PI / 2) 是水平, 0º 朝向地面/地板
定义
ts
function rotateTo(
azimuthAngle: number,
polarAngle: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| azimuthAngle | 方位角旋转(弧度) | number | ||
| polarAngle | 极角旋转(弧度) | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
dolly
将相机拉进或拉远
负值将拉远
定义
ts
function dolly(distance: number, enableTransition?: boolean): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| distance | 拉进(远)的距离 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
dollyTo
将相机拉进或拉远到给定的距离
定义
ts
function dollyTo(distance: number, enableTransition?: boolean): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| distance | 给定的拉进(远)的距离 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
dollyInFixed
将相机拉进或拉远,但不改变目标(target)和相机之间的距离,而是移动目标(target)的位置。
样例
定义
ts
function dollyInFixed(
distance: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| distance | 拉进(远)的距离(target) | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
zoom
相机变焦,该值添加到相机 zoom 属性上。
定义
ts
function zoom(zoomStep: number, enableTransition?: boolean): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| zoomStep | 变焦比例 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
你可以直接读取相机的 zoom 属性实现 in/out
js
const zoomIn = () => controls.zoom(controls.camera.zoom / 2, true);
const zoomOut = () => controls.zoom(-controls.camera.zoom / 2, true);zoomTo
相机变焦,该值会覆盖相机 zoom 属性。
通过设置 minZoom 和 maxZoom 限制
定义
ts
function zoomTo(zoomStep: number, enableTransition?: boolean): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| zoomStep | 变焦比例 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
truck( x, y, enableTransition )
基于当前方位角平移
定义
ts
function truck(x: number, y: number, enableTransition?: boolean): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| x | 水平偏移量 | number | ||
| y | 垂直偏移量 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
lookInDirectionOf
看向给定点的方向
只改变相机的 position
定义
ts
function lookInDirectionOf(
x: number,
y: number,
z: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| x | x 位置 | number | ||
| y | y 位置 | number | ||
| z | z 位置 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
setFocalOffset
使用屏幕平行坐标设置焦点偏移
相机的旋转中心点不变
定义
ts
function setFocalOffset(
x: number,
y: number,
z: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| x | x 位置 | number | ||
| y | y 位置 | number | ||
| z | z 位置 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
setOrbitPoint
设置旋转中心点
相机的位置和朝向不变,一般配合 setFocalOffset 方法使用
定义
ts
function setOrbitPoint(
targetX: number,
targetY: number,
targetZ: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| targetX | 旋转 x 位置 | number | ||
| targetY | 旋转 y 位置 | number | ||
| targetZ | 旋转 z 位置 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
forward
向前或向后移动
定义
ts
function forward(distance: number, enableTransition?: boolean): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| distance | 移动距离 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
moveTo
移动 target 到给定的点,position 到 target 的距离不会改变
相机的 position 和 朝向都会改变
定义
ts
function moveTo(
x: number,
y: number,
z: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| x | x 位置 | number | ||
| y | y 位置 | number | ||
| z | z 位置 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
elevate( height, enableTransition )
上下移动
定义
ts
function elevate(height: number, enableTransition?: boolean): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| height | 移动距离 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
fitToBox
使用相机最近的轴将视口与对象的包围盒或 Box3 对齐
flyToObj 方法基于此方法实现
定义
ts
interface FitToOptions {
cover: boolean;
paddingLeft: number;
paddingRight: number;
paddingBottom: number;
paddingTop: number;
}
function fitToBox(
box3OrObject: Box3 | Object3D,
enableTransition: boolean,
{
cover,
paddingLeft,
paddingRight,
paddingBottom,
paddingTop,
}?: Partial<FitToOptions>
): Promise<void[]>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| box3OrObject | 场景对象或 Box3 | Box3 | Object3D | ||
| enableTransition | 是否开启平滑过渡 | boolean | false | |
| options | 选项 | boolean | {} |
options
| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| cover | 是否填满屏幕 | boolean | false | |
| paddingLeft | 左侧填充距离 | number | 0 | |
| paddingRight | 右侧填充距离 | number | 0 | |
| paddingBottom | 底部填充距离 | number | 0 | |
| paddingTop | 顶部填充距离 | number | 0 |
fitToSphere
将视口与对象包围球匹配
定义
ts
function fitToSphere(
sphereOrMesh: Sphere | Object3D,
enableTransition: boolean
): Promise<void[]>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| sphereOrMesh | 场景对象或 Sphere | Sphere | Object3D | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
setLookAt
从 position 看向 target
setCameraViewpoint 方法基于此方法实现
定义
ts
function setLookAt(
positionX: number,
positionY: number,
positionZ: number,
targetX: number,
targetY: number,
targetZ: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| positionX | x 位置 | number | ||
| positionY | x 位置 | number | ||
| positionZ | x 位置 | number | ||
| targetX | 朝向 x 位置 | number | ||
| targetY | 朝向 y 位置 | number | ||
| targetZ | 朝向 z 位置 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
lerpLookAt
类似于 setLookAt,不过是基于两个状态之间插值
定义
ts
function lerpLookAt(
positionAX: number,
positionAY: number,
positionAZ: number,
targetAX: number,
targetAY: number,
targetAZ: number,
positionBX: number,
positionBY: number,
positionBZ: number,
targetBX: number,
targetBY: number,
targetBZ: number,
t: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| positionAX | 原始 x 位置 | number | ||
| positionAY | 原始 x 位置 | number | ||
| positionAZ | 原始 x 位置 | number | ||
| targetAX | 原始朝向 x 位置 | number | ||
| targetAY | 原始朝向 y 位置 | number | ||
| targetAZ | 原始朝向 z 位置 | number | ||
| positionBX | 插值 x 位置 | number | ||
| positionBY | 插值 x 位置 | number | ||
| positionBZ | 插值 x 位置 | number | ||
| targetBX | 插值朝向 x 位置 | number | ||
| targetBY | 插值朝向 y 位置 | number | ||
| targetBZ | 插值朝向 z 位置 | number | ||
| t | 插值系数,必须在 0 - 1 之间 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
setPosition
设置相机 position,但会保持相机仍然看向 target
相机的位置和朝向都会改变
类似于 setLookAt,但是 target 保留
定义
ts
function setPosition(
positionX: number,
positionY: number,
positionZ: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| positionX | x 位置 | number | ||
| positionY | x 位置 | number | ||
| positionZ | x 位置 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
setTarget
设置 target
相机的位置不会改变,会朝向新的目标点
类似于 setLookAt,但是 position 保留
定义
ts
function setTarget(
targetX: number,
targetY: number,
targetZ: number,
enableTransition?: boolean
): Promise<void>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| targetX | 朝向 x 位置 | number | ||
| targetY | 朝向 y 位置 | number | ||
| targetZ | 朝向 z 位置 | number | ||
| enableTransition | 是否开启平滑过渡 | boolean | false |
setBoundary
设置摄像机 target 的边界框,target 无法超出这个边界
定义
ts
function setBoundary(box3?: Box3): void;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| box3 | 限制区域的 box3 | Box3 |
box3可以通过以下方法获取
js
// 或者手动创建
import { Box3 } from 'three';
const box3 = new Box3();
// 获取3d对象的box3
const objectBox3 = ssp.utils.getBoundingBox(object);setViewport
设置画面的展示区域
定义
ts
function setBoundary(x: number, y: number, width: number, height: number): void;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| x | 视口的最左边位置 | number | ||
| y | 视口的最底部位置 | number | ||
| width | 视口的宽度 | number | ||
| height | 视口的高度 | number |
getTarget
返回当前 target
getCameraViewpoint 方法基于此方法实现
定义
ts
function getTarget(out?: Vector3, receiveEndValue?: boolean): Vector3;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| out | 接收数据的 Vector3 | number | ||
| receiveEndValue | 是否获取过渡结束的值 | number | true |
getPosition
返回当前 position
getCameraViewpoint 方法基于此方法实现
定义
ts
function getPosition(out?: Vector3, receiveEndValue?: boolean): Vector3;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| out | 接收数据的 Vector3 | number | ||
| receiveEndValue | 是否获取过渡结束的值 | number | true |
getSpherical( out, receiveEndValue )
返回轨道的球坐标。
定义
ts
function getSpherical(out?: Spherical, receiveEndValue?: boolean): Spherical;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| out | 接收数据的 Spherical | number | ||
| receiveEndValue | 是否获取过渡结束的值 | number | true |
getFocalOffset( out, receiveEndValue )
返回焦点偏移量,这是相机在屏幕平行坐标中平移的程度。
定义
ts
function getFocalOffset(out?: Vector3, receiveEndValue?: boolean): Vector3;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| out | 接收数据的 Vector3 | number | ||
| receiveEndValue | 是否获取过渡结束的值 | number | true |
saveState()
保存当前状态
定义
ts
function saveState(): void;normalizeRotations()
格式化方位角旋转角度到 0° - 360° 之间
定义
ts
function normalizeRotations(): void;reset
重置回默认状态,可以配合 saveState 使用
定义
ts
function reset(enableTransition?: boolean): Promise<void[]>;| 属性 | 描述 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| enableTransition | 是否开启平滑过渡 | boolean | false |
addEventListener( type: string, listener: function )
添加一个事件监听
js
const updateHandler = (event) => {
event.type; // update
};
// 添加一个事件监听
controls.addEventListener('update', updateHandler);
// 移除一个事件监听
controls.removeEventListener('update', updateHandler);
// 移除该类型所有的事件监听
controls.removeAllEventListeners('update');removeEventListener( type: string, listener: function )
移除一个事件监听
removeAllEventListeners( type: string )
移除所有改类型的事件监听