एसवीजी के आर्क पथ के साथ सर्कल ड्राइंग


146

लघु प्रश्न: एसवीजी पथ का उपयोग करके, हम एक वृत्त का 99.99% खींच सकते हैं और यह दिखाता है, लेकिन जब यह एक चक्र का 99.99999999% होता है, तो वृत्त दिखाई नहीं देगा। इसका समाधान कैसे किया जा सकता है?

निम्नलिखित एसवीजी पथ एक सर्कल का 99.99% आकर्षित कर सकता है: (इसे http://jsfiddle.net/DFhUF/1381/ पर देखें और देखें कि क्या आप 4 आर्क्स या केवल 2 आर्क्स देखते हैं, लेकिन ध्यान दें कि यदि यह IE है, तो यह वीएमएल में प्रस्तुत किया गया, एसवीजी नहीं, लेकिन इसी तरह का मुद्दा है)

M 100 100 a 50 50 0 1 0 0.00001 0

लेकिन जब यह एक सर्कल का 99.99999999% है, तो कुछ भी नहीं दिखाएगा?

M 100 100 a 50 50 0 1 0 0.00000001 0    

और यह एक चक्र के 100% के साथ एक ही है (यह अभी भी एक चाप है, यह नहीं है, बस एक बहुत ही पूर्ण चाप है)

M 100 100 a 50 50 0 1 0 0 0 

यह कैसे तय किया जा सकता है? कारण यह है कि मैं एक आर्क के प्रतिशत को आकर्षित करने के लिए एक फ़ंक्शन का उपयोग करता हूं, और अगर मुझे सर्कल फ़ंक्शन का उपयोग करने के लिए 99.9999% या 100% चाप की "विशेष स्थिति" की आवश्यकता है, तो यह मूर्खतापूर्ण होगा।

फिर, रफएलजेएस का उपयोग करके jsfiddle पर एक परीक्षण मामला http://jsfiddle.net/DFhUF/1381/ पर है
(और अगर यह IE 8 पर VML है, तो दूसरा सर्कल भी नहीं दिखाएगा ... आपको इसे बदलना होगा 0.01)


अपडेट करें:

ऐसा इसलिए है क्योंकि मैं हमारे सिस्टम में एक अंक के लिए एक चाप प्रदान कर रहा हूं, इसलिए 3.3 अंक एक सर्कल का 1/3 मिलता है। 0.5 को आधा चक्र मिलता है, और 9.9 अंक एक चक्र का 99% मिलता है। लेकिन क्या होगा अगर हमारे सिस्टम में 9.99 स्कोर हैं? क्या मुझे यह जांचना होगा कि क्या यह एक सर्कल के 99.999% के करीब है, और तदनुसार arcफ़ंक्शन या फ़ंक्शन का उपयोग करें circle? फिर 9.9987 के स्कोर के बारे में क्या? कौन सा उपयोग करना है? यह जानना हास्यास्पद है कि किस तरह के स्कोर "बहुत संपूर्ण सर्कल" में जाएंगे और एक सर्कल फ़ंक्शन पर स्विच करेंगे, और जब यह सर्कल का "एक निश्चित 99.9%" या 9.9987 स्कोर होगा, तो आर्क फ़ंक्शन का उपयोग करें। ।


@minitech बेशक यह काम करता है ... यह एक सर्कल का 99% है (बस मोटे तौर पर बोल रहा है)। मामला यह है कि यह एक सर्कल में 98%, 99%, 99.99% आकर्षित कर सकता है, लेकिन 99.9999999% या 100% नहीं है
गैर

1
वे दोनों लिंक एक ही चीज़ पर जाते हैं, और यह सफारी में ठीक काम करता है।
मार्क बेसी

सही, एक ही लिंक, मैं बस लोगों को परीक्षण के मामले को देखना चाहता हूं इसलिए मैं सवाल की शुरुआत में लिंक जोड़ता हूं। सही सफारी यह करेगा, कितना अच्छा ... क्रोम और फ़ायरफ़ॉक्स नहीं होगा ... अजीब coz सफारी और क्रोम दोनों Webkit की तरह हैं ... लेकिन क्या SVG इंजन Webkit पर निर्भर करता है?
nonopolarity

@Marcin ठीक लग रहा है कैसे? क्या आप 4 आर्क्स या 2 आर्क्स देखते हैं? क्या आपने भी कोड को देखा?
१३:४६ में एकाधिकार

2
राफेल के साथ एक अपडेटेड jsfiddle में लाइब्रेरी के रूप में शामिल, क्रॉस-ओरिजनल एरर लोडिंग राफेल.जेएस पाने के लिए: jsfiddle.net/DFhUF/1381
ericsoco

जवाबों:


35

XAML के आर्क के लिए भी। बस 99.99% चाप को बंद करें Zऔर आपको एक सर्कल मिल गया है!


तो क्या आप jsfiddle नमूने में तीसरे मामले को बंद कर सकते हैं और इसे काम कर सकते हैं?
nonopolarity

मान को 0.0001 पर कम करने के साथ, हाँ। समस्या वेबकेट के विभिन्न ब्राउज़र के कार्यान्वयन से संबंधित है, एसवीजी ही नहीं। लेकिन यह है कि आप एसवीजी / एक्सएएमएलएस आर्क घटक में एक सर्कल कैसे बनाते हैं।
टोड मेन

आह, धोखा, हमेशा सबसे अच्छा समाधान। अभी भी 100% मामले को संभालने की जरूरत है, लेकिन सिर्फ एक "अलग कोड शाखा के बजाय 99.999% करने के लिए" नीचे "गोल करके"।
सिमोन

कोई डेमो? यह उत्तर पूरा नहीं होता है
मेडेट टिलुकएबुल

@MedetTleukabiluly आपके पास सवाल में ऊपर का आर्क है, zअंत में एक और जोड़ें । आपको शून्य को हटाना पड़ सकता है, उदाहरण के लिए नवीनतम क्रोम में मुझे 0.0001इसे बनाने के लिए लिखना होगा। यदि आप पाथ स्ट्रिंग लगाने के लिए देख रहे हैं, MDN पर पाथ देखें
ट्वीस्टरेब

415

मुझे पता है कि यह खेल में थोड़ा देर से है, लेकिन मुझे यह सवाल याद था कि यह कब से नया था और मेरे पास एक समान डिल्मा था, और मुझे गलती से "सही" समाधान मिला, अगर कोई अभी भी एक की तलाश में है:

<path 
    d="
    M cx cy
    m -r, 0
    a r,r 0 1,0 (r * 2),0
    a r,r 0 1,0 -(r * 2),0
    "
/>

दूसरे शब्दों में, यह:

<circle cx="100" cy="100" r="75" />

इसके साथ एक पथ के रूप में प्राप्त किया जा सकता है:

  <path 
        d="
        M 100, 100
        m -75, 0
        a 75,75 0 1,0 150,0
        a 75,75 0 1,0 -150,0
        "
  />

चाल में दो आर्क्स होते हैं, दूसरा वह उठाता है जहां पहला छोड़ा जाता है और मूल चाप बिंदु पर वापस जाने के लिए नकारात्मक व्यास का उपयोग करता है।

इसका कारण एक चाप में पूर्ण चक्र के रूप में नहीं किया जा सकता है (और मैं सिर्फ अटकलें लगा रहा हूं) क्योंकि आप इसे खुद से एक चाप खींचने के लिए कह रहे होंगे (चलो 150,150 कहते हैं) अपने आप में (150,150), जो इसे प्रस्तुत करता है के रूप में "ओह, मैं पहले से ही वहाँ हूँ, कोई चाप आवश्यक!"।

मैं जो समाधान पेश कर रहा हूं उसके लाभ हैं:

  1. एक सर्कल से सीधे एक पथ पर अनुवाद करना आसान है, और
  2. दो चाप लाइनों में कोई ओवरलैप नहीं है (यदि आप मार्कर या पैटर्न आदि का उपयोग कर रहे हैं तो समस्या हो सकती है)। यह एक साफ निरंतर रेखा है, यद्यपि दो टुकड़ों में खींची गई है।

इस बात से कोई फर्क नहीं पड़ता कि क्या वे सिर्फ पाठपाठों को आकार स्वीकार करने देंगे। लेकिन मुझे लगता है कि वे उस समाधान से बच रहे हैं क्योंकि सर्कल जैसे आकार के तत्व तकनीकी रूप से "स्टार्ट" बिंदु नहीं हैं।

jsfiddle डेमो: http://jsfiddle.net/crazytonyi/mNt2g/

अपडेट करें:

यदि आप एक textPathसंदर्भ के लिए पथ का उपयोग कर रहे हैं और आप पाठ को आर्क के बाहरी किनारे पर रेंडर करना चाहते हैं, तो आप ठीक उसी विधि का उपयोग करेंगे लेकिन स्वीप-फ़्लैग को 0 से 1 में बदल दें ताकि यह बाहर का व्यवहार करे अंदर के बजाय सतह के रूप में पथ ( 1,0केंद्र में बैठे किसी व्यक्ति के रूप में सोचें और खुद के चारों ओर एक वृत्त खींचे, जबकि 1,1कोई व्यक्ति केंद्र के चारों ओर त्रिज्या दूरी पर घूम रहा है और उनके बगल में अपने चाक को खींच रहा है, अगर यह कोई मदद है)। यहाँ ऊपर के रूप में कोड है लेकिन परिवर्तन के साथ:

<path 
    d="
    M cx cy
    m -r, 0
    a r,r 0 1,1 (r * 2),0
    a r,r 0 1,1 -(r * 2),0
    "
/>

1
+1, सूत्र के लिए धन्यवाद। बेशक, पहले दो आदेशों को समेकित किया जा सकता था।
जॉन गिएटजन

+1 सामान्य रूप से समाधान की स्पष्टता और व्यावहारिकता के लिए, लेकिन विशेष रूप से 'आकार के तत्वों जैसे सर्कल के लिए तकनीकी रूप से "प्रारंभ" बिंदु नहीं है - समस्या को व्यक्त करने का ऐसा स्पष्ट तरीका।
डेविड जॉन वेल्श

11
मुझे लगता है कि यहां समस्या यह नहीं है कि "ओह, मैं पहले से ही वहां हूं, कोई आर्क आवश्यक नहीं है!", जैसा कि 1 प्रदान करते हैं बड़े-आर्क-ध्वज के रूप में आप स्पष्ट रूप से इंजन को बताते हैं कि आप चाहते हैं कि यह आगे का रास्ता तय करे। असली समस्या यह है कि असीम रूप से कई वृत्त हैं जो आपकी बात को गर्त में समेटने में पूरी तरह से बाधा डालते हैं। यह बताता है कि जब आप 360 * आर्क चाहते हैं, तो इंजन को पता नहीं है कि क्या करना है। 359.999 के लिए काम नहीं करने का कारण यह है कि यह संख्यात्मक रूप से अस्थिर संगणना है, और जबकि तकनीकी रूप से ठीक एक सर्कल है जो अनुरोध से मेल खाता है, यह संभवतः वह नहीं होगा जो आप किसी भी तरह चाहते थे
क्यूबलेक

@qbolec - आप सही कह रहे हैं, मैं बड़े-चाप और स्वीप के बंद होने और किसी भी गंतव्य के न होने के संदर्भ में सोच रहा था। या बहुत कम से कम कि यहां तक ​​कि बड़े-चाप और स्वीप के साथ भी सक्षम है कि कुछ मौलिक डिजाइन था जो एक आर्क को दो बिंदुओं के बीच वक्र के रूप में परिभाषित करता था (ताकि दो बार इस्तेमाल किए गए एक बिंदु के साथ, यह एक ढह गए एकल बिंदु के रूप में देखा।) आपका एक बिंदु के आस-पास 360 मंडलियों को आकर्षित करने वाले चाप की दृष्टि से समझ में आता है, हालांकि अगर यह एक केंद्र को परिभाषित करता है, तो यह एक चक्र तक गिर जाएगा, जो एक केंद्र होने पर एकल चाप बनाने का सवाल उठाता है?
एंथनी

1
"सर्कल जैसे आकार के तत्वों में तकनीकी रूप से" प्रारंभ "बिंदु नहीं है"। यह वास्तव में सच नहीं है। एसवीजी कल्पना बिल्कुल निर्दिष्ट करती है जहां सभी आकृतियों का प्रारंभ बिंदु है। आकृतियों पर काम करने के लिए डैश सरणियों के लिए ऐसा करना पड़ता है।
पॉल लेबू

17

एंथनी के समाधान के संदर्भ में, यहां एक रास्ता मिल रहा है:

function circlePath(cx, cy, r){
    return 'M '+cx+' '+cy+' m -'+r+', 0 a '+r+','+r+' 0 1,0 '+(r*2)+',0 a '+r+','+r+' 0 1,0 -'+(r*2)+',0';
}

10

एक पूरी तरह से अलग दृष्टिकोण:

Svg में आर्क निर्दिष्ट करने के लिए रास्तों के साथ फ़िडलिंग के बजाय, आप छद्म कोड में, एक वृत्त तत्व भी ले सकते हैं और एक स्ट्रोक-दशहरा भी निर्दिष्ट कर सकते हैं:

with $score between 0..1, and pi = 3.141592653589793238

$length = $score * 2 * pi * $r
$max = 7 * $r  (i.e. well above 2*pi*r)

<circle r="$r" stroke-dasharray="$length $max" />

कई-चाप-पथ विधि पर इसकी सादगी मुख्य लाभ है (उदाहरण के लिए जब आप स्क्रिप्टिंग केवल एक मूल्य में प्लग करते हैं और आप प्रत्येक आर्क लंबाई के लिए किया जाता है)

चाप सबसे सही बिंदु पर शुरू होता है, और एक घुमाव परिवर्तन का उपयोग करके इसे चारों ओर स्थानांतरित किया जा सकता है।

नोट: फ़ायरफ़ॉक्स में एक अजीब बग है जहां 90 डिग्री या उससे अधिक घुमाव पर ध्यान नहीं दिया जाता है। तो ऊपर से चाप शुरू करने के लिए, उपयोग करें:

<circle r="$r" transform="rotate(-89.9)" stroke-dasharray="$length $max" />

ज्ञात रहे कि यह समाधान केवल उन मामलों के लिए लागू होता है जहाँ आप किसी प्रकार के भरण का उपयोग नहीं कर रहे हैं और आपको केवल बिना किसी विचलन वाले चाप खंड की आवश्यकता है। जिस क्षण आप उन क्षेत्रों को आकर्षित करना चाहते हैं, जिनके लिए आपको एक नए svg पाथ नोड की आवश्यकता होती है, जिसे अन्यथा एकल पथ टैग में संभाला जा सकता है।
mxfh

@ mxfh वास्तव में नहीं है, यदि आप स्ट्रोक-चौड़ाई को दो बार r के मान से लेते हैं तो आपको सही सेक्टर मिलते हैं।
एमवीडी

इसके साथ stroke-dasharray="0 10cm 5cm 1000cm"परिवर्तन से बचना संभव है
stenci

@stenci हाँ, लेकिन नकारात्मक पक्ष यह है कि आपके पास दशर्रे में 0% से 100% भरने के पैमाने के लिए एक पैरामीटर नहीं हो सकता है (जो मेरे उद्देश्यों में से एक था)
mvds

5

एडोब इलस्ट्रेटर एसवीजी की तरह बीज़र घटता का उपयोग करता है, और हलकों के लिए यह चार अंक बनाता है। आप दो अण्डाकार चाप कमांड के साथ एक सर्कल बना सकते हैं ... लेकिन एसवीजी में एक सर्कल के लिए मैं एक <circle />:) का उपयोग करेगा


"आप दो अण्डाकार चाप कमांड के साथ एक सर्कल बना सकते हैं"? आपका मतलब क्या है? तुम सिर्फ एक का उपयोग नहीं कर सकते? कम से कम (0,0) से (0.01, 0) तक जाने के लिए ताकि यह कुछ प्रदान करता है। उपयोग करने के लिए circle, कृपया इसके बजाय प्रश्न में अद्यतन देखें ।
गैरबराबरी

नहीं, मुझे नहीं लगता कि आप सिर्फ एक का उपयोग कर सकते हैं। आपने दिखाया है कि आप नहीं कर सकते हैं, और आपको HTML5 कैनवस आर्क के साथ एक समान समस्या है।
फ्रॉग्ज

आपका मतलब है, arcबाईं चाप और दाईं चाप का उपयोग करके एक पूर्ण चक्र बनाने के लिए? तो चाप एक पूर्ण चक्र नहीं खींच सकता है ... ऐसा करने के लिए दो arcरास्तों की आवश्यकता होती है
एकाधिकार

2
@ Are, सही, दो आर्क पथ की जरूरत है (या एक चाप के बदसूरत हैक सबसे अधिक रास्ते में जा रहा है और फिर अंत तक सीधी रेखा के लिए एक करीबी कमांड)।
फ्रॉग्ज

1
इलस्ट्रेटर बेकार है। आप bezier घटता के साथ एक चक्र नहीं बना सकते। केवल एक सर्कल के करीब कुछ है, लेकिन अभी भी एक सर्कल नहीं है।
adius

4

यह एक अच्छा विचार है कि एक पूर्ण सर्कल बनाने के लिए दो आर्क कमांड का उपयोग किया जाता है।

आमतौर पर, मैं एक पूर्ण वृत्त खींचने के लिए दीर्घवृत्त या वृत्त तत्व का उपयोग करता हूं।


5
Svg की एक प्रमुख सीमा यह है कि पाठ पथों के लिए आकार तत्वों का उपयोग नहीं किया जा सकता है। यह इस सवाल पर जाने वाले सभी लोगों के लिए प्राथमिक प्रेरणा है।
एंथनी

1
@ अब वे कर सकते हैं। फ़ायरफ़ॉक्स किसी भी आकार के खिलाफ textPath का समर्थन करता है। मुझे शक है कि क्रोम भी करता है।
रॉबर्ट लोंगसन

@RobertLongson - क्या आप एक उदाहरण या उदाहरण के लिए लिंक प्रदान कर सकते हैं? जिज्ञासु यह कैसे तय करता है कि पाठ पथ कहाँ से शुरू होता है और क्या यह बाहर या अंदर (आदि) पर होता है जब इसे बिना पारंपरिक आरंभ बिंदु के खींचा जाता है।
एंथनी

@Anthony SVG 2 विनिर्देश देखें उदाहरण के लिए w3.org/TR/SVG2/shapes.html#CircleElement , नया टेक्स्टपथ साइड का गुण भी
रॉबर्ट लोंगसन

4

एंथनी और एंटोन के उत्तरों पर बिल्डिंग मैंने समग्र स्वरूप को प्रभावित किए बिना उत्पन्न सर्कल को घुमाने की क्षमता को शामिल किया। यह उपयोगी है यदि आप एक एनीमेशन के लिए पथ का उपयोग कर रहे हैं और आपको यह नियंत्रित करने की आवश्यकता है कि यह कहां से शुरू होता है।

function(cx, cy, r, deg){
    var theta = deg*Math.PI/180,
        dx = r*Math.cos(theta),
        dy = -r*Math.sin(theta);
    return "M "+cx+" "+cy+"m "+dx+","+dy+"a "+r+","+r+" 0 1,0 "+-2*dx+","+-2*dy+"a "+r+","+r+" 0 1,0 "+2*dx+","+2*dy;
}

मुझे ठीक इसी की आवश्यकता थी। मैं एक आयताकार पथ के लिए एक सर्कल पथ को आकार देने के लिए greensock मॉर्फ प्लगइन का उपयोग कर रहा था और इसे सही देखने के लिए इसे प्राप्त करने के लिए एक मामूली रोटेशन की आवश्यकता थी।
रोबोकोज़ो

3

मेरे जैसे उन लोगों के लिए जो मार्ग परिवर्तन के लिए एक दीर्घवृत्त विशेषताओं की तलाश में थे:

const ellipseAttrsToPath = (rx,cx,ry,cy) =>
`M${cx-rx},${cy}a${rx},${ry} 0 1,0 ${rx*2},0a${rx},${ry} 0 1,0 -${rx*2},0`

2

एक समारोह के रूप में लिखा, यह इस तरह दिखता है:

function getPath(cx,cy,r){
  return "M" + cx + "," + cy + "m" + (-r) + ",0a" + r + "," + r + " 0 1,0 " + (r * 2) + ",0a" + r + "," + r + " 0 1,0 " + (-r * 2) + ",0";
}

2
यह एक महान जवाब है! बस एक छोटा सा जोड़: यह रास्ता पूर्व, उत्तर, पश्चिम, दक्षिण की ओर खींचा गया है। आप चक्र वास्तव में एक की तरह व्यवहार करना चाहते हैं <circle>, तो आप पूर्व, दक्षिण, पश्चिम, उत्तर करने के लिए दिशा बदलने के लिए है: "M" + cx + "," + cy + "m" + (r) + ",0" + "a" + r + "," + r + " 0 1,1 " + (-r * 2) + ",0" + "a" + r + "," + r + " 0 1,1 " + (r * 2) + ",0" लाभ यह है कि है stroke-dashoffsetऔर startOffsetअब उसी तरह काम करते हैं।
loominade

2

ये उत्तर बहुत अधिक जटिल हैं।

दो आर्क्स बनाने या विभिन्न समन्वय प्रणालियों में परिवर्तित किए बिना ऐसा करने का एक सरल तरीका है।

यह मानता है कि आपके कैनवास क्षेत्र की चौड़ाई wऔर ऊंचाई है h

`M${w*0.5 + radius},${h*0.5}
 A${radius} ${radius} 0 1 0 ${w*0.5 + radius} ${h*0.5001}`

बस "लंबे चाप" ध्वज का उपयोग करें, इसलिए पूर्ण ध्वज भरा हुआ है। फिर 99.9999% पूर्ण वृत्त को आर्क्स बनाएं। नेत्रहीन यह एक ही है। सर्कल में सबसे सही बिंदु पर सर्कल को शुरू करने से स्वीप फ्लैग से बचें (केंद्र से एक सीधा त्रिज्या)।


1

दूसरा तरीका दो क्यूबिक बेजियर कर्व्स का उपयोग करना होगा। यह पॉकेट एसवीजी का उपयोग करने वाले आईओएस लोगों के लिए है जो कि एसवीजी आर्क पैरामीटर को नहीं पहचानते हैं।

C X1 y1, x2 y2, xy (या c dx1 dy1, dx2 dy2, dx dy)

घन बेज़ियर वक्र

यहाँ निर्देशांक का अंतिम सेट (x, y) है जहाँ आप लाइन को समाप्त करना चाहते हैं। अन्य दो नियंत्रण बिंदु हैं। (X1, y1) आपके वक्र के प्रारंभ के लिए नियंत्रण बिंदु है, और (x2, y2) आपके वक्र के अंतिम बिंदु के लिए।

<path d="M25,0 C60,0, 60,50, 25,50 C-10,50, -10,0, 25,0" />

1

मैंने इसे यहाँ करने के लिए एक jsfiddle बनाया:

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}

function describeArc(x, y, radius, startAngle, endAngle){

var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);

var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

var d = [
    "M", start.x, start.y, 
    "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
].join(" ");

return d;       
}
console.log(describeArc(255,255,220,134,136))

संपर्क

आपको बस इतना करना है कि कंसोल के इनपुट को बदल दें और कंसोल में परिणाम प्राप्त करें


यह ठीक वही है जिसकी मुझे तलाश थी। सबसे अच्छा जवाब यहाँ! इस लड़के को आगे बढ़ाएं
Måns Dahlström
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.