svg разместить фигуру на пути

Я создаю игру в формате SVG и требую, чтобы квадратные плитки размещались вдоль пути с именем дорога.
Путь может быть изогнут или расположен под углом, и я хотел бы повернуть квадратные плитки относительно пути.

Моя текущая структура выглядит так:


<defs>
    <rect id="tile" width="200" height="200" stroke-width="5" stroke="red"/>
</defs>

<g style="stroke-width=10px; stroke:#23238E;>
   <path id="road1" d="M100 100 L 500 100"/>
   <path id="road2" d="M500 100 L 200 100"/>
</g>

Мое нынешнее понимание SVG говорит мне, что мне придется вычислять положения плиток с помощью интерполяции, но могу ли я автоматически поворачивать плитки относительно пути?

Итак, как я могу применить <use x="xx" y="yy" orient="auto" xlink:href="tile"/>?



Дороги генерируются на основе следующей информации:

id = #
vector2D = {
  x1 = #
  y1 = #
  x2 = #
  y2 = #
}
tiles = # // number of tiles in road

person JGM.io    schedule 19.09.2012    source источник


Ответы (2)


Raphael http://raphaeljs.com указывает угол пути в любой точке через path.getPointAtLenght(x). У SVG есть собственная реализация, но она не обеспечивает угол. Вы можете заглянуть в источник Рафаэля, чтобы узнать, что происходит. Вот соответствующий бит:

getLengthFactory = function (istotal, subpath) {
        return function (path, length, onlystart) {
            path = path2curve(path);
            var x, y, p, l, sp = "", subpaths = {}, point,
                len = 0;
            for (var i = 0, ii = path.length; i < ii; i++) {
                p = path[i];
                if (p[0] == "M") {
                    x = +p[1];
                    y = +p[2];
                } else {
                    l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
                    if (len + l > length) {
                        if (subpath && !subpaths.start) {
                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
                            sp += ["C" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];
                            if (onlystart) {return sp;}
                            subpaths.start = sp;
                            sp = ["M" + point.x, point.y + "C" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join();
                            len += l;
                            x = +p[5];
                            y = +p[6];
                            continue;
                        }
                        if (!istotal && !subpath) {
                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
                            return {x: point.x, y: point.y, alpha: point.alpha};
                        }
                    }
                    len += l;
                    x = +p[5];
                    y = +p[6];
                }
                sp += p.shift() + p;
            }
            subpaths.end = sp;
            point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);
            point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});
            return point;
        }; 

Где point.alpha — угол поворота.

person methodofaction    schedule 20.09.2012

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

person Robert Longson    schedule 19.09.2012
comment
Но, насколько я понимаю, вы не можете связать события или слушателей с маркерами, поскольку они на самом деле не являются частью DOM/структуры, а скорее частью презентации. Это то, что я помню, когда в последний раз экспериментировал с SVG. - person JGM.io; 19.09.2012
comment
В вашем вопросе не упоминается это требование. - person Robert Longson; 20.09.2012