Canvas2D हमेशा से आप ही रहे हैं

आरोन क्रेजेस्की
आरोन क्रेजेस्की

शेड, मेश, और फ़िल्टर की दुनिया में, हो सकता है कि Canvas2D आपकी उम्मीदों को पूरा न करे. लेकिन ऐसा करना चाहिए! 30–40% वेब पेजों में <canvas> एलिमेंट होता है और सभी कैनवस में से 98% वेब पेजों में Canvas2D रेंडरिंग कॉन्टेक्स्ट का इस्तेमाल किया जाता है. कार में, फ़्रिज में, और अंतरिक्ष में Canvas2D मौजूद हैं.

माना जाता है कि सबसे आधुनिक 2D ड्रॉइंग की बात करने के मामले में, एपीआई बहुत कम समय लगता है. अच्छी बात यह है कि हम Canvas2D में नई सुविधाएं लागू करने के लिए कड़ी मेहनत कर रहे हैं, ताकि सीएसएस का इस्तेमाल किया जा सके. साथ ही, अर्गोनॉमिक्स को आसान बनाया जा सके और परफ़ॉर्मेंस बेहतर की जा सके.

पहला भाग: सीएसएस का इस्तेमाल करना

सीएसएस में कुछ ड्रॉइंग निर्देश हैं, जो Canvas2D में शायद मौजूद नहीं हैं. एपीआई के नए वर्शन में, हमने कुछ सुविधाओं को जोड़ा है, जिनका अनुरोध सबसे ज़्यादा किया गया था:

गोल रेक्टैंगल

गोल आयत: इंटरनेट का आधार, कंप्यूटिंग, दूरी, और सभ्यता की बुनियाद.

सही शब्दों में, गोल आकार वाले आयत बहुत काम के होते हैं: जैसे, बटन, चैट बबल, थंबनेल, स्पीच बबल, इनका नाम रखें. Canvas2D में एक गोल रेक्टैंगल बनाना हमेशा से मुमकिन है, यह थोड़ा मुश्किल है:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'magenta';

const top = 10;
const left = 10;
const width = 200;
const height = 100;
const radius = 20;

ctx.beginPath();
ctx.moveTo(left + radius, top);
ctx.lineTo(left + width - radius, top);
ctx.arcTo(left + width, top, left + width, top + radius, radius);
ctx.lineTo(left + width, top + height - radius);
ctx.arcTo(left + width, top + height, left + width - radius, top + height, radius);
ctx.lineTo(left + radius, top + height);
ctx.arcTo(left, top + height, left, top + height - radius, radius);
ctx.lineTo(left, top + radius);
ctx.arcTo(left, top, left + radius, top, radius);
ctx.stroke();

यह सब एक मामूली, सरल गोल आयत के लिए ज़रूरी था:

एक गोल आयत.

एपीआई के नए वर्शन में roundRect() तरीका उपलब्ध है.

ctx.roundRect(upper, left, width, height, borderRadius);

इसलिए ऊपर दिए गए को पूरी तरह से इससे बदला जा सकता है:

ctx.roundRect(10, 10, 200, 100, 20);

ctx.roundRect() वाला तरीका, ज़्यादा से ज़्यादा चार संख्याओं वाले borderRadius आर्ग्युमेंट के लिए, एक कलेक्शन भी लेता है. ये दायरे, गोल आयत के चारों कोनों को ठीक उसी तरह कंट्रोल करते हैं जैसा कि CSS के लिए किया जाता है. उदाहरण के लिए:

ctx.roundRect(10, 10, 200, 100, [15, 50, 30]);

इस्तेमाल करने के लिए डेमो देखें!

शंकु ग्रेडिएंट

आपने लीनियर ग्रेडिएंट देखे हैं:

const gradient = ctx.createLinearGradient(0, 0, 200, 100);
gradient.addColorStop(0, 'blue');
gradient.addColorStop(0.5, 'magenta');
gradient.addColorStop(1, 'white');
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 200, 100);

लीनियर ग्रेडिएंट.

रेडियल ग्रेडिएंट:

const radialGradient = ctx.createRadialGradient(150, 75, 10, 150, 75, 70);
radialGradient.addColorStop(0, 'white');
radialGradient.addColorStop(0.5, 'magenta');
radialGradient.addColorStop(1, 'lightblue');

ctx.fillStyle = radialGradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);

एक रेडियल ग्रेडिएंट.

लेकिन एक अच्छा शंकु ग्रेडिएंट कैसा रहेगा?

const grad = ctx.createConicGradient(0, 100, 100);

grad.addColorStop(0, 'red');
grad.addColorStop(0.25, 'orange');
grad.addColorStop(0.5, 'yellow');
grad.addColorStop(0.75, 'green');
grad.addColorStop(1, 'blue');

ctx.fillStyle = grad;
ctx.fillRect(0, 0, 200, 200);

शंकु ग्रेडिएंट.

टेक्स्ट मॉडिफ़ायर

Canvas2Ds की टेक्स्ट रेंडरिंग की क्षमताएं बहुत खराब थीं. Chrome ने Canvas2D टेक्स्ट रेंडरिंग में कई नए एट्रिब्यूट जोड़े हैं:

ये एट्रिब्यूट, उनके सीएसएस प्रोग्राम के एक जैसे नाम से मैच करते हैं.

दूसरा भाग: काम से जुड़े बदलाव

पहले Canvas2D की मदद से कुछ चीज़ें मुमकिन थीं, लेकिन उन्हें लागू करना बेहद मुश्किल था. Canvas2D को इस्तेमाल करने वाले JavaScript डेवलपर के लिए, इसे बेहतर बनाने के कुछ तरीके यहां बताए गए हैं:

संदर्भ रीसेट किया गया

कैनवस को मिटाने के बारे में समझाने के लिए, मैंने एक छोटा-सा अजीबोगरीब पुराना पैटर्न बनाने का फ़ंक्शन लिखा है:

draw90sPattern();

त्रिभुजों और स्क्वेयर का रेट्रो पैटर्न.

बढ़िया! पैटर्न बनाने के बाद, अब मुझे कैनवस साफ़ करके कुछ और बनाना है. रुको, हम कैनवस को फिर से कैसे साफ़ करते हैं? ओह! ctx.clearRect(), बिलकुल.

ctx.clearRect(0, 0, canvas.width, canvas.height);

ओह... यह काम नहीं किया. ओह! मुझे पहले ट्रांसफ़ॉर्म को रीसेट करना होगा:

ctx.resetTransform();
ctx.clearRect(0, 0, canvas.width, canvas.height);
कैनवस खाली है.

बढ़िया! खाली कैनवस. आइए, अब एक अच्छी हॉरिज़ॉन्टल लाइन बनाना शुरू करें:

ctx.moveTo(10, 10);
ctx.lineTo(canvas.width, 10);
ctx.stroke();

एक हॉरिज़ॉन्टल और विकर्ण लाइन.

धत्त! गलत जवाब! 💀 यहां वह अतिरिक्त लाइन क्या कर रही है? साथ ही, यह गुलाबी क्यों है? ठीक है, आइए StackOverflow को देखते हैं.

canvas.width = canvas.width;

यह इतना अजीब क्यों है? यह इतना मुश्किल क्यों है?

अब और नहीं है. नए एपीआई के साथ हमें आसान, सहज, और शानदार अनुभव मिलता है:

ctx.reset();

माफ़ करें, इसमें इतना समय लगा.

फ़िल्टर

SVG फ़िल्टर का इस्तेमाल करना अपने-आप में पूरा होता है. अगर आपने हाल ही में ये फ़िल्टर इस्तेमाल किए हैं, तो हमारा सुझाव है कि आप The Art of SVG Filter and How it Is Awesome को पढ़ें.

Canvas2D के लिए SVG स्टाइल के फ़िल्टर पहले से उपलब्ध हैं! आपको बस फ़िल्टर को, पेज पर मौजूद किसी दूसरे SVG फ़िल्टर एलिमेंट को पॉइंट करने वाले यूआरएल के तौर पर पास करना होगा:

<svg>
  <defs>
    <filter id="svgFilter">
      <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
      <feConvolveMatrix kernelMatrix="-3 0 0 0 0.5 0 0 0 3" />
      <feColorMatrix type="hueRotate" values="90" />
    </filter>
  </defs>
</svg>
const canvas = document.createElement('canvas');
canvas.width = 500;
canvas.height = 400;
const ctx = canvas.getContext('2d');
document.body.appendChild(canvas);

ctx.filter = "url('#svgFilter')";
draw90sPattern(ctx);

इससे हमारा पैटर्न काफ़ी खराब हो गया है:

पुराने ज़माने का पैटर्न, जिसमें धुंधला इफ़ेक्ट लागू किया गया है.

लेकिन, अगर आप ऊपर दिया गया तरीका अपनाना चाहते हैं, लेकिन JavaScript के अंदर ही रहना चाहते हैं और स्ट्रिंग की गड़बड़ी नहीं करना चाहते, तो क्या होगा? एपीआई के नए वर्शन का इस्तेमाल करके, ऐसा किया जा सकता है.

ctx.filter = new CanvasFilter([
  { filter: 'gaussianBlur', stdDeviation: 5 },
  {
    filter: 'convolveMatrix',
    kernelMatrix: [
      [-3, 0, 0],
      [0, 0.5, 0],
      [0, 0, 3],
    ],
  },
  { filter: 'colorMatrix', type: 'hueRotate', values: 90 },
]);

पाई की तरह आसान! इसे आज़माएं और यहां डेमो में पैरामीटर के साथ खेलें.

तीसरा भाग: परफ़ॉर्मेंस में सुधार करना

नए Canvas2D API की मदद से, हम जहां तक हो सके परफ़ॉर्मेंस को भी बेहतर बनाना चाहते थे. हमने इसमें कुछ सुविधाएं जोड़ी हैं, जिनकी मदद से डेवलपर अपनी वेबसाइटों पर बेहतर कंट्रोल पा सकते हैं. साथ ही, सबसे आसान फ़्रेमरेट की सुविधा भी पा सकते हैं:

अक्सर पढ़ा जाएगा

Pixel के डेटा को कैनवस पर देखने के लिए, getImageData() का इस्तेमाल करें. यह बहुत धीमा हो सकता है. नए एपीआई से, आपको कैनवस को वापस पढ़ने के लिए, साफ़ तौर पर मार्क करने का तरीका मिलता है (उदाहरण के लिए, जनरेटिव इफ़ेक्ट के लिए). इससे आपको हुड के तहत आने वाली चीज़ों को ऑप्टिमाइज़ करने और कैनवस को इस्तेमाल के अलग-अलग उदाहरणों के लिए तेज़ी से बनाए रखने में मदद मिलती है. यह सुविधा कुछ समय से Firefox में है और हम इसे कैनवस विशेष का हिस्सा बना रहे हैं.

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true });

संदर्भ का नुकसान

आइए, उदासी वाले टैब को फिर से खुश कर दें! अगर किसी क्लाइंट की जीपीयू मेमोरी खत्म हो जाती है या आपके कैनवस पर कोई दूसरी समस्या आ जाती है, तो अब आपको कॉलबैक मिल सकता है और ज़रूरत के हिसाब से फिर से बनाया जा सकता है:

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

canvas.addEventListener('contextlost', onContextLost);
canvas.addEventListener('contextrestored', redraw);

अगर आप कैनवस के संदर्भ और नुकसान के बारे में और पढ़ना चाहते हैं, तो WHATWG के उनके विकी पर अच्छा विवरण दिया गया है.

नतीजा

चाहे Canvas2D आपके लिए नया हो, आप कई सालों से इसका इस्तेमाल कर रहे हों या सालों से इसका इस्तेमाल न कर रहे हों, मैं अब आपको कैनवस को एक नया लुक देने के लिए कह रही हूं. यह एपीआई ने ही काम किया है.

स्वीकार हैं

अनस्प्लैश पर सैंडी क्लार्क की हीरो इमेज.