x3dom:5.移动实体(在坐标系里位置变化)

参考的案例: https://www.x3dom.org/x3dom/example/MovingObjectsWithDOMEvents.html
在这里插入图片描述
源码:

<!DOCTYPE html>
<html style='width:100%; height:100%; border:0; margin:0; padding:0;'>
  
  <head>    
    <meta http-equiv='X-UA-Compatible' content='chrome=1'></meta>
    <meta http-equiv='Content-Type' content='text/html;charset=utf-8'></meta>
    <title>Moving Objects with DOM Mouse Events</title>
    
    <link rel='stylesheet' type='text/css' href='x3dom.css'></link>
    <script type='text/javascript' src='x3dom.js'></script>      
    
    <!--small script that implements the dragging functionality-->
    <script>
        var cellSize = 1.0;
        
        var lastMouseX = -1;
        var lastMouseY = -1;
        
        var draggedTransformNode = null;
        
        //vectors in 3D world space, associated to mouse x/y movement on the screen
        var draggingUpVec    = null;
        var draggingRightVec = null;
        
        var unsnappedDragPos = null;

        
        //------------------------------------------------------------------------------------------------------------------
        
        var mouseMoved = function(event)
        {
            //offsetX / offsetY polyfill for FF
            var target = event.target || event.srcElement;
            var rect = target.getBoundingClientRect();
            event.offsetX = event.clientX - rect.left;
            event.offsetY = event.clientY - rect.top;
        
            if (lastMouseX === -1)
            {
                lastMouseX = event.offsetX;
            }
            if (lastMouseY === -1)
            {
                lastMouseY = event.offsetY;
            }

            if (draggedTransformNode)
            {
               dragObject(event.offsetX - this.lastMouseX, event.offsetY - this.lastMouseY);
            }

            lastMouseX = event.offsetX;
            lastMouseY = event.offsetY;
        };
        
        //------------------------------------------------------------------------------------------------------------------
        
        var startDragging = function(transformNode)
        {        
            //disable navigation during dragging
            document.getElementById("navInfo").setAttribute("type", '"NONE"');
                       
            draggedTransformNode = transformNode;            
            unsnappedDragPos     = new x3dom.fields.SFVec3f.parse(transformNode.getAttribute("translation"));
            
            
            //compute the dragging vectors in world coordinates
            //(since navigation is disabled, those will not change until dragging has been finished)

            //get the viewer's 3D local frame
            var x3dElem  = document.getElementById("x3dElement");
            var vMatInv  = x3dElem.runtime.viewMatrix().inverse();            
            var viewDir  = vMatInv.multMatrixVec(new x3dom.fields.SFVec3f(0.0, 0.0, -1.0));
            
            //use the viewer's up-vector and right-vector
            draggingUpVec    = vMatInv.multMatrixVec(new x3dom.fields.SFVec3f(0.0, 1.0,  0.0));;
            draggingRightVec = viewDir.cross(this.draggingUpVec);   

            
            //project a world unit to the screen to get its size in pixels            
            var x3dElem  = document.getElementById("x3dElement");
            var p1 = x3dElem.runtime.calcCanvasPos(unsnappedDragPos.x, unsnappedDragPos.y, unsnappedDragPos.z);
            var p2 = x3dElem.runtime.calcCanvasPos(unsnappedDragPos.x + draggingRightVec.x,
                                                   unsnappedDragPos.y + draggingRightVec.y,
                                                   unsnappedDragPos.z + draggingRightVec.z)
            var magnificationFactor = 1.0 / Math.abs(p1[0] - p2[0]);
            
            //scale up vector and right vector accordingly            
            draggingUpVec    = draggingUpVec.multiply(magnificationFactor);
            draggingRightVec = draggingRightVec.multiply(magnificationFactor);            
        };

        //------------------------------------------------------------------------------------------------------------------

        var dragObject = function(dx, dy)
        {
            //scale up vector and right vector accordingly            
            var offsetUp    = draggingUpVec.multiply(-dy);
            var offsetRight = draggingRightVec.multiply(dx);

            unsnappedDragPos = unsnappedDragPos.add(offsetUp).add(offsetRight);

            var snappedDragPos;

            //if enabled, take grid snapping into account
            if (document.getElementById("snapCheckbox").checked)
            {
                snappedDragPos = new x3dom.fields.SFVec3f(cellSize * Math.ceil(unsnappedDragPos.x / cellSize),
                                                          cellSize * Math.ceil(unsnappedDragPos.y / cellSize),
                                                          cellSize * Math.ceil(unsnappedDragPos.z / cellSize));
                draggedTransformNode.setAttribute("translation", snappedDragPos.toString());
            }
            else
            {
                draggedTransformNode.setAttribute("translation", unsnappedDragPos.toString());
            }
        }

        //------------------------------------------------------------------------------------------------------------------

        var stopDragging = function()
        {
            draggedTransformNode = null;                
            draggingUpVec        = null;
            draggingRightVec     = null;
            unsnappedDragPos     = null;
            
            //re-enable navigation after dragging
            document.getElementById("navInfo").setAttribute("type", '"EXAMINE" "ANY"');
        };        
    </script>
  </head>
  
  <body style='width:100%; height:100%; border:0; margin:0; padding:0; background: linear-gradient(Grey 0%, White 100%);'>
    
    <div style="position:fixed;background:white;padding:16px;opacity:0.8;width:480px;z-index:10000">        
        <h1>DOM鼠标事件:移动实体</h1>
        
        <p style="font-size:140%">
            此例展示如何实现基础的3维交互,只是用少量的html和js代码
        <br/>
        因此,简单的 <strong>拖拽</strong>功能便实现了
        </p>
        
        <input id="snapCheckbox" type="checkbox"></input><span style="font-size:140%">Snap to grid(对齐到网格)</span>
        
    </div>
    
    <x3d id='x3dElement' style='width:100%; height:100%; border:0'        
        onmouseup  ="stopDragging();"
        "mouseMoved(event);">
      <scene> 
      
        <!--view and navigation-->        
        <viewpoint position="5.09349 5.61586 13.27088" orientation="-0.71805 0.68885 0.09947 0.51301"></viewpoint>	
        <navigationInfo id="navInfo" type='"EXAMINE" "ANY"' typeParams="-0.4, 60, 0.5, 1.55"></navigationInfo>
      
      
        <!--grid-->
        <inline url="scene/grid_20x20.x3d"></inline>
        
        
        <!--axes-->
        <transform translation="0 0.002 0.0">
            <inline url="scene/axis.x3d"></inline>
        </transform>
        
        
        <!--models-->
        <transform translation="-2 0 1" onmousedown="startDragging(this);">
            <inline url="scene/suzanne-ao-bg.x3d"></inline>
        </transform>
        
        <transform translation="0 1 -6" onmousedown="startDragging(this);">
            <shape>
                <appearance>
                    <material diffuseColor="1 0.5 0" specularColor="0.3 0.3 0.3"></material>
                </appearance>
                <cone></cone>
            <shape>
        </transform>
        
        <transform translation="4 0 0" onmousedown="startDragging(this);">
            <shape>
                <appearance>
                    <material diffuseColor="0 0.7 0.5" specularColor="0.3 0.3 0.3"></material>
                </appearance>
                <sphere></sphere>
            <shape>
        </transform>       
        
      </scene>
    </x3d>
    
  </body>
  
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值