Перевод элементов SVG для изометрической проекции - PullRequest
5 голосов
/ 23 января 2011

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

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

alt text

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 25 июля 2012

Используя 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');​
4 голосов
/ 23 января 2011

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

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>
...