美文网首页
3d世界拖拽物体,比如一个棋盘样式

3d世界拖拽物体,比如一个棋盘样式

作者: skoll | 来源:发表于2021-12-08 21:33 被阅读0次

1 .结合事件,做了鼠标hover,out改变物体属性的操作

<!DOCTYPE html>
<!-- 添加小人,使用序列图 -->
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
    <title>Babylon - Getting Started</title>
    <!-- Link to the last version of BabylonJS -->
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <!-- Link to the last version of BabylonJS loaders to enable loading filetypes such as .gltf -->
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <!-- Link to pep.js to ensure pointer events work consistently in all browsers -->
    <script src="https://code.jquery.com/pep/0.4.1/pep.js"></script>
</head>
<body>
    <canvas id="renderCanvas"></canvas>
</body>
</html>
As you can see, we inserted in the <body> a <canvas> element. This <canvas> element will be the place where we'll display the result of our 3D rendering. Insert some style in the <head>:

<style>
    html, body {
        overflow: hidden;
        width   : 100%;
        height  : 100%;
        margin  : 0;
        padding : 0;
    }

    #renderCanvas {
        width   : 100%;
        height  : 100%;
        touch-action: none;
    }
</style>
Now some javascript code to run our project. To begin with, insert at the end of your <body>:

<script>
    window.addEventListener('DOMContentLoaded', function() {
        var canvas = document.getElementById('renderCanvas');
        var engine = new BABYLON.Engine(canvas, true);

        var scene = function(){
            var scene = new BABYLON.Scene(engine);

            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.setPosition(new BABYLON.Vector3(20, 200, 400));
            camera.attachControl(canvas, true);

            camera.upperBetaLimit = (Math.PI / 2) * 0.99;
            var light = new BABYLON.PointLight("omni", new BABYLON.Vector3(50, 200, 0), scene);
            
            // 全部材质
            let groundMat=new BABYLON.StandardMaterial("ground",scene)
            groundMat.specularColor=BABYLON.Color3.Black()

            var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
            groundMaterial.specularColor = BABYLON.Color3.Black();

            var redMat = new BABYLON.StandardMaterial("ground", scene);
            redMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            redMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            redMat.emissiveColor = BABYLON.Color3.Red();

            var greenMat = new BABYLON.StandardMaterial("ground", scene);
            greenMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            greenMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            greenMat.emissiveColor = BABYLON.Color3.Green();

            var blueMat = new BABYLON.StandardMaterial("ground", scene);
            blueMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            blueMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            blueMat.emissiveColor = BABYLON.Color3.Blue();

            var purpleMat = new BABYLON.StandardMaterial("ground", scene);
            purpleMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            purpleMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            purpleMat.emissiveColor = BABYLON.Color3.Purple();

            // let ground=BABYLON.Mesh.CreateGround('ground',{width:500,height:500},scene)
            // 最后一个参数是是否可更新
            let ground=BABYLON.Mesh.CreateGround('ground',506,506,2,scene,false)
            // 也就是说他的新语法把旧的给拆出来了,旧的属性是在一个对象里面的,这里全都拿出来了
            ground.Material=groundMat

            var redSphere = BABYLON.MeshBuilder.CreateSphere("red", {diameter:20}, scene);
            redSphere.material = redMat;
            redSphere.position.y = 10;
            redSphere.position.x -= 100;

            var greenBox = BABYLON.MeshBuilder.CreateBox("green", {size:20}, scene);
            greenBox.material = greenMat;
            greenBox.position.z -= 100;
            greenBox.position.y = 10;

            var blueBox = BABYLON.MeshBuilder.CreateBox("blue", {size:20}, scene);
            blueBox.material = blueMat;
            blueBox.position.x += 100;
            blueBox.position.y = 10;

            var purpleDonut = BABYLON.MeshBuilder.CreateTorus("red", {diameter:30, thickness:10}, scene);
            purpleDonut.material = purpleMat;
            purpleDonut.position.y = 10;
            purpleDonut.position.z += 100;

            // 给你添加一个鼠标hover展示
            purpleDonut.actionManager = new BABYLON.ActionManager(scene);
            
            purpleDonut.actionManager.registerAction(
                new BABYLON.InterpolateValueAction(
                    BABYLON.ActionManager.OnPointerOverTrigger,
                    purpleDonut,
                    'visibility',
                    0.2,
                    500,
                )
            )

            purpleDonut.actionManager.registerAction(
                new BABYLON.InterpolateValueAction(
                    BABYLON.ActionManager.OnPointerOutTrigger,
                    purpleDonut,
                    'visibility',
                    1,
                    500,
                )
            )

            let startPosition
            // 定义开始拖拽时的位置

            let currentMesh
            // 定义当前拖拽的物体


           function groundPosition () {
                var pickinfo = scene.pick(scene.pointerX, scene.pointerY, function (mesh) { return mesh == ground; });
                // 启动一个射线,检测鼠标是否指向了这个物体
                // 创建可用于在场景中拾取的光线

                if (pickinfo.hit) {
                   return pickinfo.pickedPoint;
                 }
                return null;
            }
            // 根据屏幕上点击的坐标,返回在ground上的坐标

            function pointerDown(mesh){
                currentMesh=mesh

                startPosition=groundPosition()
                if(startPosition){
                    setTimeout(function () {
                        camera.detachControl(canvas);
                    }, 0);
                    // 他这里的操作是要取消摄像机和屏幕的关系,一会我们要做摄像机跟随拖拽物移动的操作
                }
            }

            function pointerUp(){
                if(startPosition){
                    camera.attachControl(canvas,true)
                    startPosition=null;
                    return
                }
            }

            function pointerMove(){
                if(!startPosition){
                    return;
                }

                let current=groundPosition()
                if(!current){
                    return;
                }

                let diff=current.subtract(startPosition)
                currentMesh.position.addInPlace(diff)
                startPosition=current
            }

            scene.onPointerObservable.add((pointerInfo)=>{
                switch(pointerInfo.type){
                    case BABYLON.PointerEventTypes.POINTERDOWN:
                        if(pointerInfo.pickInfo.hit&&pointerInfo.pickInfo.pickedMesh!=ground){
                            pointerDown(pointerInfo.pickInfo.pickedMesh)
                        }
                        break;
                    case BABYLON.PointerEventTypes.POINTERMOVE:
                        pointerMove()
                        break;
                    case BABYLON.PointerEventTypes.POINTERUP:
                        pointerUp()
                        break;
                }
            })
    
            return scene;
    }()


    engine.runRenderLoop(function() {
        scene.render();
    });

    window.addEventListener('resize', function() {
        engine.resize();
     });
});
</script>

相关文章

网友评论

      本文标题:3d世界拖拽物体,比如一个棋盘样式

      本文链接:https://www.haomeiwen.com/subject/rvgmjltx.html