KineticJS изометрические преобразования
Я пытаюсь сделать изометрическую гексагональную карту с помощью KineticJS lib и застрял в трансформирующем слое. Слой должен быть сначала повернут на 45 градусов. а затем масштаб (1, 0,5), чтобы получить правильный результат
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/), но в KineticJS операции поворота и масштабирования выполняются на исходном слое
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/).
Как установить приоритет операций трансформации в KineticJS?
1 ответ
Решение
Вы можете добавить группу, чтобы получить больше контроля над порядком преобразования:
- положи свою поли в группу
- повернуть группу
- масштабировать слой группы
Что-то вроде этого:
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);