1. 程式人生 > >JavaScript-X3DOM學習筆記(一)-世界座標

JavaScript-X3DOM學習筆記(一)-世界座標

快捷鍵r,可以重置觀察者viewpoint, 滑鼠左鍵是rotation,  中鍵是Pan.右鍵是forward/backward

這是執行效果圖


下面是html原始碼

<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta charset="utf-8">
    <title>測試X3DOM世界座標</title>
    <!-- 2018-3-14 by kagula -->

    <!-- x3dom用的是1.7.2dev -->
    <script type="text/javascript" src="/x3dom/x3dom.js"></script>

    <!-- d3用的是4.13.0 -->
    <script type="text/javascript" src='/d3/d3.min.js'></script>

    <link rel="stylesheet" type="text/css" href="/x3dom/x3dom.css">
</head>

<body>
    <x3d style="width:100%;height:600px">
        <scene>
        </scene>
    </x3d>
</body>


</html>

<script type="text/javascript">
    //Horizontal axis
    function drawAxisX(selectorRoot, countOfTick, lengthOfTick, heightOfTick)
    {
        var axisLength = countOfTick * lengthOfTick;

        //draw axis
        var linesetX = d3.select(selectorRoot).append("group").attr("id", "groupAxisX")
            .append("shape")
            .append("lineset").attr("vertexcount", "2");

        linesetX.append("coordinate").attr("point", d => "0 0 0, " + axisLength + " 0 0");
        linesetX.append("color").attr("color", "1 0 0, 1 0 0");

        //draw tick
        //第一個shape是axis,後面countOfTick個才是真正的刻度。
        let ticks = d3.range( countOfTick + 1 ).map(function (i) {
            return i; //i=[0,1,...,countOfTick]
        })
        d3.select("#groupAxisX").selectAll("lineset").data(ticks)
        .enter().append("shape").append("lineset").attr("vertexcount", "2")
        .append("coordinate").attr("point", d => d * lengthOfTick + " 0 0, " + d * lengthOfTick + " " + heightOfTick + " 0"); //因為第一個是axis,d的第一個元素被跳過,所以d=[1,2,..]

        //draw text
        d3.select("#groupAxisX").selectAll(".label").data(ticks)
        .enter().append("transform").classed("label", "true").attr("translation", d => (d * lengthOfTick + 0.6) + " " + (heightOfTick-0.5) + " 0")
        .append("billboard")
        .append("shape").classed("shapeAxisX", "true")
        .append("text").attr("string", d => d).attr("solid", "false")//正反兩面可見
        .append("fontstyle").attr("family", "yahei").attr("size", "1.2");

        //返回#groupAxisX子節點下面的子節點下面class為shapeAxisX的所有節點
        d3.select("#groupAxisX").selectAll(".shapeAxisX")
        .append("appearance")//新增appearance子節點
        .append("material").attr("diffuseColor","0 0 0");

        //draw arrow
        d3.select("#groupAxisX").append("transform").attr("translation", (axisLength+0.25) +" 0 0").attr("rotation", "0  0 1 " + (-3.14159)/2)
        .append("shape").attr("id", "xAxisArrow").append("cone").attr("height", "0.5").attr("bottomRadius", "0.1").attr("lit", "true");
        d3.select("#xAxisArrow").append("appearance").append("material").attr("diffuseColor",'1 0 0');
    }

    //Vertical axis
    function drawAxisY(selectorRoot, countOfTick, lengthOfTick, heightOfTick) {
        var axisLength = countOfTick * lengthOfTick;

        //draw axis
        var linesetY = d3.select(selectorRoot).append("group").attr("id", "groupAxisY")
            .append("shape")
            .append("lineset").attr("vertexcount", "2");

        linesetY.append("coordinate").attr("point", d => "0 0 0, 0 " + axisLength + " 0");
        linesetY.append("color").attr("color", "0 1 0, 0 1 0");


        //draw tick
        //第一個shape是axis,後面countOfTick個才是真正的刻度。
        let ticks = d3.range(countOfTick+1).map(function (i) {
            return i+1; //i=[0,1,...,countOfTick]
        })
        d3.select("#groupAxisY").selectAll("lineset").data(ticks)
        .enter().append("shape").append("lineset").attr("vertexcount", "2")
        .append("coordinate").attr("point", d => "0 " + ((d - 1) * lengthOfTick) + " 0, " + heightOfTick + " " + (d - 1) * lengthOfTick + " 0"); //因為第一個是axis,d的第一個元素被跳過,所以d=[1,2,..]

        //draw text
        ticks.splice(ticks.length-1,1);
        d3.select("#groupAxisY").selectAll(".label").data(ticks)
        .enter().append("transform").classed("label", "true").attr("translation", d =>  (0.8) + " " + (d * lengthOfTick + 1) + " 0")
        .append("billboard")
        .append("shape").classed("shapeAxisY", "true")
        .append("text").attr("string", d => d).attr("solid", "false")//正反兩面可見
        .append("fontstyle").attr("family", "yahei").attr("size", "1.2");

        //返回#groupAxisY子節點下面的子節點下面class為shapeAxisY的所有節點
        d3.select("#groupAxisY").selectAll(".shapeAxisY")
        .append("appearance")//新增appearance子節點
        .append("material").attr("diffuseColor", "0 0 0");
        
        //draw arrow
        d3.select("#groupAxisY").append("transform").attr("translation", "0 " + (axisLength + 0.25) + " 0")
        .append("shape").attr("id", "yAxisArrow").append("cone").attr("height", "0.5").attr("bottomRadius", "0.1").attr("lit", "true");
        d3.select("#yAxisArrow").append("appearance").append("material").attr("diffuseColor", '0 1 0');        
    }

    //Depth axis
    function drawAxisZ(selectorRoot, countOfTick, lengthOfTick, heightOfTick) {
        var axisLength = countOfTick * lengthOfTick;

        //draw axis
        var linesetY = d3.select(selectorRoot).append("group").attr("id", "groupAxisZ")
            .append("shape")
            .append("lineset").attr("vertexcount", "2");

        linesetY.append("coordinate").attr("point", d => "0 0 0, 0 0 " + axisLength);
        linesetY.append("color").attr("color", "0 0 1, 0 0 1");


        //draw tick
        //第一個shape是axis,後面countOfTick個才是真正的刻度。
        let ticks = d3.range(countOfTick + 1).map(function (i) {
            return i + 1; //i=[0,1,...,countOfTick]
        })
        d3.select("#groupAxisZ").selectAll("lineset").data(ticks)
        .enter().append("shape").append("lineset").attr("vertexcount", "2")
        .append("coordinate").attr("point", d => "0 0 " + ((d - 1) * lengthOfTick) + ", " + heightOfTick + " 0 " + (d - 1) * lengthOfTick); //因為第一個是axis,d的第一個元素被跳過,所以d=[1,2,..]

        //draw text
        ticks.splice(ticks.length - 1, 1);
        d3.select("#groupAxisZ").selectAll(".label").data(ticks)
        .enter().append("transform").classed("label", "true").attr("translation", d =>  (0.8) + " 1.0 " + (d * lengthOfTick + 1))
        .append("billboard")
        .append("shape").classed("shapeAxisZ", "true")
        .append("text").attr("string", d => d).attr("solid", "false")
        .append("fontstyle").attr("family", "yahei").attr("size", "1.2");        
        //返回#groupAxisY子節點下面的子節點下面class為shapeAxisY的所有節點
        d3.select("#groupAxisZ").selectAll(".shapeAxisZ")
        .append("appearance")//新增appearance子節點
        .append("material").attr("diffuseColor", "0 0 0");
        
        //draw arrow
        d3.select("#groupAxisZ").append("transform").attr("translation", "0 0 " + (axisLength + 0.25)).attr("rotation", "1 0 0 " + (3.14159) / 2)
        .append("shape").attr("id", "zAxisArrow").append("cone").attr("height", "0.5").attr("bottomRadius", "0.1").attr("lit", "true");
        d3.select("#zAxisArrow").append("appearance").append("material").attr("diffuseColor", '0 0 1');        
    }

    function drawAxis()
    {
        const selectorRoot = "scene";
        const countOfTick = 5;
        const lengthOfTick = 10;
        const heightOfTick = 2;

        drawAxisX(selectorRoot, countOfTick, lengthOfTick, heightOfTick);
        drawAxisY(selectorRoot, countOfTick, lengthOfTick, heightOfTick);
        drawAxisZ(selectorRoot, countOfTick, lengthOfTick, heightOfTick);
    }

    drawAxis();
</script>