You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Forge Viewer:模型加载时自动启动指定对象动画

How to Auto-Start a Looping Animation for a Specific Revit Element in Forge Viewer

Absolutely! You can totally pull this off with Forge Viewer's core API—no extra extensions needed, just some custom JavaScript code. Let me walk you through how to make that cube slide back and forth on the ground automatically once your model finishes loading.

Step 1: Wait for the Model to Fully Load

First, you need to trigger the animation only after all model geometry is ready. Use the Autodesk.Viewing.GEOMETRY_LOADED_EVENT—this fires when the viewer has finished loading all the model's data, so you can safely access and modify elements.

Step 2: Grab Your Target Cube by Revit Element ID

Revit Element IDs are stored as "external IDs" in Forge. To get the viewer's internal object ID for your cube, you'll need to format the Revit ID with a specific prefix, then use model.getObjectIdsByExternalId() to fetch it.

Step 3: Build the Looping Animation Logic

Use requestAnimationFrame to create a smooth, continuous animation loop. You'll track the cube's position, reverse direction when it hits your desired boundary, and update its transform every frame. Keep the Y-axis fixed to make sure it stays on the ground.

Full Working Code Snippet

Here's a complete example you can drop into your existing Viewer setup:

// Assume 'viewer' is your initialized Forge Viewer instance
let animationFrameId = null;
let targetObjectId = null;
let currentPos = { x: 0, y: 0, z: 0 };
let moveDir = 1; // 1 = forward, -1 = backward
const moveSpeed = 0.05; // Adjust based on your model's scale
const maxTravelDistance = 10; // How far the cube moves before turning around

// Listen for when the model's geometry is fully loaded
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, (event) => {
    const loadedModel = event.model;
    // Replace this with your actual Revit Element ID
    const revitElementId = "12345";
    // Format the Revit ID into Forge's external ID format
    const externalId = `urn:revit:element:${revitElementId}:${loadedModel.getData().modelId}`;

    // Get the viewer's internal object ID for the cube
    const objectIds = loadedModel.getObjectIdsByExternalId(externalId);
    if (objectIds.length === 0) {
        console.error("Oops—couldn't find the element with Revit ID:", revitElementId);
        return;
    }
    targetObjectId = objectIds[0];

    // Capture the cube's initial position to keep Y fixed (ground level)
    const fragmentList = loadedModel.getFragmentList();
    const fragmentIds = loadedModel.getFragmentIds()[targetObjectId];
    fragmentList.getWorldMatrix(fragmentIds[0], new THREE.Matrix4()).decompose(currentPos, new THREE.Quaternion(), new THREE.Vector3());

    // Kick off the animation loop
    startLoopAnimation();
});

function startLoopAnimation() {
    // Cancel any existing animation to avoid duplicates
    if (animationFrameId) cancelAnimationFrame(animationFrameId);

    function animateFrame() {
        if (!targetObjectId) return;

        // Update the cube's X position (adjust to Z if your ground is oriented differently)
        currentPos.x += moveSpeed * moveDir;

        // Reverse direction when the cube hits the distance limit
        if (Math.abs(currentPos.x) >= maxTravelDistance) {
            moveDir *= -1;
        }

        // Apply the new position to the cube
        const newTransform = new THREE.Matrix4().makeTranslation(currentPos.x, currentPos.y, currentPos.z);
        viewer.impl.editObjectTransform(targetObjectId, newTransform);

        // Schedule the next frame
        animationFrameId = requestAnimationFrame(animateFrame);
    }

    animateFrame();
}

// Optional: Function to stop the animation later
// function stopAnimation() {
//     if (animationFrameId) {
//         cancelAnimationFrame(animationFrameId);
//         animationFrameId = null;
//     }
// }

Quick Tips to Fine-Tune the Animation

  • Coordinate System: Forge uses a right-handed system—X = right, Y = up, Z = forward. If your ground runs along the Z-axis instead of X, just swap currentPos.x with currentPos.z in the code.
  • Scale Adjustments: If the cube moves too fast or slow, tweak the moveSpeed value. Adjust maxTravelDistance to control how far it goes before turning around.
  • Performance: This code only updates the target cube's transform each frame, so it won't bog down the viewer even with complex models.
  • Interaction: The animation will keep running even if users zoom, pan, or rotate the view—since it's modifying the cube's local transform relative to the model.

内容的提问来源于stack exchange,提问作者Mykita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:21:21