2011-01-23 2 views
5

Я работаю над некоторым кодом JavaScript для рендеринга стандартных 2D-элементов SVG/Canvas (с рисунком Raphael-JS) в изометрии 3Dish вид.Перевод элементов SVG для изометрического представления

Скажем, у нас есть два прямоугольника, нарисованные рядом друг с другом. Затем я их перерисовываю под правильным углом (в основном 30-градусный поворот) для изометрического обзора.

alt text

(На изображении выше я показал происхождение двух соответствующих элементов.)

Моя проблема, я не знаю, как правильно перевести все отдельные элементы, чтобы они «плитка» правильно, а не просто перекрывается.

Хотя на самом деле использование плитки упростит ситуацию, поскольку я мог бы просто разместить любое место плитки на той, которая была перед ней, плитки в этом случае не будут работать. Все динамично и будет более сложным, чем простые плоскости x/y.

Here is an image of some isometric tiles если есть какие-либо недоразумения относительно того, как я хочу, чтобы эти объекты были размещены.

+0

Ваше название, кажется, указывает, что вы используете элемент HTML Canvas. Поскольку Raphael использует SVG (хотя они также говорят о холсте), вам может понадобиться очистить это, чтобы получить ответы. Интересный вопрос, хотя! – polarblau

+0

Спасибо за подсказку, polarblau. Я постараюсь уточнить свой вопрос. –

+0

Обратите внимание, что рисунок, который вы поставили в своем вопросе, не является правильной изометрической проекцией, предполагая, что два квадрата находятся на одной высоте с землей. Как показано в приведенном вами URL-адресе, края соседних плит должны оставаться выровненными после проецирования. Если вы пытались показать свою проблему, то вам, возможно, следует пояснить, что это текущий/неправильный результат, который вы показываете. – Phrogz

ответ

2

Вы не должны применять преобразование к отдельным элементам, а к элементам-источникам в качестве коллекции. В Рафаэль, вы могли бы использовать что-то вроде

var s = paper.set(); 
s.push(square1, square2); 

и теперь делать преобразования, не слишком много математики, которая должна работать, как это:

// s.clone(); // if you want to keep originals 
s.rotate(45, 0, 0).scale(1, .7).translate(100, 0); 

(Тем не менее, масштабирование повернутых элементов, кажется, сломана в RaphaelJS)

Обычный SVG пример:.

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
    viewBox="-200,-500 1000,1000"> 
    <title>Isometric</title> 
     <g id="source"> <!-- group --> 
      <circle cx="-50" cy="-50" r="50"/> 
      <rect width="100" height="100"/> 
      <rect width="100" height="100" x="101"/> 
      <rect width="100" height="100" x="50" y="-200"/> 
     </g> 
     <!-- make copy of group and apply transformations --> 
     <use xlink:href="#source" transform="translate(500) scale(1, .7) rotate(-45)"/> 
</svg> 
+0

Спасибо за ответ, Pumbaa80.К сожалению, это решение для меня не подходит. Я бы хотел, чтобы в конечном итоге можно было ввести некоторые координаты, скажем, базового плана этажа. Затем визуализируйте эти координаты в изометрической проекции и выдавите z-ось (высоту) из «базы» элемента. Позже, используя JavaScript, я хочу иметь возможность манипулировать отдельными элементами: перемещение, удаление, добавление и изменение. На самом деле я не могу нарисовать z-оси (сделать кубы из следов), а затем повернуть набор. Я полагаю, что * можно * повернуть все, а затем extrude -continued-> –

+0

<-continuted-height, переопределив координаты каждого элемента. Это может сработать, но кажется довольно уродливым. Опять же, может быть, это проще. Я попробую. –

+0

. В интересах кого-то еще, вот моя публикация групп Google Raphael-JS по масштабированию проблемы с вращающимися элементами: http://groups.google.com/group/raphaeljs/browse_thread/thread/217a5edb9db22419 –

3

Использование Raphel.js 2.0 вы можете сделать это с помощью метода .transform() и предоставить строку преобразования, которая вращается на 45 градусов и масштабируется по вертикали 70% (или любой желаемый угол). Важно обратить внимание на положение, в котором вы вращаетесь и масштабируетесь, - в этом случае я использую 0,0. Вы также заметите, что я переводил 100 вправо, чтобы компенсировать поворот.

Строки преобразования также отлично подходят для этого случая использования, потому что вы можете просто добавить преобразование проекции в преобразование других объектов в сцене, и все они окажутся в нужном месте.

Например (см http://jsfiddle.net/k22yG/):

var paper = Raphael(10, 10, 320, 240), 
    set = paper.set(); 

// Build a set to make it easier to transform them all at once 
set.push(
    // Grid of rectangles 
    paper.rect(0, 0, 50, 50), 
    paper.rect(60, 0, 50, 50), 
    paper.rect(0, 60, 50, 50), 
    paper.rect(60, 60, 50, 50) 
); 

// Rotate, then scale, then move (describe in "reverse" order) 
set.transform('t100,0s1,0.7,0,0r45,0,0');​ 
Смежные вопросы