এটা সবসময় আপনি ছিল, Canvas2D

অ্যারন ক্রাজেস্কি
অ্যারন ক্রাজেস্কি

শেডার, মেশ এবং ফিল্টারের বিশ্বে, Canvas2D আপনাকে উত্তেজিত নাও করতে পারে। কিন্তু এটা উচিত! 30-40% ওয়েব পৃষ্ঠাগুলিতে একটি <canvas> উপাদান রয়েছে এবং সমস্ত ক্যানভাসের 98% একটি Canvas2D রেন্ডারিং প্রসঙ্গ ব্যবহার করে। গাড়িতে, ফ্রিজে এবং মহাকাশে (সত্যিই) Canvas2D আছে।

স্বীকার্য যে, অত্যাধুনিক 2D অঙ্কনের ক্ষেত্রে এপিআই সময়ের চেয়ে কিছুটা পিছিয়ে। সৌভাগ্যবশত আমরা ক্যানভাস2ডি-তে নতুন বৈশিষ্ট্যগুলি বাস্তবায়নের জন্য কঠোর পরিশ্রম করেছি যাতে CSS-এ ধরা পড়ে, এরগনোমিক্সকে স্ট্রীমলাইন করা এবং কর্মক্ষমতা উন্নত করা যায়।

পার্ট 1: CSS এর সাথে ধরা

CSS-এর কয়েকটি ড্রয়িং কমান্ড রয়েছে যা Canvas2D থেকে খুব বেশি অনুপস্থিত। নতুন API-এর সাথে আমরা সবচেয়ে বেশি অনুরোধ করা কয়েকটি বৈশিষ্ট্য যুক্ত করেছি:

গোলাকার রেক্ট

বৃত্তাকার আয়তক্ষেত্র: ইন্টারনেটের ভিত্তিপ্রস্তর, কম্পিউটিং, কাছাকাছি, সভ্যতার।

সমস্ত গুরুত্বের মধ্যে, বৃত্তাকার আয়তক্ষেত্রগুলি অত্যন্ত দরকারী: বোতাম হিসাবে, চ্যাট বুদবুদ, থাম্বনেইল, স্পিচ বুদবুদ, আপনি এটির নাম দিন। ক্যানভাস 2 ডি-তে একটি বৃত্তাকার আয়তক্ষেত্র তৈরি করা সর্বদা সম্ভব হয়েছে, এটি কিছুটা অগোছালো হয়েছে:

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();

এই সব একটি বিনয়ী, সরল বৃত্তাকার আয়তক্ষেত্রের জন্য প্রয়োজনীয় ছিল:

একটি বৃত্তাকার আয়তক্ষেত্র।

নতুন API এর সাথে একটি 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);

একটি কনিক গ্রেডিয়েন্ট।

টেক্সট মডিফায়ার

Canvas2D-এর টেক্সট রেন্ডারিং ক্ষমতা খুবই পিছিয়ে আছে। ক্রোম Canvas2D টেক্সট রেন্ডারিং-এ বেশ কিছু নতুন বৈশিষ্ট্য যুক্ত করেছে:

এই বৈশিষ্ট্যগুলি একই নামের সাথে তাদের CSS প্রতিরূপের সাথে মেলে।

পার্ট 2: ergonomic tweaks

পূর্বে, Canvas2D এর সাথে কিছু জিনিস সম্ভব ছিল, কিন্তু বাস্তবায়ন করা অপ্রয়োজনীয়ভাবে জটিল। এখানে JavaScript ডেভেলপারদের জন্য জীবন মানের কিছু উন্নতি রয়েছে যারা Canvas2D ব্যবহার করতে চান:

প্রসঙ্গ রিসেট

একটি ক্যানভাস পরিষ্কার করার ব্যাখ্যা করার জন্য, আমি একটি বিপরীতমুখী প্যাটার্ন আঁকার জন্য একটি নির্বোধ সামান্য ফাংশন লিখেছি:

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();

একটি অনুভূমিক এবং একটি তির্যক রেখা।

গ্রররর! এটা ঠিক না! 😡 অতিরিক্ত লাইন এখানে কি করছে? এছাড়াও, কেন এটা গোলাপী? ঠিক আছে, আসুন স্ট্যাকওভারফ্লো পরীক্ষা করি।

canvas.width = canvas.width;

কেন এই এত নির্বোধ? এটা এত কঠিন কেন?

ওয়েল, এটা আর না. নতুন API-এর সাথে আমাদের রয়েছে সহজ, মার্জিত, সুন্দর গ্রাউন্ডব্রেকিং:

ctx.reset();

দুঃখিত যে এত সময় লেগেছিল।

ফিল্টার

SVG ফিল্টারগুলি নিজেদের কাছে একটি বিশ্ব। যদি তারা আপনার কাছে নতুন হয়ে থাকে তবে আমি অত্যন্ত সুপারিশ করছি The Art of SVG ফিল্টার এবং কেন এটি দুর্দান্ত পড়ার জন্য, যা তাদের কিছু আশ্চর্যজনক সম্ভাবনা দেখায়।

SVG শৈলী ফিল্টার ইতিমধ্যেই Canvas2D এর জন্য উপলব্ধ! আপনাকে শুধু পৃষ্ঠায় অন্য SVG ফিল্টার উপাদানের দিকে নির্দেশ করে একটি url হিসাবে ফিল্টারটি পাস করতে ইচ্ছুক হতে হবে:

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

যা আমাদের প্যাটার্নটি বেশ ভাল করে:

একটি ঝাপসা প্রভাব প্রয়োগ করা বিপরীতমুখী প্যাটার্ন।

কিন্তু, আপনি যদি উপরের কাজটি করতে চান তবে জাভাস্ক্রিপ্টের মধ্যে থাকতে চান এবং স্ট্রিংগুলি নিয়ে গোলমাল না করেন? নতুন API এর সাথে, এটি সম্পূর্ণরূপে সম্ভব।

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 },
]);

পাই হিসাবে সহজ! এটি চেষ্টা করুন এবং এখানে ডেমোতে পরামিতিগুলির সাথে খেলুন।

পার্ট 3: কর্মক্ষমতা উন্নতি

নতুন Canvas2D API এর সাথে, আমরা যেখানে সম্ভব পারফরম্যান্স উন্নত করতে চেয়েছিলাম। আমরা ডেভেলপারদের তাদের ওয়েবসাইটের সূক্ষ্ম নিয়ন্ত্রণ দিতে এবং সবচেয়ে চটকদার সম্ভাব্য ফ্রেমরেটের অনুমতি দিতে কয়েকটি বৈশিষ্ট্য যুক্ত করেছি:

ঘন ঘন পড়বে

একটি ক্যানভাস থেকে পিক্সেল ডেটা পড়তে getImageData() ব্যবহার করুন। এটা খুব ধীর হতে পারে. নতুন API আপনাকে পিছনে পড়ার জন্য একটি ক্যানভাসকে স্পষ্টভাবে চিহ্নিত করার একটি উপায় দেয় (উদাহরণস্বরূপ জেনারেটিভ ইফেক্টের জন্য)। এটি আপনাকে হুডের নীচে জিনিসগুলিকে অপ্টিমাইজ করতে এবং বৃহত্তর ধরণের ব্যবহারের ক্ষেত্রে ক্যানভাসকে দ্রুত রাখতে দেয়৷ এই বৈশিষ্ট্যটি ফায়ারফক্সে কিছু সময়ের জন্য রয়েছে এবং আমরা অবশেষে এটিকে ক্যানভাস স্পেকের অংশ করে তুলছি।

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

প্রসঙ্গ ক্ষতি

আসুন দুঃখিত ট্যাবগুলিকে আবার খুশি করি! যদি কোনও ক্লায়েন্টের GPU মেমরি শেষ হয়ে যায় বা আপনার ক্যানভাসে অন্য কোনও বিপর্যয় ঘটে, আপনি এখন একটি কলব্যাক পেতে পারেন এবং প্রয়োজন অনুসারে পুনরায় আঁকতে পারেন:

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

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

আপনি যদি ক্যানভাসের প্রসঙ্গ এবং ক্ষতি সম্পর্কে আরও পড়তে চান তবে WHATWG-এর উইকিতে একটি ভাল ব্যাখ্যা রয়েছে।

উপসংহার

আপনি Canvas2D-তে নতুন হোন না কেন, আপনি এটি বছরের পর বছর ধরে ব্যবহার করছেন, বা আপনি এটিকে বছরের পর বছর ধরে ব্যবহার করা এড়িয়ে যাচ্ছেন, আমি এখানে আপনাকে ক্যানভাসকে আরেকটি চেহারা দিতে বলতে এসেছি। এটা API-পরের-দরজা যে সব বরাবর সেখানে হয়েছে.

স্বীকৃতি

আনস্প্ল্যাশে স্যান্ডি ক্লার্কের হিরো ছবি।