PerfectVector
लेखक: Irene Kim8 मिनट का पठन

SVG बॉक्स सीमाएँ: सही निर्देशांक मापें

ट्रांसफ़ॉर्म SVG कलाकृति पर getBBox और getBoundingClientRect तुलना करें। ओवरले सही रखें, स्ट्रोक सीमा परखें और किनारों पर तय खाली जगह छोड़कर viewBox फ़िट करें।

इस पेज पर

SVG तत्व की अपने उपयोगकर्ता निर्देशांकों में सीमा चाहिए तो getBBox() दें। ब्राउज़र व्यूपोर्ट के सापेक्ष CSS पिक्सेल आयत चाहिए तो getBoundingClientRect() दें। परिणाम ओवरले या viewBox में कॉपी करने से पहले गंतव्य का निर्देशांक तंत्र जाँचें।

घुमाए प्रतीक का स्थानीय बॉक्स छोटा और स्क्रीन से संरेखित बॉक्स बहुत बड़ा हो सकता है। दोनों माप सही हो सकते हैं। किसी को हर रंगे पिक्सेल का सार्वभौमिक आयत न मानें, खासकर स्ट्रोक, मार्कर, क्लिपिंग या फ़िल्टर हों।

गंतव्य के लिए माप चुनें

गंतव्यशुरुआती मापज़रूरी सावधानी
समान SVG निर्देशांक तंत्र का आयतgetBBox()आयत को मेल खाता ट्रांसफ़ॉर्म संदर्भ दें
स्थिर HTML चयन आउटलाइनgetBoundingClientRect()व्यूपोर्ट निर्देशांक रखें और लेआउट बदलने पर अपडेट करें
ट्रांसफ़ॉर्म समूह के आसपास रूट SVG viewBoxस्थानीय बॉक्स और निर्देशांक ट्रांसफ़ॉर्मफ़िट से पहले रूट उपयोगकर्ता इकाइयों में बदलें
स्ट्रोक और प्रभाव सहित क्रॉपअलग सत्यापित सीमा प्रक्रियामूल ज्यामिति बॉक्स में पूरा रंग मानकर न चलें

MDN का getBBox() दस्तावेज़ स्थानीय ज्यामिति सीमा और वैकल्पिक स्ट्रोक, मार्कर तथा क्लिपिंग नियंत्रण बताता है। मापे तत्व का अपना और ऊपरी तत्वों का ट्रांसफ़ॉर्म स्थानीय परिणाम में नहीं है। समूह के भीतर के तत्व उनकी स्थिति सहित समूह ज्यामिति में योगदान देते हैं।

MDN का getBoundingClientRect() संदर्भ व्यूपोर्ट-सापेक्ष निर्देशांक बताता है। स्क्रोलिंग वह संबंध बदलती है। CSS पिक्सेल मान अपने-आप SVG उपयोगकर्ता इकाइयाँ या भौतिक प्रिंट आयाम नहीं हैं।

क्षैतिज स्क्रीन आयत के भीतर मेल खाते तिरछे स्थानीय आयत वाले झुके प्रतीक का चित्रण
दो निर्देशांक तंत्रों का वैचारिक चित्रण। स्थानीय आयत कलाकृति के अक्ष लेता है; व्यूपोर्ट आयत स्क्रीन से संरेखित रहता है।

मौलिक ट्रांसफ़ॉर्म प्रतीक मापें

नमूने में आयताकार खुली जगह वाला नीला-हरा छल्ला और अलग सुनहरा त्रिकोण हैं। दोनों का मोटा, गोल जोड़ वाला स्ट्रोक है। समूह खिसकाया, घुमाया और आकार बदला है।

<svg id="scene" width="600" height="300" viewBox="0 0 300 150"
     xmlns="http://www.w3.org/2000/svg" style="overflow:visible">
  <g id="art" transform="translate(100 35) rotate(25) scale(1.2)"
     stroke="#17364c" stroke-width="10" stroke-linejoin="round">
    <path fill="#147d78" fill-rule="evenodd"
          d="M0 0H80V60H0Z M20 20H60V40H20Z" />
    <path fill="#e5a340" d="M100 50L120 10L140 50Z" />
  </g>
</svg>
<script>
  const art = document.querySelector("#art");
  const local = art.getBBox();
  const screen = art.getBoundingClientRect();
</script>

स्थानीय निर्देशांक क्षैतिज 0 से 140 और लंबवत 0 से 60 हैं। छेद भीतर की आकृति प्रभावित करता है, लेकिन बाहरी विस्तार नहीं घटाता।

हमने Chrome में ज्यामिति खोलकर छोटे उपकरण से मापी। 600 × 300 CSS पिक्सेल प्रदर्शन पर getBBox() ने x=0, y=0, width=140, height=60 दिया। क्लाइंट आयत लगभग 365.376 × 272.508 CSS पिक्सेल था। स्क्रीन स्थान पेज पर SVG की जगह पर निर्भर था।

प्रदर्शन आकार 300 × 150 करने पर स्थानीय बॉक्स 140 × 60 रहा। क्लाइंट आयत लगभग 182.688 × 136.254, यानी पहले का आधा हुआ। स्रोत ज्यामिति नहीं बदली थी; पेज पर मैपिंग बदली।

ये अंक परीक्षित ब्राउज़र में इस नमूने के हैं। वे ब्राउज़र इंजन की तुलना या हर संपादक के चयन बॉक्स का विनिर्देश नहीं।

हर आउटलाइन अपने निर्देशांक तंत्र में बनाएँ

स्थानीय आउटलाइन में लौटे निर्देशांक और मापे समूह का वही ट्रांसफ़ॉर्म दें। उसे समान स्तर पर रखें, ताकि अगले माप का हिस्सा न बने:

const scene = document.querySelector("#scene");
const box = art.getBBox();
const outline = document.createElementNS("http://www.w3.org/2000/svg", "rect");
for (const key of ["x", "y", "width", "height"]) {
  outline.setAttribute(key, box[key]);
}
outline.setAttribute("transform", art.getAttribute("transform"));
outline.setAttribute("fill", "none");
outline.setAttribute("stroke", "olive");
scene.append(outline);

इस नमूने में सीधा ट्रांसफ़ॉर्म कॉपी उचित है, क्योंकि कलाकृति और आउटलाइन का पैरेंट समान है। दूसरी जगह रखे आयत को दोनों निर्देशांक तंत्रों की मैट्रिक्स मैपिंग चाहिए।

HTML आउटलाइन के लिए बिना ट्रांसफ़ॉर्म वाले ऊपरी कंटेनर के सीधे body के नीचे स्थिर स्थिति वाला div रखें:

const box = art.getBoundingClientRect();
Object.assign(overlay.style, {
  position: "fixed",
  boxSizing: "border-box",
  pointerEvents: "none",
  border: "2px dashed coral",
  left: `${box.x}px`,
  top: `${box.y}px`,
  width: `${box.width}px`,
  height: `${box.height}px`,
});

यहाँ overlay आपका मौजूदा आउटलाइन तत्व है। स्क्रोल, आकार, कलाकृति लेआउट या ट्रांसफ़ॉर्म बदलने पर फिर मापें। दस्तावेज़ स्थिति दें तो स्क्रोल खिसकाव जोड़ें; स्थिति वाले कंटेनर में उसका निर्देशांक तंत्र ध्यान में रखें। नियम मिलाना सही आयत खिसका दिखने का सामान्य कारण है।

हमारे उपकरण ने दोनों आउटलाइन दिखाईं। स्थानीय आयत छल्ले और त्रिकोण के साथ झुका, जबकि टूटा HTML आयत क्षैतिज और लंबवत रहा। मोटा स्ट्रोक ज्यामिति आउटलाइन के कुछ हिस्सों से बाहर गया।

समर्थन मानने के बजाय स्ट्रोक विकल्प परखें

डिफ़ॉल्ट स्थानीय बॉक्स स्ट्रोक चौड़ाई छोड़ता है। MDN getBBox({ stroke: true }) बताता है, लेकिन विकल्प पैरामीटर की अनुकूलता लंबे समय से मौजूद बिना तर्क वाली विधि से अलग है।

हमारे Chrome नमूने में { stroke: true } देने से बिना तर्क के समान 140 × 60 बॉक्स मिला। 10 इकाई स्ट्रोक हटाने पर क्लाइंट आयत भी वही रहा। दिखाई गहरी सीमा स्पष्ट बदली, इसलिए उस परीक्षण में कोई परिणाम पूरा रंगा क्षेत्र नहीं था।

बिना त्रुटि विकल्प ऑब्जेक्ट स्वीकार करना यह प्रमाण नहीं कि विकल्प माना गया। ज्ञात स्ट्रोक आकृति परखें और लक्ष्य ब्राउज़र में लौटे आयाम देखें। ऑब्जेक्ट, स्ट्रोक और सजावटी सीमा अलग करने के लिए SVG बॉक्स सीमा परिभाषाएँ इस्तेमाल करें।

हर आकृति पर आधी स्ट्रोक चौड़ाई जितनी खाली जगह जोड़ने का नियम न लगाएँ। माइटर जोड़, मार्कर, स्केल बदलने पर चौड़ाई न बदलने वाले स्ट्रोक, छाया और फ़िल्टर अलग फैल सकते हैं। नियंत्रित सरल गोल जोड़ नमूने में किनारों पर तय खाली जगह और दृश्य जाँच पर्याप्त हो सकती है। स्वचालित एक्सपोर्ट क्रॉपर में वे मामले जानबूझकर सँभालने चाहिए।

रूट viewBox फ़िट करने से पहले स्थानीय बॉक्स बदलें

क्लाइंट आयत के x, y, width और height सीधे SVG viewBox में कभी न दें। उनमें पेज स्थिति है और इकाई तंत्र अलग है।

नमूने में स्थानीय बॉक्स के चार कोने रूट SVG उपयोगकर्ता निर्देशांकों में लाएँ। MDN का getScreenCTM() संदर्भ SVG निर्देशांक दस्तावेज़ व्यूपोर्ट की ओर लाने वाला मैट्रिक्स बताता है। कलाकृति मैट्रिक्स और रूट मैट्रिक्स का प्रतिलोम मिलाने से साझा स्क्रीन मैपिंग हटती है:

const box = art.getBBox();
const rootMatrix = scene.getScreenCTM();
const artMatrix = art.getScreenCTM();
if (!rootMatrix || !artMatrix) throw new Error("SVG is not measurable");
 
const toRoot = rootMatrix.inverse().multiply(artMatrix);
const corners = [
  [box.x, box.y],
  [box.x + box.width, box.y],
  [box.x + box.width, box.y + box.height],
  [box.x, box.y + box.height],
].map(([x, y]) => new DOMPoint(x, y).matrixTransform(toRoot));
 
const xs = corners.map(p => p.x);
const ys = corners.map(p => p.y);
const x = Math.min(...xs);
const y = Math.min(...ys);
const width = Math.max(...xs) - x;
const height = Math.max(...ys) - y;
const padding = 12; // Chosen for this simple fixture, in root user units.
scene.setAttribute("viewBox", [
  x - padding, y - padding,
  width + 2 * padding, height + 2 * padding,
].join(" "));

यह उलट सकने वाले द्विआयामी ट्रांसफ़ॉर्म वाला रेंडर SVG मानता है। स्थानीय आयत कोने मैप करने से सुरक्षित अक्ष-संरेखित बाहरी सीमा मिलती है, आवश्यक नहीं कि हर ट्रांसफ़ॉर्म वक्र के आसपास सबसे कसा बॉक्स।

उपकरण ने किनारों पर उस खाली जगह के साथ लगभग 57.571 23 206.688 160.254 viewBox दिया। परिणाम देखा और नमूने का गोल स्ट्रोक प्रदर्शन क्षेत्र में रहा। चौड़े प्रदर्शन में किनारे की जगह अब भी थी, क्योंकि फ़िट viewBox का अनुपात अलग था; फ़िट का मतलब खिंचाव नहीं।

क्रॉप के बजाय घुमाव केंद्र चाहिए तो transform-origin मार्गदर्शिका संदर्भ बॉक्स का घुमाव पर असर समझाती है। भौतिक इंपोर्ट आयामों के लिए SVG आकार समस्या प्रक्रिया दें।

संपादित करने वाली ज्यामिति मापें

स्रोत केवल PNG या JPG हो और संपादन योग्य आकृतियाँ चाहिए तो PerfectVector माप से पहले SVG वापस ला सकता है। पाथ, खुली जगह, स्ट्रोक और बची रास्टर सामग्री देखें। बॉक्स सीमा ज्यामिति का फैलाव बताती है; यह ट्रेस की सटीकता या हर दृश्य विवरण का संपादन योग्य होना नहीं सिद्ध करती।

मौजूदा SVG सीधे मापा जा सकता है। SVG संपादन मार्गदर्शिका वास्तविक सामग्री पहचानने में मदद करती है, जबकि इमेज वेक्टराइज़ेशन परिचय उससे पहले का रूपांतरण चरण समझाता है।

केवल रास्टर कलाकृति हो तो PerfectVector में स्रोत आज़माएँ, प्राप्त सीमाएँ देखें, फिर रखने या एक्सपोर्ट करने वाला समूह मापें। परिणाम को वितरण क्रॉप मानने से पहले किनारों पर खाली जगह रखें और अंतिम दृश्य सीमा देखें।

अक्सर पूछे जाने वाले सवाल

दोनों विधियों से अलग चौड़ाई क्यों मिलती है? वे अलग निर्देशांक तंत्र इस्तेमाल करती हैं। स्थानीय SVG बॉक्स उपयोगकर्ता इकाइयों में ज्यामिति बताता है, जबकि क्लाइंट आयत पेज मैपिंग के बाद CSS पिक्सेल में व्यूपोर्ट-सापेक्ष सीमा बताता है। आकार और घुमाव आयाम बदल सकते हैं।

क्या बॉक्स सीमा बताती है कि कलाकृति में छेद है? नहीं। आयत बाहरी विस्तार दर्ज करता है, भीतर की संरचना नहीं। समान बाहरी किनारे वाले ठोस आयत और छल्ले का बॉक्स समान हो सकता है। खुली जगह के लिए पाथ और भराव नियम देखें।

क्या क्लाइंट आयत को viewBox दे सकता हूँ? सीधे नहीं। पहले संबंधित ज्यामिति रूट SVG उपयोगकर्ता निर्देशांकों में बदलें। स्क्रीन स्थिति और CSS पिक्सेल आयाम स्रोत निर्देशांक आयत में कॉपी नहीं करने चाहिए।

स्रोत

  1. MDN getBBox — स्थानीय SVG सीमा और वैकल्पिक माप नियंत्रण परिभाषित करता है।
  2. MDN getBoundingClientRect — व्यूपोर्ट-सापेक्ष आयत और स्क्रोलिंग समझाता है।
  3. SVG बॉक्स सीमा परिभाषाएँ — ऑब्जेक्ट, स्ट्रोक और सजावटी ज्यामिति सीमा अलग करती हैं।
  4. MDN getScreenCTM — SVG और व्यूपोर्ट निर्देशांक जोड़ने वाला मैट्रिक्स बताता है।

Blog से और

ऐसे साफ़ SVG से शुरुआत करें
जिसे एडिट करना आसान हो