樹木 3D|Trees 3D|HTML5

樹木 3D|Trees 3D|HTML5

樹木 3D|Trees 3D|HTML5|HTML5(HTML5, JavaScript, CSS3) : デモ

樹木 3D|Trees 3D|HTML5|HTML5(HTML5, JavaScript, CSS3) : ZIPファイル(4kb)

1.HTML

<!DOCTYPE html>
<html lang="jp">
    <head>
        <meta charset="UTF-8" />
        <title>樹木3D</title>
        <link href="css/base.css" rel="stylesheet" type="text/css">
        <script src="js/base.js"></script>
    </head>
    <body>
        <div id="contents">
            <canvas id="canvas" width="275" height="275"></canvas>
        </div>
    </body>
</html>

2.CSS

@charset "utf-8";
  
body
{
    margin: 0;
    padding: 0;
    background-color: #fff;
}
  
#contents
{
    position: absolute;
    top: 0;
    left: 0;
    width: 275px;
    height: 275px;
    border: 1px solid #000;
    overflow:hidden;
}
  
#canvas
{
    position: absolute;
    top: 0;
    left: 0;
    width: 275px;
    height: 275px;
}

3.JavaScript

base.js

window.addEventListener("load", init, false);
  
function init()
{
    var offsetX = 0,
    offsetY = 0,
    ctx,
    trees = [],
    numTrees = 100,
    fl = 250,
    vpX = 0,
    vpY = 0,
    gravity = 0.3,
    floor = 50,
    ax = 0,
    ay = 0,
    az = 0,
    vx = 0,
    vy = 0,
    vz = 0,
    friction = 0.98,
    theContents;
     
    theContents = document.getElementById("contents");
    offsetX = (theContents.currentStyle || document.defaultView.getComputedStyle(theContents,'')).width;
    offsetX = Number(offsetX.replace('px', ''));
  
    offsetY = (theContents.currentStyle || document.defaultView.getComputedStyle(theContents,'')).height;
    offsetY = Number(offsetY.replace('px', ''));
     
    vpX = offsetX / 2;
    vpY = offsetY / 2;
     
    ctx = document.getElementById('canvas').getContext("2d");
     
    for(var i = 0; i < numTrees; i++)
    {
        var tree = {};
         
        tree.xpos = Math.random() * 2000 - 1000;
        tree.ypos = floor;
        tree.zpos = Math.random() * 10000;
         
        tree.scaleX = 1; 
        tree.scaleY = 1;
        tree.x = 0;
        tree.y = 0;
         
        tree.red = 0; //Math.floor(Math.random() * 256);
        tree.green = 0; //Math.floor(Math.random() * 256);
        tree.blue = 0; //Math.floor(Math.random() * 256);
        tree.alpha = 1;
         
        tree.x01 = 0;
        tree.y01 = 0;
        tree.x02 = 0;
        tree.y02 = -140 - Math.random() * 20;
         
        tree.x11 = 0;
        tree.y11 = -30 - Math.random() * 30;
        tree.x12 = Math.random() * 80 - 40;
        tree.y12 = -100 - Math.random() * 40;
         
        tree.x21 = 0;
        tree.y21 = -60 - Math.random() * 40;
        tree.x22 = Math.random() * 60 - 30;
        tree.y22 = -110 - Math.random() * 20;
         
        trees[i] = tree;
    }
     
    setAnimation();
     
    function setAnimation()
    {
        animation();
        requestAnimationFrame(setAnimation);
    }
     
    function animation()
    {
        ctx.clearRect(0, 0, 300, 300);
        sortZ();
        az = -0.5;
        //ax = 0.5;
        //ay = 0.5;
        vx += ax;
        vy += ay;
        vz += az;
        vy -= gravity;
        for(var i = 0; i < numTrees; i++)
        {
            var tree = trees[i];
            move(tree);
        }
        vx *= friction;
        vy *= friction;
        vz *= friction;
    }
     
    function move(tree)
    {
        tree.xpos += vx;
        tree.ypos += vy;
        tree.zpos += vz;
         
        if(tree.ypos < floor)
        {
            tree.ypos = floor;
        }
         
        if(tree.zpos < -fl)
        {
            tree.zpos += 10000;
        }
        if(tree.zpos > 10000 - fl)
        {
            tree.zpos -= 10000;
        }
         
        var scale = fl / (fl + tree.zpos);
        tree.scaleX = scale; 
        tree.scaleY = scale;
        tree.x = vpX + tree.xpos * scale;
        tree.y = vpY + tree.ypos * scale;
        tree.alpha = scale;
         
        ctx.fillStyle = "rgba(" + tree.red + "," + tree.green + "," + tree.blue + "," + tree.alpha + ")";
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.strokeStyle =  "rgba(" + tree.red + "," + tree.green + "," + tree.blue + "," + tree.alpha + ")";
        ctx.moveTo(tree.x + tree.x01 * tree.scaleX, tree.y + tree.y01 * tree.scaleX);
        ctx.lineTo(tree.x + tree.x02 * tree.scaleX, tree.y + tree.y02 * tree.scaleX);
        ctx.fill();
        ctx.stroke();
         
        ctx.fillStyle = "rgba(" + tree.red + "," + tree.green + "," + tree.blue + "," + tree.alpha + ")";
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.strokeStyle = "rgba(" + tree.red + "," + tree.green + "," + tree.blue + "," + tree.alpha + ")";
        ctx.moveTo(tree.x + tree.x11 * tree.scaleX, tree.y + tree.y11 * tree.scaleX);
        ctx.lineTo(tree.x + tree.x12 * tree.scaleX, tree.y + tree.y12 * tree.scaleX);
        ctx.fill();
        ctx.stroke();
         
        ctx.fillStyle = "rgba(" + tree.red + "," + tree.green + "," + tree.blue + "," + tree.alpha + ")";
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.strokeStyle = "rgba(" + tree.red + "," + tree.green + "," + tree.blue + "," + tree.alpha + ")";
        ctx.moveTo(tree.x + tree.x21 * tree.scaleX, tree.y + tree.y21 * tree.scaleX);
        ctx.lineTo(tree.x + tree.x22 * tree.scaleX, tree.y + tree.y22 * tree.scaleX);
        ctx.fill();
        ctx.stroke();
    }
     
    /*
     * 配列の並べ替え: 降順
     */
    function sortZ()
    {
        trees.sort( function( a, b ) { return b.zpos - a.zpos; } );
    }
}
 
// 各ブラウザ対応
window.requestAnimationFrame = (function()
{
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback)
    {
        window.setTimeout(callback, 1000/60);
    };
}());

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です