2013-01-06 18 views
6

एक एसवीजी पथ तत्व को देखते हुए, मैं सभी पथ कमांड को सापेक्ष निर्देशांक में कैसे परिवर्तित कर सकता हूं? इस बराबर पथ मेंएसवीजी पथ से संबंधित कमांड में कनवर्ट करें

<path d="M3,7 L13,7 m-10,10 l10,0 V27 H23 v10 h10 
     C33,43 38,47 43,47 c0,5 5,10 10,10 
     S63,67 63,67  s-10,10 10,10 
     Q50,50 73,57  q20,-5 0,-10 
     T70,40    t0,-15 
     A5,5 45 1 0 40,20 a5,5 20 0 1 -10,-10 
     Z" /> 

: उदाहरण के लिए, इस पथ (जो हर आदेश, निरपेक्ष और सापेक्ष, interleaved भी शामिल है) में परिवर्तित

<path d="m3,7 l10,0 m-10 10 l10,0 v10 h10 v10 h10 
     c0,6 5,10 10,10 c0,5 5,10 10,10 
     s10,10 10,10  s-10,10 10,10 
     q-23,-27 0,-20  q20,-5 0,-10 
     t-3,-7    t0-15 
     a5,5 45 1 0 -30,-5 a5,5 20 0 1 -10,-10 
     z"/> 

यह सवाल this question से प्रेरित हुआ।

function convertToRelative(path) { 
    function set(type) { 
    var args = [].slice.call(arguments, 1) 
     , rcmd = 'createSVGPathSeg'+ type +'Rel' 
     , rseg = path[rcmd].apply(path, args); 
    segs.replaceItem(rseg, i); 
    } 
    var dx, dy, x0, y0, x1, y1, x2, y2, segs = path.pathSegList; 
    for (var x = 0, y = 0, i = 0, len = segs.numberOfItems; i < len; i++) { 
    var seg = segs.getItem(i) 
     , c = seg.pathSegTypeAsLetter; 
    if (/[MLHVCSQTAZz]/.test(c)) { 
     if ('x1' in seg) x1 = seg.x1 - x; 
     if ('x2' in seg) x2 = seg.x2 - x; 
     if ('y1' in seg) y1 = seg.y1 - y; 
     if ('y2' in seg) y2 = seg.y2 - y; 
     if ('x' in seg) dx = -x + (x = seg.x); 
     if ('y' in seg) dy = -y + (y = seg.y); 
     switch (c) { 
     case 'M': set('Moveto',dx,dy);     break; 
     case 'L': set('Lineto',dx,dy);     break; 
     case 'H': set('LinetoHorizontal',dx);   break; 
     case 'V': set('LinetoVertical',dy);    break; 
     case 'C': set('CurvetoCubic',dx,dy,x1,y1,x2,y2); break; 
     case 'S': set('CurvetoCubicSmooth',dx,dy,x2,y2); break; 
     case 'Q': set('CurvetoQuadratic',dx,dy,x1,y1); break; 
     case 'T': set('CurvetoQuadraticSmooth',dx,dy); break; 
     case 'A': set('Arc',dx,dy,seg.r1,seg.r2,seg.angle, 
         seg.largeArcFlag,seg.sweepFlag); break; 
     case 'Z': case 'z': x = x0; y = y0; break; 
     } 
    } 
    else { 
     if ('x' in seg) x += seg.x; 
     if ('y' in seg) y += seg.y; 
    } 
    // store the start of a subpath 
    if (c == 'M' || c == 'm') { 
     x0 = x; 
     y0 = y; 
    } 
    } 
    path.setAttribute('d', path.getAttribute('d').replace(/Z/g, 'z')); 
} 

सवाल से पथ के साथ इसलिए की तरह उपयोग किया::

उत्तर

6

स्नैप। वीजीजी में Snap.path.toRelative() है।

var rel = Snap.path.toRelative(abspathstring); 

Fiddle

+0

वर्थ नोटिंग: कम से कम स्नैप एसवीजी यहां लिंक संस्करण (http://cdn.jsdelivr.net/snap.svg/0.3.0/snap.svg.js) आपके इनपुट से समन्वय परिशुद्धता को बनाए रखेगा, लेकिन सभी निर्देशांकों के लिए 3 दशमलव तक गोल नहीं करेगा। – ecmanaut

7

मैं इस convertToRelative समारोह में Phrogz' convertToAbsolute बदलाव

var path = document.querySelector('path'); 
convertToRelative(path); 
console.log(path.getAttribute('d')); 
// m 3 7 l 10 0 m -10 10 l 10 0 v 10 h 10 v 10 h 10 c 0 6 5 10 10 10 c 0 5 5 10 10 10 s 10 10 10 10 s -10 10 10 10 q -23 -27 0 -20 q 20 -5 0 -10 t -3 -7 t 0 -15 a 5 5 45 1 0 -30 -5 a 5 5 20 0 1 -10 -10 z 

मैं भी बना एक छोटा phantomjs उपयोगिता svg2rel जिसमें सभी रास्तों को बदल देती है शैल एक एसईजी इस तरह से (अच्छी माप के लिए, एक ही जिस्ट में एक संबंधित svg2abs है)।

+0

'pathSegList' अब पदावनत किया गया है: https://stackoverflow.com/questions/34352624/alternative-for-deprecated-svg-pathseglist –

+0

के रूप में इस सवाल का जवाब सही नहीं है जैसा कि ऊपर उल्लेख के बाद क्रोम (और अन्य ब्राउज़रों) में एपीआई बहिष्करण, मैं स्नैप हैक पर स्विच कर रहा हूं - या अपने बड़े भाई राफेल में एक समान समाधान: http://jsbin.com/voxemav/ – ecmanaut

संबंधित मुद्दे