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

Canvas Path2D SVG: सही आकार पर पाथ दोबारा इस्तेमाल करें

सही viewBox ट्रांसफ़ॉर्म, रंग, खाली हिस्सों और पिक्सेल घनत्व के साथ कैनवस पर SVG पाथ डेटा दोबारा इस्तेमाल करें। मौलिक उदाहरण अपनाएँ और संपादन योग्य SVG मूल फ़ाइल रखें।

इस पेज पर

पाथ का d एट्रिब्यूट new Path2D(d) को दें, फिर कैनवस कॉन्टेक्स्ट से उसे बनाएँ। SVG से मेल के लिए उसकी निर्देशांक मैपिंग, रंग और भरण नियम भी साथ लाएँ। कन्स्ट्रक्टर पाथ डेटा स्वीकार करता है; यह SVG दस्तावेज़ आयात नहीं करता और न दस्तावेज़ का viewBox, CSS या समूह ट्रांसफ़ॉर्म लागू करता है (MDN Path2D कन्स्ट्रक्टर)।

यह तब ज़रूरी है जब कस्टम आइकन SVG में सही दिखता है, लेकिन कैनवस पर छोटा, खिसका हुआ, काला या अपने खुले हिस्से में भरा हुआ हो जाता है। नीचे का उदाहरण दो पाथ और स्पष्ट फ़िट ट्रांसफ़ॉर्म से ये अंतर ठीक करता है। जब मौजूदा वेक्टर ज्यामिति हो, तो उसी से शुरू करें। वेक्टराइज़ेशन केवल तब उपयोगी है जब दोबारा इस्तेमाल करने वाला चित्र अभी भी पिक्सेल के रूप में हो।

Path2D ऑब्जेक्ट क्या रखता है

पाथ डेटा को कंटूर का विवरण समझें। दूसरे SVG निर्देश उस स्ट्रिंग के बाहर होते हैं और आपकी कैनवस ड्रॉइंग कोड को आवश्यक निर्देश देने होंगे।

SVG इनपुटकैनवस की ज़िम्मेदारी
पाथ का d मानPath2D ज्यामिति बनाएँ
viewBox और दिखाया गया आकारड्रॉइंग ट्रांसफ़ॉर्म की गणना करें
fill और fill-rulefillStyle तय करें और नियम fill() को दें
पैरेंट या पाथ का transformसमान ट्रांसफ़ॉर्म अलग से लागू करें
CSS, ग्रेडिएंट, मास्क, टेक्स्ट और छवियाँआवश्यक रेंडरिंग लागू करें या दूसरा रास्ता चुनें

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

स्रोत की तुलना बिना सेटिंग वाले कैनवस से करें

इस मौलिक प्रतीक में गोल किनारों वाला नीला-हरा मुख्य आकार, नारंगी नोक और चौकोर खुला हिस्सा है। इसका viewBox (0, 0) के बजाय (20, 10) से शुरू होता है। अंदरूनी सबपाथ बाहरी सीमा वाली दिशा में ही चलता है, इसलिए घोषित evenodd नियम ज़रूरी है।

यह SVG और कैनवस किसी HTML पेज में रखें:

<svg id="source" xmlns="http://www.w3.org/2000/svg"
     viewBox="20 10 120 80" width="240" height="160">
  <path fill="#126d70" fill-rule="evenodd"
        d="M40 20 H90 Q110 20 110 40 V60 Q110 80 90 80 H40 Q30 80 30 70 V30 Q30 20 40 20 Z M50 35 H80 V60 H50 Z"/>
  <path fill="#f19b38" d="M115 25 L135 50 L115 75 Z"/>
</svg>
<canvas id="result"></canvas>

यदि आप दोनों d मानों पर लूप चलाकर बिना कुछ और सेट किए ctx.fill(new Path2D(d)) बुलाएँ, तो ज्यामिति कैनवस निर्देशांक तथा डिफ़ॉल्ट रंग और भरण नियम इस्तेमाल करती है। उसे SVG का रूप अपने आप नहीं मिलता। कैनवस का fill() पाथ और स्पष्ट evenodd या nonzero नियम दोनों स्वीकार करता है; nonzero डिफ़ॉल्ट है (MDN fill())।

ब्राउज़र में SVG प्रतीक, छोटे काले कच्चे Path2D रेंडर जिसका खुला हिस्सा भरा है, और सही फ़िट वाले दो रंग के कैनवस रेंडर की तुलना
ब्राउज़र में वही हाथ से लिखे पाथ: SVG संदर्भ, कच्चा Path2D और रंग तथा evenodd बहाल करने वाला स्पष्ट फ़िट। तालिका चार आकार और DPR इनपुट के लिए बिटमैप आयाम दर्ज करती है।

विधि: हमने हाथ से लिखा यह SVG ब्राउज़र में रेंडर किया, दोनों कैनवस रास्तों से उसके दो पाथ बनाए और प्रकाशित कोड अलग HTML पेज में दोबारा चलाया। स्क्रीनशॉट वास्तविक ब्राउज़र आउटपुट है। यह निर्देशांक और रंग संभालना दिखाता है, PerfectVector रूपांतरण नहीं।

viewBox को कैनवस में मैप करें

SVG का डिफ़ॉल्ट अनुपात सुरक्षित रखने वाला व्यवहार viewBox को उसके व्यूपोर्ट के अंदर फ़िट और केंद्रित करता है। SVG निर्देशांक प्रणाली विनिर्देश यह मैपिंग परिभाषित करता है। इस सपाट उदाहरण के लिए एक समान पैमाने और स्थानांतरण से xMidYMid meet दोहराएँ:

scale = min(cssWidth / viewBoxWidth, cssHeight / viewBoxHeight)
tx = (cssWidth - viewBoxWidth * scale) / 2 - viewBoxX * scale
ty = (cssHeight - viewBoxHeight * scale) / 2 - viewBoxY * scale

अंतिम पद शून्य से अलग मूल बिंदु हटाते हैं। 240 × 160 पर पैमाना 2, tx का मान -40 और ty का मान -20 है। 300 × 120 पर पैमाना 1.5 होता है; 180 पिक्सेल चौड़े फ़िट किए गए viewBox के दोनों तरफ़ 60 पिक्सेल क्षैतिज जगह मिलती है। इसलिए स्रोत के मूल बिंदु को ध्यान में रखने के बाद स्थानांतरण (30, -15) है।

ऊपर के HTML के बाद यह स्क्रिप्ट इस्तेमाल करें। यह इस नमूने के सीधे पाथ एट्रिब्यूट संभालती है, पूरा कैनवस दोबारा बनाती है और CSS आकार को पीछे के बिटमैप आकार से अलग रखती है:

const source = document.querySelector("#source");
const vb = source.viewBox.baseVal;
const layers = [...source.querySelectorAll("path")].map(el => ({
  path: new Path2D(el.getAttribute("d")),
  fill: el.getAttribute("fill"),
  rule: el.getAttribute("fill-rule") || "nonzero"
}));
 
function draw(canvas, cssWidth, cssHeight, dpr = window.devicePixelRatio || 1) {
  canvas.style.width = `${cssWidth}px`;
  canvas.style.height = `${cssHeight}px`;
  canvas.width = Math.round(cssWidth * dpr);
  canvas.height = Math.round(cssHeight * dpr);
  const ctx = canvas.getContext("2d");
  const scale = Math.min(cssWidth / vb.width, cssHeight / vb.height);
  const tx = (cssWidth - vb.width * scale) / 2 - vb.x * scale;
  const ty = (cssHeight - vb.height * scale) / 2 - vb.y * scale;
  const px = canvas.width / cssWidth;
  const py = canvas.height / cssHeight;
  ctx.setTransform(px * scale, 0, 0, py * scale, px * tx, py * ty);
  for (const layer of layers) {
    ctx.fillStyle = layer.fill;
    ctx.fill(layer.path, layer.rule);
  }
}
 
draw(document.querySelector("#result"), 240, 160);
 

canvas.width और canvas.height सेट करने से कॉन्टेक्स्ट साफ़ और रीसेट होता है। फिर फ़ंक्शन पूरा ट्रांसफ़ॉर्म सेट करके हर परत दोबारा रंगता है, इसलिए बार-बार कॉल करने पर पैमाना जमा नहीं होता। यह धनात्मक चौड़ाई और ऊँचाई वाले मान्य viewBox तथा धनात्मक माँगे गए आयाम मानता है।

px और py वास्तव में राउंड किए गए बिटमैप आयाम इस्तेमाल करते हैं। इससे माँगे गए घनत्व से गणना किए गए आयाम पूर्णांक न होने पर भी CSS निर्देशांक आवंटित पिक्सेल से मैप रहते हैं। MDN का devicePixelRatio उदाहरण समझाता है कि कैनवस प्रदर्शन आकार और पिक्सेल आयाम अलग क्यों सँभालने चाहिए।

आकार और पिक्सेल घनत्व अलग-अलग जाँचें

हमने दो CSS आकारों पर उसी फ़ंक्शन में DPR मान 1 और 2 स्पष्ट रूप से दिए। ये नियंत्रित घनत्व इनपुट हैं, दो भौतिक उपकरण जाँचने का दावा नहीं। डिफ़ॉल्ट कॉल के लिए ब्राउज़र का बताया डिवाइस पिक्सेल अनुपात 2 था।

CSS आकारDPR आर्ग्युमेंटदेखा गया कैनवस बिटमैप
240 × 1601240 × 160
240 × 1602480 × 320
300 × 1201300 × 120
300 × 1202600 × 240

चारों स्थितियों में खुले हिस्से का केंद्र पारदर्शी रहा। ऊँचा घनत्व पीछे का रिज़ॉल्यूशन बदलता है; यह गलत ट्रांसफ़ॉर्म ठीक नहीं करता और गायब भरण नियम वापस नहीं लाता। इच्छित CSS आयाम या डिवाइस पिक्सेल अनुपात बदलने पर दोबारा बनाएँ। केवल CSS से बड़ा करने पर कैनवस पर पहले से मौजूद बिटमैप खिंचता है।

यदि स्रोत कैनवस तक पहुँचने से पहले ही गलत है, तो SVG आकार और viewBox जाँच इस्तेमाल करें। यदि केवल कैनवस गलत है, तो पहले उसके ट्रांसफ़ॉर्म और रंग संभालने की तुलना काम करने वाले SVG संदर्भ से करें।

स्रोत सुरक्षित रखें और सही आयात रास्ता चुनें

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

कैनवस आउटपुट PNG में सहेजने पर रास्टर छवि बनती है, भले ड्रॉइंग वेक्टर पाथ से शुरू हुई हो। कैनवस निर्यात API छवि ब्लॉब बनाता है; PNG समर्थन आवश्यक है (MDN toBlob())। आगे पाथ संपादन के लिए SVG रखें। इसी तरह SVG फ़ाइल में उपयोगी पाथ डेटा के बजाय रास्टर छवि हो सकती है; एम्बेडेड छवि का निदान ये स्थितियाँ अलग करने में मदद करता है।

PerfectVector तब उपयुक्त है जब आपके कस्टम आइकन का केवल PNG या JPG बचा हो और दोबारा इस्तेमाल योग्य कंटूर चाहिए हों। उस छवि को SVG में बदलें, फिर कैनवस के लिए पाथ निकालने से पहले उसकी बाहरी आकृति, अलग रंग और छोटे खुले हिस्से देखें। साफ़ SVG मूल फ़ाइल सीधे तैयारी चरण में जानी चाहिए। ट्रेसिंग viewBox मैपिंग लागू नहीं करती, CSS कॉपी नहीं करती और कैनवस PNG को संपादन योग्य वेक्टर नहीं बनाती।

पूरे आइकन परिवार के लिए हर ड्रॉइंग प्रक्रिया जोड़ने से पहले साझा UI-kit ग्रिड और रंग नियम तय करें। SVG तैयारी के और उदाहरण ब्लॉग में हैं।

अपने इंटरफ़ेस में ड्रॉइंग इस्तेमाल करने से पहले

  • SVG संदर्भ को कैनवस के समान प्रदर्शन आयामों पर जाँचें।
  • viewBox की चौड़ाई और ऊँचाई के साथ उसका मूल बिंदु भी सुनिश्चित करें।
  • रंग और इच्छित भरण नियम स्थानांतरित करें; हर खुले हिस्से को जाँचें।
  • केवल d कॉपी करने के बजाय समूह ट्रांसफ़ॉर्म का हिसाब रखें।
  • वास्तविक canvas.width और canvas.height पढ़ें, फिर सबसे बड़ा इच्छित प्रदर्शन आकार जाँचें।
  • SVG मूल फ़ाइल सुरक्षित रखें और इंटरफ़ेस के अनुकूल सुलभ नाम या आसपास टेक्स्ट दें।

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

क्या Path2D पूरी SVG फ़ाइल आयात कर सकता है? नहीं। उसका स्ट्रिंग इनपुट SVG पाथ डेटा होता है, जैसे पाथ के d एट्रिब्यूट का मान। दस्तावेज़ संरचना, viewBox मैपिंग, स्टाइल और समूह ट्रांसफ़ॉर्म अलग सँभालने पड़ते हैं।

मेरे SVG का खाली हिस्सा कैनवस पर भर क्यों गया? भरण नियम और सबपाथ दिशाएँ जाँचें। इस उदाहरण को evenodd चाहिए, जबकि कैनवस भरण का डिफ़ॉल्ट nonzero है। Path2D ऑब्जेक्ट भरते समय इच्छित नियम दें।

क्या कैनवस पर SVG पाथ बनाने से वेक्टर निर्यात बना रहता है? पाथ आपके प्रोग्राम में दोबारा इस्तेमाल योग्य ड्रॉइंग निर्देश रहते हैं, लेकिन कैनवस को PNG में निर्यात करने पर पिक्सेल बनते हैं। संपादन और वेक्टर डिलीवरी के लिए मूल SVG रखें।

स्रोत

  1. MDN — Path2D कन्स्ट्रक्टर — कन्स्ट्रक्टर द्वारा स्वीकार की जाने वाली पाथ डेटा स्ट्रिंग परिभाषित करता है।
  2. W3C — SVG निर्देशांक प्रणालियाँ — viewBox मूल बिंदु, व्यूपोर्ट मैपिंग और अनुपात सुरक्षित रखने वाला संरेखण परिभाषित करता है।
  3. MDN — Canvas fill() — पाथ भरण और evenodd तथा nonzero नियमों का दस्तावेज़ देता है।
  4. MDN — devicePixelRatio — CSS प्रदर्शन आकार और कैनवस बिटमैप रिज़ॉल्यूशन समझाता है।
  5. MDN — Canvas toBlob() — कैनवस से रास्टर छवि निर्यात का दस्तावेज़ देता है।

केवल रास्टर आइकन है? PerfectVector से उसका SVG तैयार करें, कंटूर और खुले हिस्से जाँचें, फिर अपने वास्तविक इंटरफ़ेस आकारों पर कैनवस ड्रॉइंग की तुलना उस SVG से करें।

Blog से और

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