Как достичь «дырок от бублика» с путями в Рафаэле - PullRequest
13 голосов
/ 28 июля 2010

Я хотел бы нарисовать фигуру, в которой есть отверстия, так что я могу fill придать ей форму, чтобы отверстия не были заполнены этим цветом (оставить их прозрачными).

В соответствии со спецификацией пути W3 :

Сложные пути (т. Е. Пути с несколькими подпутями) позволяют создавать такие эффекты, как «дырки от бублика» в объектах.

Может ли кто-нибудь привести очень простой пример того, как выполнить это с векторным путем в Рафаэль ?

Большое спасибо.

Ответы [ 4 ]

19 голосов
/ 29 июля 2010

Это будет довольно просто, если вы знаете хитрость.Например, это не работает :

paper.path("M 50 50 L 50 150 L 150 150 L 150 50 z" + 
          " M 75 75 L 75 125 L 125 125 L 125 75 z")
.attr("fill", "#f00");

Но это работает *:

paper.path("M 50 50 L 50 150 L 150 150 L 150 50 z" +
          " M 75 75 L 125 75 L 125 125 L 75 125 z")
.attr("fill", "#f00");

Разница в том, что дляЧтобы появиться пончик, внутренний путь должен иметь его вершины, нарисованные в обратном порядке к внешнему пути (т. е. нарисовать одну по часовой стрелке, а другую против часовой стрелки).Тидбит, который я нашел в архивах text.xml.svg.devel .

(*) По крайней мере, он работает в бета-версии Chrome, Opera и Firefox 4.0, но не в 3.6

4 голосов
/ 08 декабря 2010

Чтобы сделать это в Firefox 3.6, вам нужно закрыть дыру; то есть заставить координаты соединяться обратно при определении внутренней границы. Любопытно, что это не кажется необходимым для внешней границы.

paper.path("M 50 50 L 50 150 L 150 150 L 150 50 z" +
          " M 75 75 L 125 75 L 125 125 L 75 125 L 75 75 z")
.attr("fill", "#f00");

Просто небольшое замечание, чтобы прокомментировать комментарий - концепция по часовой стрелке / против часовой стрелки может показаться странной на первый взгляд, но она довольно стандартна для всех технологий ГИС / САПР.

3 голосов
/ 30 августа 2012

Я думаю, что правильный способ сделать это - установить атрибут «fill-rule» в значение «evenodd». Взгляните на svg spec :

Не пытайтесь установить его с помощью "Raphael.Element.attr ()". Не работает Вместо этого я использую функцию jQuery.attr ():

// assuming paper is a Raphael.Paper object
path = paper.path('Mx,y{some path commands for the main shape}Z'
                  +'Mx,y{some path commands for the hole}Z'
);

// this doesn't work
path.attr({'fill-rule': 'evenodd'});
// neither this
path.attr({fillRule: 'evenodd'});

// if you inspect the object returned by paper.path
// you can see it has a reference to the DOM element
console.debug(path)

// so a bit of jQuery and it's done
$(path[0]).attr('fill-rule', 'evenodd');

Я использовал это на сложных путях с успешными результатами.

2 голосов
/ 31 июля 2013

Для тех, кто хочет делать круглые пончики, отличный легкий плагин Raphael-donut-plugin

Суть:

Raphael.fn.donut = function(x, y, innerRadius, outerRadius) {
  y -= outerRadius;
  return this.path('M'+x+' '+y+'a'+outerRadius+' '+outerRadius +
      ' 0 1 0 1 0m-1 '+
      (outerRadius - innerRadius)+
      'a'+innerRadius+' '+innerRadius+
      ' 0 1 1 -1 0');
};
...