KineticJS isometric transforms

328 views Asked by At

I'm trying to make isometric hexagonal map with KineticJS lib, and get stucked transforming layer. Layer must be first rotated by 45 deg. and then scale (1, 0.5) to receive proper result

var canvas = document.getElementById('main'),
    ctx = canvas.getContext('2d');

var size = 32,
    rows = 12,
    cols = 10;

var height = 2 * size,
    width = height * Math.sqrt(3) / 2;

var grass = new Image();
grass.src = 'http://i46.tinypic.com/302cnk6.png';
grass.onload = function () {
    var pGrass = ctx.createPattern(grass, 'repeat');

    ctx.save();
    ctx.scale(1, 0.5); //Scale first
    ctx.translate(400, 100); //Then moving
    ctx.rotate(45 * Math.PI / 180); // Last rotating

    xDisp = 0, yDisp = 0;
    ctx.fillStyle = pGrass;
    for (var i = 0; i < rows; i++) {
        xDisp = i % 2 === 0 ? 0 : width / 2;
        additional = i * height / 4;
        for (var j = 0; j < cols; j++) {
            drawPoly(30 + j * width + xDisp, 35 + i * height - additional, size, '#000');
            ctx.shadowColor = '#000';
            ctx.shadowBlur = 10;
            ctx.shadowOffsetX = 0;
            ctx.shadowOffsetY = 5;
            ctx.fill();
        }
    }
    ctx.restore();
};
function drawPoly(cX, cY, size, color) {
    ctx.beginPath();
    for (var i = 0; i < 6; i++) {
        angle = 2 * Math.PI / 6 * (i + 0.5);
        x = cX + size * Math.cos(angle);
        y = cY + size * Math.sin(angle);

        if (i === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
    }
    ctx.closePath();
    ctx.strokeStyle = color;
    ctx.stroke();
}

(pureJS: http://jsfiddle.net/YvwLB/), but in KineticJS rotate and scale operation perform on original layer

var size = 32,
    rows = 12,
    cols = 10;

var height = 2 * size,
    width = height * Math.sqrt(3) / 2;

var stage = new Kinetic.Stage({
    container: 'container',
    width: 800,
    height: 600
});

var lBackground = new Kinetic.Layer();

for (var i = 0; i < rows; i++) {
    xDisp = i % 2 === 0 ? 0 : width / 2;
    additional = i * height / 4;
    for (var j = 0; j < cols; j++) {
        var _poly = drawPoly(30 + j * width + xDisp, 35 + i * height - additional, size, '#0d0');
        lBackground.add(_poly);
    }
}
stage.add(lBackground);

lBackground.rotateDeg(45);
lBackground.move(400, 100);
lBackground.setScaleY(0.5);

stage.draw();

function drawPoly(cX, cY, rad, color) {
    var poly = new Kinetic.RegularPolygon({
        x: cX,
        y: cY,
        sides: 6,
        radius: rad,
        fill: color,
        stroke: 'black',
        strokeWidth: 1
    });
    poly.on('mouseover', function () {
        this.setFill('#D23333');
        lBackground.draw();
    });
    poly.on('mouseout', function () {
        this.setFill(color);
        lBackground.draw();
    });
    return poly;
}

(http://jsfiddle.net/26ArE/).

How to set priority of transforming operations in KineticJS?

1

There are 1 answers

0
markE On BEST ANSWER

You might add a group to get more control of the transformation order:

  • put your poly's in a group
  • rotate the group
  • scale the group's layer

Something like this:

var group=new Kinetic.Group({
  x:200,
  y:200
});
layer.add(group);

for (var i = 0; i < rows; i++) {
    xDisp = i % 2 === 0 ? 0 : width / 2;
    additional = i * height / 4;
    for (var j = 0; j < cols; j++) {
        var _poly = drawPoly(
            30 + j * width + xDisp, 35 + i * height - additional, size, '#0d0');
        group.add(_poly);
    }
}

group.rotateDeg(45);
layer.setScale(1, 0.5);