API

Function attachControl

  • Attach orbit/zoom/pan controls to an ArcRotateCamera. Matches Babylon.js ArcRotateCameraPointersInput behavior with inertia:

    • Primary-button drag: rotate (alpha/beta) with momentum by default
    • Secondary-button drag: pan (shift target) with momentum by default
    • Wheel: zoom (radius) with momentum
    • Pinch: zoom (touch, direct — no inertia)

    Mouse and pen button actions can be configured independently through AttachControlOptions.pointerMappings. Touch and wheel behavior are fixed so remapping desktop pointer buttons cannot alter mobile gestures. Keyboard input is a separate opt-in installed by enableArcRotateKeyboardControls; mappings and sensitivities are configured through AttachControlOptions.keyboard.

    Input handlers accumulate into the camera's inertial offset properties. Inertia is applied each frame via scene._beforeRender (the engine's render loop); a scene is required for inertia, there is no standalone rAF fallback.

    Orbit/zoom limits are entirely opt-in via setCameraLimits; the camera self-clamps in its setters, so this loop carries no limit code.

    Camera stays plain data — this function reads/writes its properties.

    The returned function detaches everything this call attached: it removes the canvas DOM listeners (pointer/wheel/contextmenu/touch/gesture plus any listeners owned by installed input modules) and, when a scene was supplied, removes its _beforeRender inertia hook. It is idempotent — calling it more than once is safe (the hook is removed only if still present, and removing a DOM listener twice is a no-op).

    The controls are not automatically tied to the scene's lifetime. Passing a scene only enables inertia (it registers the per-frame hook); it does not register this cleanup for scene disposal. Because the DOM listeners live on the canvas rather than on the scene, disposeScene clears scene-owned state (including _beforeRender) but does not remove the canvas listeners added here. The caller owns the controls' lifetime and must detach them explicitly:

    const detachCameraControl = attachControl(camera, canvas, scene);
    // Later — detach controls yourself before/after disposing the scene:
    detachCameraControl();
    disposeScene(scene);

    To tie the controls to the scene so disposeScene(scene) also detaches them, register the returned cleanup with onSceneDispose:

    onSceneDispose(scene, attachControl(camera, canvas, scene));
    // Now disposeScene(scene) removes the canvas listeners too.

    Parameters

    Returns () => void

    A cleanup function that removes all canvas listeners and the _beforeRender inertia hook. Safe to call multiple times.