2011-08-30 11 views
147

वर्तमान में ब्राउज़र-आधारित SVG एप्लिकेशन बना रहा है। इस ऐप के भीतर, विभिन्न आकारों को आयत समेत उपयोगकर्ता द्वारा स्टाइल और स्थानांतरित किया जा सकता है।क्या आप नियंत्रित कर सकते हैं कि एसवीजी की स्ट्रोक-चौड़ाई कैसे खींची जाती है?

जब मैं का एक एसवीजी rect तत्व करने के लिए एक stroke-width कहना 1px लागू होते हैं, स्ट्रोक विभिन्न ब्राउज़रों द्वारा विभिन्न तरीकों से ऑफसेट rect की और इनसेट लिए आवेदन किया है। यह परेशानी साबित हो रहा है, विशेष रूप से जब मैं आयताकार की बाहरी चौड़ाई और दृश्य स्थिति की गणना करने की कोशिश करता हूं और इसे अन्य तत्वों के बगल में स्थित करता हूं।

उदाहरण के लिए:

  • फ़ायरफ़ॉक्स 1px इनसेट (नीचे और बाएं) कहते हैं, और ऑफसेट 1px (ऊपर और सही)
  • क्रोम 1px इनसेट (ऊपर और बाएं) कहते हैं, और ऑफसेट 1px (नीचे और दाएं)

मेरा एकमात्र समाधान अब तक वास्तविक सीमाओं को आकर्षित करना होगा (शायद path टूल के साथ) और स्ट्रोक तत्व के पीछे सीमाओं को स्थिति दें। लेकिन यह समाधान एक अप्रिय कामकाज है, और यदि संभव हो तो मैं इस सड़क पर नहीं जाना चाहूंगा।

तो मेरा सवाल यह है कि, क्या आप नियंत्रित कर सकते हैं कि एसवीजी का stroke-width तत्वों पर कैसे खींचा जाता है?

+0

फ़िल्टर हैक्स आप इसे प्राप्त करने के लिए उपयोग कर सकते हैं - लेकिन यह एक अच्छा समाधान नहीं है –

+1

वहां 'पेंट-ऑर्डर' पैरामीटर है, जहां आप निर्दिष्ट कर सकते हैं कि भरना स्ट्रोक के शीर्ष पर प्रस्तुत किया जाना चाहिए, ताकि आप "बाहरी संरेखण" प्राप्त होगा, https://jsfiddle.net/hne0kyLg/1/ –

उत्तर

272

नहीं, आप यह निर्दिष्ट नहीं कर सकते कि स्ट्रोक किसी तत्व के अंदर या बाहर खींचा गया है या नहीं। मैंने 2003 में इस कार्यक्षमता के लिए एसवीजी कार्यकारी समूह में a proposal बनाया, लेकिन इसे कोई समर्थन (या चर्चा) नहीं मिली।

SVG proposed stroke-location example, from phrogz.net/SVG/stroke-location.svg

जैसा कि मैंने प्रस्ताव में बताया गया है,

  • आप अपने स्ट्रोक की चौड़ाई को दोगुना करने के लिए और फिर अपने आप को वस्तु क्लिप करने के लिए एक कतरन पथ का उपयोग कर के रूप में "अंदर" एक ही दृश्य परिणाम प्राप्त कर सकते हैं , और
  • आप स्ट्रोक चौड़ाई को दोगुना करके और बाहर के ऑब्जेक्ट की नो-स्ट्रोक प्रति को ओवरले करके 'बाहरी' के रूप में एक ही दृश्य परिणाम प्राप्त कर सकते हैं।

संपादित करें: यह उत्तर भविष्य में गलत हो सकता है।के साथ veIntersect ('अंदर' के लिए) या veExclude ('बाहर के लिए) के साथ SVG Vector Effects का उपयोग करके इन परिणामों को प्राप्त करना संभव होना चाहिए। हालांकि, वेक्टर इफेक्ट्स अभी भी एक कामकाजी मसौदा मॉड्यूल है जिसमें कोई कार्यान्वयन नहीं है जिसे मैं अभी तक पा सकता हूं।

संपादित करें: एसवीजी 2 ड्राफ्ट विनिर्देश में stroke-alignment संपत्ति (केंद्र | अंदर | संभावित मूल्यों के बाहर) शामिल है। यह संपत्ति अंततः UAs में बना सकती है।

संपादित 3: Amusingly और dissapointingly, एसवीजी कार्यदल एसवीजी 2. से stroke-alignment हटा दिया गया है आप गद्य here के बाद वर्णित चिंताओं में से कुछ देख सकते हैं।दिए गए स्ट्रोक का उपयोग कर - -

+2

देखें कि यह मामला हो सकता है। इसे हल करने के लिए मैंने GetBtroxBBox() नामक getBBox() के लिए एक रैपर फ़ंक्शन लिखा है। यह रैपर बीबीओक्स को इस बात के हिसाब से देता है कि ब्राउजर एक आकृति के इन्सेट और ऑफ़सेट पर स्ट्रोक कैसे लागू करता है। यह सही नहीं है (नवीनतम ब्राउज़र संस्करणों के खिलाफ जांच रखने की आवश्यकता है) लेकिन यह अब के लिए बाहरी आकार को सटीक रूप से प्रदान करता है। – Steve

+6

@Phrogz शायद हम इसे 10 साल बीतने से पहले देखेंगे। https://svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint एनोटेशन – frenchone

+1

[यह आखिरकार यहाँ है!] (// stackoverflow.com/questions/7241393/can-you-control-how-an-svgs-stroke- चौड़ाई-तैयार/28787545 # उत्तर -28787545) मैं, एक के लिए, वास्तव में इस संपत्ति के आने के लिए आग्रह कर रहा हूं। – mnsth

6

यहाँ एक समारोह है कि गणना करेगा कि कितने पिक्सल आप जोड़ने की आवश्यकता है सभी ब्राउज़र के आधार पर, शीर्ष, सही, नीचे करने के लिए और छोड़ दिया:

var getStrokeOffsets = function(stroke){ 

     var strokeFloor =  Math.floor(stroke/2),                 // max offset 
      strokeCeil =  Math.ceil(stroke/2);                 // min offset 

     if($.browser.mozilla){                       // Mozilla offsets 

      return { 
       bottom:  strokeFloor, 
       left:  strokeFloor, 
       top:  strokeCeil, 
       right:  strokeCeil 
      }; 

     }else if($.browser.webkit){                      // WebKit offsets 

      return { 
       bottom:  strokeCeil, 
       left:  strokeFloor, 
       top:  strokeFloor, 
       right:  strokeCeil 
      }; 

     }else{                           // default offsets 

      return { 
       bottom:  strokeCeil, 
       left:  strokeCeil, 
       top:  strokeCeil, 
       right:  strokeCeil 
      }; 

     } 

    }; 
4

लोगों के ऊपर है के रूप में ध्यान दिया गया है कि आपको स्ट्रोक के पथ निर्देशांक में ऑफसेट को फिर से गणना करना होगा या इसकी चौड़ाई को दोगुना करना होगा और फिर एक तरफ या दूसरी मास्क मास्क करना होगा, क्योंकि न केवल एसवीजी न केवल इलस्ट्रेटर के स्ट्रोक संरेखण का समर्थन करता है, लेकिन पोस्टस्क्रिप्ट या तो नहीं है।

एडोब के पोस्टस्क्रिप्ट मैनुअल 2 संस्करण राज्यों में स्ट्रोक के लिए विनिर्देश: "4.5.1 पथपाकर: स्ट्रोक ऑपरेटर वर्तमान मार्ग के किनारे कुछ मोटाई की एक पंक्ति ड्रॉ में प्रत्येक सीधे या घुमावदार सेगमेंट के लिए। पथ, स्ट्रोक सेगमेंट पर केंद्रित सेगमेंट पर समांतर सेगमेंट पर एक पंक्ति खींचती है। " (जोर उनके)

शेष विनिर्देश के पास लाइन की स्थिति को ऑफ़सेट करने के लिए कोई विशेषता नहीं है। जब इलस्ट्रेटर आपको अंदर या बाहर संरेखित करने देता है, तो यह वास्तविक पथ के ऑफसेट को दोबारा शुरू कर रहा है (क्योंकि यह अभी भी मास्किंग के बाद ओवरप्रिंटिंग से कम्प्यूटेशनल रूप से सस्ता है)। .ai दस्तावेज़ में पथ निर्देशांक संदर्भ हैं, न कि अंतिम प्रारूप में क्या rastered या निर्यात किया जाता है।

क्योंकि इंकस्केप का मूल प्रारूप एसवीजी का नमूना है, यह कल्पना की कमी की सुविधा प्रदान नहीं कर सकता है।

43

अद्यतन:stroke-alignment विशेषता was on April 1st moved to a completely new spec called SVG Strokes

फरवरी 26 वें, 2015 (और संभवतः के बाद से February 13th) की एसवीजी 2.0 संपादक का ड्राफ्ट के रूप में, मूल्यों inner साथ the stroke-alignment property is present, center(डिफ़ॉल्ट) और outer

ऐसा लगता है कि stroke-location संपत्ति @Phrogz द्वारा प्रस्तावित संपत्ति और बाद में stroke-position suggestion है। यह गुण कम से कम 2011 के बाद से की योजना बनाई गई है, लेकिन अलग एक एनोटेशन कि कहा

एसवीजी 2

स्ट्रोक स्थिति निर्दिष्ट करने के लिए एक तरह से शामिल होगा, यह के रूप में कल्पना में विस्तृत नहीं किया गया है से स्थगित था - अब तक ऐसा लगता है।

कोई ब्राउज़र इस संपत्ति का समर्थन नहीं करता है, या जहां तक ​​मुझे पता है, नई एसवीजी 2 सुविधाओं में से कोई भी, लेकिन उम्मीद है कि जैसे ही यह कल्पना परिपक्व हो जाएगी। यह एक ऐसी संपत्ति रही है जिसे मैं व्यक्तिगत रूप से करने का आग्रह कर रहा हूं, और मैं वास्तव में खुश हूं कि अंत में यह कल्पना में है।

कुछ समस्याएं हैं कि संपत्ति को खुले पथों के साथ-साथ लूप पर कैसे व्यवहार करना चाहिए। इन मुद्दों, सबसे अधिक संभावना है, ब्राउज़रों में कार्यान्वयन लंबे समय तक। हालांकि, मैं इस जानकारी को नई जानकारी के साथ अपडेट कर दूंगा क्योंकि ब्राउज़र इस संपत्ति का समर्थन करना शुरू कर देता है।

+1

'स्ट्रोक-संरेखण' एसवीजी स्ट्रोक, एक डब्ल्यू 3 सी वर्किंग ड्राफ्ट में निर्दिष्ट है। इस बीच, एसवीजी 2 डब्ल्यू 3 सी एडिटर ड्राफ्ट का कहना है कि एक स्ट्रोक पोजीशनिंग संपत्ति एसवीजी स्पेक में https://svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint पर होगी, लेकिन यह कल्पना पहले से ही डब्ल्यू 3 सी उम्मीदवार सिफारिश की स्थिति तक पहुंच चुकी है और इस तरह की कोई संपत्ति 'स्ट्रोक-पोजीशन' प्रस्ताव के लिंक से अलग नहीं है, ऐसा लगता है कि ऐसा नहीं होगा। –

0

ए (गंदा) संभव समाधान, पैटर्न का उपयोग करके है

यहाँ एक अंदर stroked त्रिकोण के साथ एक उदाहरण है:

https://jsfiddle.net/qr3p7php/5/

<style> 
#triangle1{ 
    fill: #0F0; 
    fill-opacity: 0.3; 
    stroke: #000; 
    stroke-opacity: 0.5; 
    stroke-width: 20; 
} 
#triangle2{ 
    stroke: #f00; 
    stroke-opacity: 1; 
    stroke-width: 1; 
}  
</style> 

<svg height="210" width="400" > 
    <pattern id="fagl" patternUnits="objectBoundingBox" width="2" height="1" x="-50%"> 
     <path id="triangle1" d="M150 0 L75 200 L225 200 Z"> 
    </pattern>  
    <path id="triangle2" d="M150 0 L75 200 L225 200 Z" fill="url(#fagl)"/> 
</svg> 
2

यहाँ भीतरी के लिए चारों ओर एक काम हैrectsymbol और use का उपयोग कर सीमाबद्ध।

उदाहरण: https://jsbin.com/yopemiwame/edit?html,output

एसवीजी:

<svg> 
    <symbol id="inner-border-rect"> 
    <rect class="inner-border" width="100%" height="100%" style="fill:rgb(0,255,255);stroke-width:10;stroke:rgb(0,0,0)"> 
    </symbol> 
    ... 
    <use xlink:href="#inner-border-rect" x="?" y="?" width="?" height="?"> 
</svg> 

नोट: वास्तविक मूल्यों के साथ use में ? को बदलने के लिए सुनिश्चित करें।

पृष्ठभूमि: कारण है कि इस काम करता है क्योंकि प्रतीक svg साथ symbol की जगह और छाया डोम में एक तत्व बनाने के द्वारा एक नया व्यूपोर्ट स्थापित करता है। छाया DOM का यह svg तब आपके वर्तमान SVG तत्व से जुड़ा हुआ है। ध्यान दें कि svg एस को नेस्टेड किया जा सकता है और प्रत्येक svg एक नया व्यूपोर्ट बनाता है, जो अतिव्यापी सीमा सहित ओवरलैप करता है जो सब कुछ क्लिप करता है। सारा सूएडन द्वारा this fantastic article पर पढ़ने के बारे में अधिक विस्तृत जानकारी के लिए।

17

मैं एक आसान तरीका है, जो कुछ प्रतिबंध है पाया, लेकिन मेरे लिए काम किया:

  • defs में आकार को परिभाषित
  • आकार
  • संदर्भित इसका इस्तेमाल एक क्लिप पथ को परिभाषित करने और डबल

    <defs> 
        <path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z"/> 
        <clipPath id="clip"> 
         <use xlink:href="#ld"/> 
        </clipPath> 
    </defs> 
    <g> 
        <use xlink:href="#ld" stroke="#0081C6" stroke-width="160" fill="#00D2B8" clip-path="url(#clip)"/> 
    </g> 
    
    : के रूप में बाहर

क्लिप किया गया है यहाँ एक काम कर उदाहरण के साथ स्ट्रोक

+0

सबसे अच्छा जवाब मैंने पाया –

+0

चालाक समाधान। धन्यवाद –

+0

इसे उत्तर के रूप में स्वीकार किया जाना चाहिए। और का उपयोग वर्तमान में उपलब्ध सबसे सुरुचिपूर्ण समाधान है। – Nyerguds

0

मुझे नहीं पता कि यह कितना उपयोगी होगा लेकिन मेरे मामले में मैंने केवल सीमा के साथ एक और सर्कल बनाया और इसे दूसरे आकार में "अंदर" रखा।

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

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