views:

104

answers:

2

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!

+1  A: 

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

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

spacemanaki
+4  A: 

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();
    }
}
galambalazs
galambalazs: your suggestion doesn't linked to question. But you are 100% correct! Don't take my code close to your heart... that is a prototype only... To be honest, I am just learning how to work with objects/classes in JS. But Definitely, I will use 'Hex' class :)
Budda