Модификация изображения Raphael SVG с помощью jQuery - PullRequest
2 голосов
/ 13 июля 2011

У меня есть небольшое приложение, где мне нужно генерировать надписи textPath для дуг. Я рисую дуги через Рафаэля, и это прекрасно работает. Однако у Рафаэля нет поддержки textPaths. Мы можем добавить их в элемент svg через jQuery, но по какой-то причине они не отображаются. Когда я статически продублирую динамически сгенерированный код, он прекрасно воспроизводится.

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="600">
  <desc>Created with Raphaël</desc><defs></defs>
  <a title="This is a test entry">
    <path fill="none" stroke="#1e79a0" d="M395.2627944162883,355A110,110,0,0,1,199.5099996593139,344.74103073833805" style="stroke-width: 20px; " stroke-width="20" id="This_is_a_test_entry"></path>
  </a>
  <text>
    <textpath xlink:href="#This_is_a_test_entry">This is a test entry</textpath>
  </text>
</svg>

С приведенным выше кодом вы никогда не увидите метку для дуги. Однако, когда следующее жестко запрограммировано, оно отрисовывается как ожидалось:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="600">
  <a title="Bacon">
    <path id="Arc" fill="none" stroke="#1e79a0" d="M395.2627944162883,355A110,110,0,0,1,201.13265490709162,348.2208261467985" style="stroke-width: 20;" stroke-width="20">
    </path>
  </a>
  <text>
    <textPath xlink:href="#Arc">This is an Arc</textPath>
  </text>
</svg>

Любое понимание того, почему я не вижу весь свой svg, будет высоко ценится.

РЕДАКТИРОВАТЬ:

Я внес изменения в свой javascript и думаю, что он почти там, но textPath все равно не будет отображаться. Вот текущий код, в основном благодаря Femi:

function drawRange(start, end, R, range, id, title) {
                    var color = "hsb(".concat(Math.round(R) / 200, ",", end / 360, ", .75)");
                    var key_position = key[id];
                    var svg_bits = document.getElementsByTagName('svg')[0].childNodes;
                    var svgns = document.createElementNS('http://www.w3.org/2000/svg', "path");
                    var path;
                    range.attr({title: title});
                    range.animate({arc: [start, end, R]}, 900, ">");
                    //Add an id to the path element that was just drawn.  This doesn't seem to help though.
                    for(var i = 0; i < svg_bits.length; i++) {
                        if (svg_bits[i].tagName == "a" && svg_bits[i].getAttribute('title') == title){
                            path = svg_bits[i].childNodes[0];
                        }
                    }
                    path.setAttribute('id', title);
                    //Add the name to the key, set the color and unhide the element.
                    $(key_position).html(range.attr("title"));
                    $(key_position).css('color', Raphael.getRGB(color).hex);
                    $(key_position).show();
                };



function makeSVG(tag, attrs) {
                    var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
                    for (var k in attrs)
                        el.setAttribute(k, attrs[k]);
                    return el;
                };

function addLabel(label) {
                    var text = makeSVG("text", {});
                    var title = makeSVG("textPath", {"xlink:href":'#' + label.replace(/\s/g, '_')});
                    title.appendChild(document.createTextNode(label));
                    text.appendChild(title);
                    r.canvas.appendChild(text);
                };

Я получаю ограничивающую рамку 0x0 для textPath, но без textPath.

Ответы [ 4 ]

3 голосов
/ 13 июля 2011

Вам может потребоваться либо удалить xlink, который появляется в первом примере, либо добавить соответствующее определение пространства имен XML.

РЕДАКТИРОВАТЬ: при добавлении элемента textPath может потребоваться использовать правильное имя элемента (textPath, а не textpath).

РЕДАКТИРОВАТЬ: умеренно интересно, так как это сочетание браузера и jQuery, меняющих путь. Чтобы получить правильную вещь, используйте эту функцию (освобожден от ответа на приложение jquery не работает с элементом svg? ):

function makeSVG(tag, attrs){
   var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
   for (var k in attrs)
     el.setAttribute(k, attrs[k]);
   return el;
 }

А затем сделайте это:

var paper = Raphael("notepad", 320, 200);

// do all your other stuff here
...

var text = makeSVG("text", {});
       var c = makeSVG("textPath", {"xlink:href":"#Arc"});
       c.appendChild(document.createTextNode("This is an Arc"));
       text.appendChild(c);
paper.canvas.appendChild(text);

Это даст вам правильный SVG: однако, он все равно не будет правильно рисовать, что странно.

2 голосов
/ 13 июля 2011

Если вы не беспокоитесь о том, что ваша работа не работает в ie8 или более ранней версии, почему бы не использовать плагин jquery SVG от kieth wood, который поддерживает textpath Синтаксис пути для плагина отличается, но его легко конвертировать из Raphael Плагин SVG обеспечивает красивые радиальные градиенты, но этовот почему я занимаюсь этим сейчас.

Если вы хотите, чтобы текст на пути не отображал кривую с каждой буквой, то вы можете остаться с Rap и использовать это ... http://irunmywebsite.com/raphael/additionalhelp.php?v=1&q=anglebannersoncurves

Извините правописание iPodновичок

1 голос
/ 19 августа 2011

Ответ Феми довольно хороший, единственное, чего не хватает, это заставить его перерисовать и задать пространство имен xlink.

Я не могу понять основную причину, но это должно быть что-то в ядре Рафаэля, которое препятствует обновлению холста SVG, так как все, что вам нужно сделать, чтобы исправить рисунок, это принудительно перерисовать, быстро удаляя и затем читая элемент svg из DOM:

$('#myRaphaelDiv').html($('#myRaphaelDiv').html());

Следует отметить, что любой прямой взлом атрибутов SVG нарушит совместимость с браузерами ( sigh , IE), которые вместо этого используют VML. Я еще не изучил способ создания текстовых путей в VML. Код ниже для полноты.

// add the new namespace attribute to the SVG canvas. 'raphael' is the Raphael instance.
// note that this only needs to be done once.
$(raphael.canvas).attr('xmlns:xlink', "http://www.w3.org/1999/xlink");

// draw the curved text
var lblId = 'some_unique_dom_id';
var path = raphael.path().attr({
    stroke : 'none' // defaults to black
    // ...other path attributes used in generating it...
});
var label = raphael.text().attr({ 'text-anchor' : 'start' });

// create and inject raw SVG textPath element
var link;
try {
    link = document.createElementNS('http://www.w3.org/2000/svg', 'textPath');
} catch (e) {
    // no createElementNS() method is pretty much synonymous with using IE, so
    // this is where you would do your VML version of a text path
    alert("Your browser does not support SVG, please use Firefox, Chrome etc");
}
link.setAttribute('xlink:href', '#' + lblId);
link.appendChild(document.createTextNode("path-oriented text"));

// finally, force a redraw of the SVG document. 
// Obviously, you would defer this until all elements had been added.
$('#myRaphaelDiv').html($('#myRaphaelDiv').html());
0 голосов
/ 18 июля 2011

Итак, после нахождения патча к Рафаэлю здесь и внесения небольшого изменения в патч, он работает. Я все еще не уверен, что мне не хватало, но textPaths теперь рендерится, и все счастливы. Спасибо всем за помощь.

...