Back to Tools and Commands

Node Move

The nodeMove command handles object movement inside the scene. To activate this command, call:



The default options are:

options: {
  displayGizmo: true,
  mode: 'free',

  //default plane is the x-z plane
  plane: {
    normal: { x: 0, y: 1, z: 0 }, //normal direction
    constant: 0, //distance to original
  surfaceNodeIds: [],
  onChange: undefined,
  onEnd: undefined,
  updatePosition: undefined,
  shouldMove: undefined,
  attach: undefined,
  keepOffset: true,


Control whether or not to display the widget around the selected node. The widget can be used to move the object along the x, y and z-axis.


The keepOffset option will maintain the offset between the mouse position and the node povit of the object the same while moving. If set to false, the node may have a jump if you are not dragging on the povit of the mesh when the moving start.


The attach option allows you attach meshes while moving. The following is an example of attach option

 attach: {
  models: [
      modelId: api.scene.find('Model'),
      attachPoints: [
          attachNodeId: api.scene.find('Left'),
          anchorNodeIds: api.scene.filter('AnchorRight*'),
          withRotation: true,
          attachDistance: 0.1,
          realtimeRotation: true,
          attachNodeId: api.scene.find('Right'),
          anchorNodeIds: api.scene.filter('AnchorLeft*'),
          withRotation: true,
          attachDistance: 0.3,
          realtimeRotation: false,
  alwaysAttach: true,

The models take an array to specify all the models that are considered to be able to attach. Each model contains a modelId and an array of attachPoint sets. Each attachPoint set has an attachNodeId, an array of anchorNodeIds, the attachDistance threshold and if the attach will also match the rotation or not. Please note each attachNode will only consider the anchorNodeId, using the threshold under the same set. For attachDistance, you can either specify a fixed value or leave it empty so that the distance will be adjusted based on the camera zoom. There will be potential model rotation during the movement if you set the withRotation to true. In this case, the relative position between the model and attachNode will change if the rotation happens, thus it will affect the further attachment. If you want to aviod it, simply set the realtimeRotation to false. When you do so, no matter how the model rotate during the moving, the relative position between attachNode and model will also keep the same as the move start.


There are three different modes: free, plane and surface. Corresponding to move node freely in the scene, move the node along a given plane, and move node on given objects' surface respectively.


An object representing a plane and only used when setting the mode to plane. See Move Node On Plane.


An array of node ids, used only when setting the mode to surface. See Move Node On Object.


The first custom function will be called at every single frame when an object is moving. The mouse event and new position (world space) of the node will be passed as first two arguments. In surface mode, target mesh surface information will be passed as the third argument. Return true/false to enable/disable the move in the current frame.

Note: The updatePosition and onChange will not the called if shouldMove return false.


The second custom function that will be called at each frame. The first parameter is the new position (world space) the node will be moved to. In surface mode, target mesh surface information will be passed as the second argument. To update the position, simply change the first argument direction.

// fix the node y coordinate while moving
function updatePosition(position) {
  position.y = 0;


A custom function that will be called at each frame after the node moved to the new position. It is a good place to get node new local transform. The mouse event is passed as the first argument. In surface mode, target mesh surface information will be passed as the second argument. See Attach Object. The tool state will be passed as the third argument. It could provide you the attach status if you are enable the attachment.


A custom function will be called at the end of the object movement. The mouse event and tool state will be passed as the arguments.

var opts = {
  onEnd: function(ev) {
    console.log('move end at', ev.clientX, ev.clientY);
setCommandOptions('nodeMove', opts);