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.xwithcurrentPos.zin the code. - Scale Adjustments: If the cube moves too fast or slow, tweak the
moveSpeedvalue. AdjustmaxTravelDistanceto 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

