简体   繁体   中英

3d drawing in Canvas with HTML+JS

Is there any framework/engine that provide ability to draw 3d images on Canvas?

I am planning to draw some primitives (different shapes) located in one plane:

    var dist = 2;
    var hexHalfW = 35;
    var lengthX = 20;
    var hexR = Math.sqrt(lengthX*lengthX+hexHalfW*hexHalfW);//40.31128874
    var hexDiag = 2*hexR;
    var hexHeight = hexDiag;
    var hexWidth = 2*hexHalfW;

    function DrawHex(ctx, x, y)
    {               
        var cx = x*(hexWidth + dist) - y*(hexWidth + dist)/2;
        var cy = y*(hexR + lengthX + dist);
        ctx.beginPath();
        ctx.moveTo(cx, cy-hexR);
        ctx.lineTo(cx+hexHalfW, cy-hexR+lengthX);
        ctx.lineTo(cx+hexHalfW, cy+hexR-lengthX);
        ctx.lineTo(cx, cy+hexR);
        ctx.lineTo(cx-hexHalfW, cy+hexR-lengthX);
        ctx.lineTo(cx-hexHalfW, cy-hexR+lengthX);
        ctx.lineTo(cx, cy-hexR);
        ctx.fill();
    }

    function draw()
    {
        var canvas = document.getElementById('tutorial');
        if (canvas.getContext)
        {
            var ctx = canvas.getContext('2d');

            //Pick Hexagon color, this one will be blue
            ctx.fillStyle = "rgb(0, 0, 255)";   DrawHex(ctx, 1, 1);
            ctx.fillStyle = "rgb(0, 0, 225)";   DrawHex(ctx, 3, 1);
            ctx.fillStyle = "rgb(0, 0, 195)";   DrawHex(ctx, 4, 1);
            ctx.fillStyle = "rgb(0, 0, 165)";   DrawHex(ctx, 6, 1);

            ctx.fillStyle = "rgb(0, 255, 0)";   DrawHex(ctx, 3, 2);
            ctx.fillStyle = "rgb(0, 225, 0)";   DrawHex(ctx, 4, 2);
            ctx.fillStyle = "rgb(0, 195, 0)";   DrawHex(ctx, 5, 2);
        }
    }

I would like to draw these primitives in "perspective": closer shapes (in the bottom of the screen) will be bigger, shapes "far away" (in the top of the screen) needs to be smaller...

For this purpose shapes coordinates are needs to be recalculated.

Guess, I could find some formulas that allows to recalculate coordinates and write a proper functions... but, probably, there are some engines that already doing that?

Please advise.

Any thoughts are welcome!

Whatever framework you chose, you should learn to encapsulate your data into objects.

- View simple demo -

Hexagon

// Hexagon
function Hexagon(ctx, color, pos, size, scale) {
    this.color = color;
    this.ctx = ctx;
    this.x = pos[0];
    this.y = pos[1];
    this.z = pos[2] || 0; // scale
    this.width = size.width;
    this.height = size.height;
}

Hexagon.draw

// Hexagon.draw
Hexagon.prototype.draw = function (x, y) {
    if (x == null || y == null) {
        x = this.x;
        y = this.y; 
    }
    var width  = this.width  + (this.width  * this.z), // scaled width
        height = this.height + (this.height * this.z), // scaled height
        cx  = x * (width + dist) - y * (width + dist) / 2,
        cy  = y * (3/4 * height + dist),
        ctx = this.ctx;
    ctx.fillStyle = this.color;
    ctx.beginPath();
    ctx.moveTo(cx, cy - height/2);
    ctx.lineTo(cx + width/2, cy - height/4);
    ctx.lineTo(cx + width/2, cy + height/4);
    ctx.lineTo(cx, cy + height/2);
    ctx.lineTo(cx - width/2, cy + height/4);
    ctx.lineTo(cx - width/2, cy - height/4);
    ctx.lineTo(cx, cy - height/2);  
    ctx.fill();
};

Usage

var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
var dist = 2;

// Create Hexagons
var size = { 
   width:  70, 
   height: 80 
};

var hexes = [
    new Hexagon(ctx, "rgb(0, 0, 255)", [1, 1], size),
    new Hexagon(ctx, "rgb(0, 0, 225)", [3, 1], size),
    new Hexagon(ctx, "rgb(0, 0, 195)", [4, 1], size),
    new Hexagon(ctx, "rgb(0, 0, 165)", [6, 1], size),
    new Hexagon(ctx, "rgb(0, 225, 0)", [3, 2], size),
    new Hexagon(ctx, "rgb(0, 225, 0)", [4, 2], size),
    new Hexagon(ctx, "rgb(0, 195, 0)", [5, 2], size)
];

function draw() {
    for (var i = hexes.length; i--;) {
        hexes[i].draw();
    }
}

You might want to look at mrdoob's three.js:

http://github.com/mrdoob/three.js/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM