क्या आप नियंत्रित कर सकते हैं कि एसवीजी की स्ट्रोक-चौड़ाई कैसे खींची जाती है?


204

वर्तमान में एक ब्राउज़र-आधारित एसवीजी एप्लिकेशन का निर्माण। इस एप्लिकेशन के भीतर, विभिन्न आकृतियों को आयत सहित उपयोगकर्ता द्वारा स्टाइल और पोस्ट किया जा सकता है।

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

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

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

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

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


वहाँ फिल्टर हैक्स आप इसे प्राप्त करने के लिए उपयोग कर सकते हैं - लेकिन यह एक महान समाधान नहीं है
माइकल मुल्तानी

2
वहाँ paint-orderपैरामीटर है, जहां आप निर्दिष्ट कर सकते हैं, कि भराव स्ट्रोक के शीर्ष पर प्रदान किया जाना चाहिए, इसलिए आपको "बाहरी संरेखण" मिलेगा, jsfiddle.net/hne0kyLg/1
इवान कुकिर

Css 'आउटलाइन-' विशेषताएँ: codepen.io/badcat/pen/YVznYY का उपयोग करके ऐसा करने का एक तरीका मिला । यह निश्चित नहीं है कि ब्राउज़रों के लिए इसका समर्थन क्या है, लेकिन उपयोगी हो सकता है।
bplmp 12

जवाबों:


375

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

SVG ने स्ट्रोक-लोकेशन का उदाहरण पेश किया, phrogz.net/SVG/stroke-location.svg से

जैसा कि मैंने प्रस्ताव में उल्लेख किया है,

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

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

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

संपादन 3 : मनोरंजक और असंतुष्ट रूप से, SVG वर्किंग ग्रुप ने stroke-alignmentSVG 2 को हटा दिया है। आप यहाँ गद्य के बाद वर्णित कुछ चिंताओं को देख सकते हैं ।


2
सोचा कि मामला हो सकता है। इसे हल करने के लिए मैंने getBBox () के लिए एक रैपर फ़ंक्शन लिखा है जिसे getStrokedBBox () कहा जाता है। यह रैपर BBox देता है कि कैसे ब्राउज़र इनसेट पर आघात करता है और किसी आकृति की भरपाई करता है। यह सही नहीं है (नवीनतम ब्राउज़र संस्करणों के खिलाफ जाँच रखने की आवश्यकता है), लेकिन यह सटीक रूप से अभी के लिए एक बाहरी चौड़ाई प्रदान करता है।
स्टीव

6
@ फ्रॉग शायद 10 साल बीत जाने से पहले हम इसे देख लेंगे। svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint एनोटेशन
डिमोन

1
यह अंत में यहाँ है! मैं, एक के लिए, वास्तव में इस संपत्ति के आने के लिए आग्रह कर रहा हूं।
mnsth

मैंने किसी भी एसवीजीग्रोमेट्रीमेंट के समोच्च को ट्रेस करने के लिए एक svg-contour स्क्रिप्ट बनाई, जिसका उपयोग स्ट्रोक-संरेखण के वर्कअराउंड के रूप में किया जा सकता है, किसी के लिए भी आप यहां
maioman

2
क्या कोई ऐसा पृष्ठ है जहां मैं प्रस्ताव के लिए आवेदन कर सकता हूं? धन्यवाद। हास्यास्पद लगता है यह समर्थित नहीं है।
महिष

57

अद्यतन:stroke-alignment विशेषता 1st अप्रैल, 2015 एक पूरी तरह से नए कल्पना एसवीजी स्ट्रोक कहा जाता है के लिए ले जाया गया था पर

एसवीजी 2.0 के संपादक के 26 फरवरी, 2015 के प्रारूप के अनुसार (और संभवतः 13 फरवरी से )stroke-alignmentसंपत्ति मौजूद हैमूल्यों के साथ inner, center (डिफ़ॉल्ट) और outer

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

एसवीजी 2 में स्ट्रोक की स्थिति को निर्दिष्ट करने का एक तरीका शामिल होगा

, यह कल्पना में कभी विस्तृत नहीं हुआ क्योंकि इसे स्थगित कर दिया गया था - अब तक, ऐसा लगता है।

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

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


1
stroke-alignmentएसवीजी स्ट्रोक, एक डब्ल्यू 3 सी वर्किंग ड्राफ्ट में निर्दिष्ट है। इस बीच, एसवीजी 2 डब्लू 3 सी एडिटर के ड्राफ्ट का कहना है कि एक स्ट्रोक पोजिशनिंग प्रॉपर्टी svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint में SVG स्पेक में होगी , लेकिन यह डब्लू 3 सी कैंडिडेट की सिफारिश की स्थिति तक पहुंच चुका है और ऐसी कोई प्रॉपर्टी नहीं है। stroke-positionप्रस्ताव के लिए एक लिंक से एक तरफ कल्पना में , ऐसा लगता है कि ऐसा नहीं होगा।
पैट्रिक डार्क

47

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

  • डिफ में आकार को परिभाषित करें
  • आकृति को संदर्भित करते हुए एक क्लिप पथ को परिभाषित करें
  • इसका उपयोग करें और स्ट्रोक को दोगुना करें क्योंकि बाहर की क्लिप लगी हुई है

यहाँ एक कार्य उदाहरण:

<svg width="240" height="240" viewBox="0 0 1024 1024">
<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>
</svg>


2
सबसे अच्छा जवाब मुझे मिला
एड कोलोसोव्स्की

1
चतुर समाधान। धन्यवाद
विन्स युआन

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

अच्छा समाधान। आप इसे बाहर का स्ट्रोक बनाने के लिए कैसे उलट देंगे?
लूसेंट

शीर्ष-स्तर क्यों <use>? क्यों नहीं सीधे रास्ते और क्लिप पथ को सीधे रखा? यह ठीक काम करता है <svg width="240" height="240" viewBox="0 0 1024 1024"> <path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z" clip-path="url(#clip)" stroke="#0081C6" stroke-width="160" fill="#00d2b8"/> <clipPath id="clip"> <use xlink:href="#ld"/> </clipPath> </svg>:। (हां, यह पूरी तरह से उचित और सही एसवीजी है और हर जगह सही ढंग से प्रस्तुत करेगा। डर नहीं पुनरावृत्ति।)
क्रिस मॉर्गन

30

आप सीएसएस का उपयोग स्ट्रोक के क्रम को भरने और भरने के लिए कर सकते हैं। यही है, पहले स्ट्रोक करें और फिर दूसरा भरें, और वांछित प्रभाव प्राप्त करें।

MDN ऑन paint-order: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/paint-order

सीएसएस कोड:

paint-order: stroke;

यह पूर्ण है! साझा करने के लिए धन्यवाद
ब्रूनोफेन्गल

1
लिंक किए गए दस्तावेज़ से यह संकेत नहीं मिलता है कि स्ट्रोक अंदर, बाहर या केंद्रित है? क्या आप स्पष्ट कर सकते हैं कि स्ट्रोक को कैसे नियंत्रित किया जाए? धन्यवाद।
Crashalot

2
स्ट्रोक केंद्रित है, जैसा कि यह हमेशा था - लेकिन अगर आपके पास एक ठोस भराव है, तो पेंट ऑर्डर को स्ट्रोक से पेंट करने के लिए सबसे पहले समायोजित करने का प्रभाव यह है कि स्ट्रोक के अंदरूनी आधे हिस्से को चित्रित किया गया है, जिसका एक ड्राइंग के समान प्रभाव है बाहर की तरह आधा घना आघात।
क्रिस मॉर्गन

7

यहां एक फ़ंक्शन है जो गणना करेगा कि आपको कितने पिक्सेल जोड़ने की आवश्यकता है - दिए गए स्ट्रोक का उपयोग करके - ऊपर, दाएं, नीचे और बाएं, सभी ब्राउज़र पर आधारित:

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
            };

        }

    };

6

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

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

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

Inkscape के मूल प्रारूप में एसवीजी होने का अनुमान होने के कारण, यह उस विशेषता की कमी की पेशकश नहीं कर सकता है।


4

यहाँ के लिए एक काम के आसपास है भीतरी bordered rect का उपयोग कर symbolऔर 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वास्तविक मूल्यों के साथ।

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


2

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


0

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

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

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>

0

स्ट्रोक की चौड़ाई को दोगुना करने और पेंट-ऑर्डर को बदलने के जेवियर हो से समाधान शानदार है, हालांकि केवल तभी काम करता है यदि भराव एक ठोस रंग है, जिसमें कोई पारदर्शिता नहीं है।

मैंने अन्य दृष्टिकोण विकसित किए हैं, और अधिक जटिल लेकिन किसी भी भरने के लिए काम करता है। यह दीर्घवृत्त या पथों में भी काम करता है (बाद में अजीब व्यवहार के साथ कुछ कोने के मामले होते हैं, उदाहरण के लिए खुले रास्ते जो अपने आप को पार करते हैं, लेकिन बहुत ज्यादा नहीं)।

चाल को दो परतों में आकार प्रदर्शित करना है। एक बिना स्ट्रोक (केवल भराव), और दूसरा केवल डबल चौड़ाई (पारदर्शी भराव) पर स्ट्रोक के साथ और एक मुखौटा के माध्यम से पारित हुआ जो पूरे आकार को दर्शाता है, लेकिन स्ट्रोक के बिना मूल आकार को छुपाता है।

  <svg width="240" height="240" viewBox="0 0 1024 1024">
  <defs>
    <path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z"/>
    <mask id="mask">
      <use xlink:href="#ld" stroke="#FFFFFF" stroke-width="160" fill="#FFFFFF"/>
      <use xlink:href="#ld" fill="#000000"/>
    </mask>
  </defs>
  <g>
    <use xlink:href="#ld" fill="#00D2B8"/>
    <use xlink:href="#ld" stroke="#0081C6" stroke-width="160" fill="red" mask="url(#mask)"/>
  </g>
  </svg>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.