ওয়েব ক্ষমতা কোডল্যাব

১. ভূমিকা ও সেটআপ

ওয়েব সক্ষমতা

আমরা ওয়েব এবং নেটিভের মধ্যেকার সক্ষমতার ব্যবধান কমিয়ে আনতে চাই এবং ডেভেলপারদের জন্য উন্মুক্ত ওয়েবে চমৎকার অভিজ্ঞতা তৈরি করা সহজ করে দিতে চাই। আমরা দৃঢ়ভাবে বিশ্বাস করি যে, একটি দুর্দান্ত ওয়েব অভিজ্ঞতা তৈরির জন্য প্রত্যেক ডেভেলপারের প্রয়োজনীয় সক্ষমতাগুলিতে প্রবেশাধিকার থাকা উচিত এবং আমরা একটি আরও সক্ষম ওয়েব তৈরিতে প্রতিশ্রুতিবদ্ধ।

তবে, ফাইল সিস্টেম অ্যাক্সেস এবং নিষ্ক্রিয় অবস্থা শনাক্তকরণের মতো কিছু সক্ষমতা রয়েছে, যা নেটিভ প্ল্যাটফর্মে থাকলেও ওয়েবে পাওয়া যায় না। এই সক্ষমতাগুলোর অনুপস্থিতির কারণে কিছু নির্দিষ্ট ধরনের অ্যাপ ওয়েবে সরবরাহ করা যায় না, অথবা সেগুলো কম কার্যকর হয়।

আমরা বিদ্যমান ওপেন ওয়েব প্ল্যাটফর্ম স্ট্যান্ডার্ড প্রক্রিয়াগুলো ব্যবহার করে এই নতুন সক্ষমতাগুলো একটি উন্মুক্ত ও স্বচ্ছ উপায়ে ডিজাইন ও ডেভেলপ করব এবং ডিজাইনের পুনরাবৃত্তির সময় ডেভেলপার ও অন্যান্য ব্রাউজার বিক্রেতাদের কাছ থেকে প্রাথমিক মতামত নেব, যাতে একটি আন্তঃকার্যকরী ডিজাইন নিশ্চিত করা যায়।

আপনি যা তৈরি করবেন

এই কোডল্যাবে, আপনি এমন কিছু ওয়েব এপিআই নিয়ে কাজ করবেন যেগুলো একদম নতুন অথবা শুধুমাত্র একটি ফ্ল্যাগের মাধ্যমে ব্যবহার করা যায়। তাই, এই কোডল্যাবটি কোনো নির্দিষ্ট চূড়ান্ত পণ্য তৈরির পরিবর্তে, এপিআইগুলো এবং সেগুলোর মাধ্যমে উন্মোচিত হওয়া ব্যবহারের ক্ষেত্রগুলোর উপরই বেশি মনোযোগ দেয়।

আপনি যা শিখবেন

এই কোডল্যাবটি আপনাকে কয়েকটি অত্যাধুনিক এপিআই-এর মৌলিক কার্যপ্রণালী শেখাবে। উল্লেখ্য যে, এই কার্যপ্রণালীগুলো এখনও চূড়ান্ত নয়, এবং ডেভেলপার ফ্লো সম্পর্কে আপনার মতামতকে আমরা অত্যন্ত গুরুত্ব দিই।

আপনার যা যা লাগবে

এই কোডল্যাবে ব্যবহৃত এপিআইগুলো একেবারে অত্যাধুনিক হওয়ায়, প্রতিটি এপিআই-এর জন্য প্রয়োজনীয়তা ভিন্ন। অনুগ্রহ করে প্রতিটি বিভাগের শুরুতে দেওয়া সামঞ্জস্যতার তথ্য মনোযোগ সহকারে পড়ে নিন।

কোডল্যাবে কীভাবে অগ্রসর হবেন

কোডল্যাবটি ক্রমানুসারে সম্পন্ন করার কোনো বাধ্যবাধকতা নেই। প্রতিটি বিভাগ একটি স্বতন্ত্র API-কে উপস্থাপন করে, তাই আপনার সবচেয়ে পছন্দের অংশটি বেছে নিতে পারেন।

২. ব্যাজিং এপিআই

ব্যাজিং এপিআই-এর লক্ষ্য হলো ব্যাকগ্রাউন্ডে ঘটে চলা বিষয়গুলোর প্রতি ব্যবহারকারীদের মনোযোগ আকর্ষণ করা। এই কোডল্যাবের ডেমোটির সরলতার জন্য, চলুন এপিআই ব্যবহার করে ফোরগ্রাউন্ডে ঘটে চলা কোনো কিছুর প্রতি ব্যবহারকারীদের মনোযোগ আকর্ষণ করি। এরপর আপনি ব্যাকগ্রাউন্ডে ঘটে চলা বিষয়গুলোর দিকে মনোযোগটি মানসিকভাবে স্থানান্তর করতে পারবেন।

এয়ারহর্নার ইনস্টল করুন

এই API-টি কাজ করার জন্য, আপনার হোম স্ক্রিনে একটি PWA ইনস্টল করা প্রয়োজন। তাই প্রথম ধাপ হলো একটি PWA ইনস্টল করা, যেমন কুখ্যাত ও বিশ্ববিখ্যাত airhorner.com । উপরের ডান কোণায় থাকা ইনস্টল বোতামটি চাপুন অথবা ম্যানুয়ালি ইনস্টল করার জন্য থ্রি-ডট মেনুটি ব্যবহার করুন।

8b7fa8b3c94c6bdd.png

এটি একটি নিশ্চিতকরণ বার্তা দেখাবে, ইনস্টল-এ ক্লিক করুন।

98e90422167ac786.png

এখন আপনার অপারেটিং সিস্টেমের ডকে একটি নতুন আইকন রয়েছে। PWA-টি চালু করতে এটিতে ক্লিক করুন। এটির নিজস্ব অ্যাপ উইন্ডো থাকবে এবং এটি স্ট্যান্ডঅ্যালোন মোডে চলবে।

একটি ব্যাজ সেট করা

এখন যেহেতু আপনার একটি PWA ইনস্টল করা আছে, ব্যাজে দেখানোর জন্য আপনার কিছু সাংখ্যিক ডেটা প্রয়োজন (ব্যাজে শুধুমাত্র সংখ্যা থাকতে পারে)। ‘দ্য এয়ার হর্নার’-এ গণনা করার একটি সহজ বিষয় হলো, এটি কতবার হর্ন বাজিয়েছে। আসলে, ইনস্টল করা এয়ারহর্নার অ্যাপটি দিয়ে হর্ন বাজিয়ে দেখুন এবং ব্যাজটি পরীক্ষা করুন। আপনি যতবার হর্ন বাজাবেন , এটি ততবার এক করে গণনা করবে।

b5e39de7a1775054.png

তাহলে, এটা কীভাবে কাজ করে? মূলত, কোডটি হলো এই:

let hornCounter = 0;
const horn = document.querySelector('.horn');
horn.addEventListener('click', () => {
  navigator.setExperimentalAppBadge(++hornCounter);
});

কয়েকবার এয়ারহর্ন বাজান এবং PWA-এর আইকনটি দেখুন: প্রতিবার এয়ারহর্ন বাজার সাথে সাথে এটি আপডেট হবে। ব্যাপারটা এতটাই সহজ।

eed10c3ffe59999.png

একটি ব্যাজ পরিষ্কার করা

কাউন্টারটি ৯৯ পর্যন্ত যায় এবং তারপর আবার শুরু হয়। আপনি এটি ম্যানুয়ালিও রিসেট করতে পারেন। DevTools Console ট্যাবটি খুলুন, নিচের লাইনটি পেস্ট করুন এবং এন্টার চাপুন।

navigator.setExperimentalAppBadge(0);

বিকল্পভাবে, আপনি নিচের কোড স্নিপেটে দেখানো পদ্ধতি অনুযায়ী ব্যাজটি স্পষ্টভাবে মুছে দিয়েও এটি থেকে মুক্তি পেতে পারেন। আপনার PWA-এর আইকনটি এখন আবার শুরুর মতো পরিষ্কার এবং ব্যাজবিহীন দেখাবে।

navigator.clearExperimentalAppBadge();

33eafb314a3a9f30.png

প্রতিক্রিয়া

এই এপিআইটি আপনার কেমন লেগেছে? অনুগ্রহ করে এই সমীক্ষায় সংক্ষেপে উত্তর দিয়ে আমাদের সাহায্য করুন:

এই এপিআইটি কি ব্যবহার করতে সহজবোধ্য ছিল?

হ্যাঁ না

আপনি কি উদাহরণটি চালাতে পেরেছেন?

হ্যাঁ না

আপনার কি আরও কিছু বলার আছে? কোনো বৈশিষ্ট্য কি বাদ পড়েছে? অনুগ্রহ করে এই সমীক্ষায় দ্রুত আপনার মতামত জানান। ধন্যবাদ!

৩. নেটিভ ফাইল সিস্টেম এপিআই

নেটিভ ফাইল সিস্টেম এপিআই ডেভেলপারদের এমন শক্তিশালী ওয়েব অ্যাপ তৈরি করতে সক্ষম করে, যা ব্যবহারকারীর স্থানীয় ডিভাইসের ফাইলগুলোর সাথে ইন্টারঅ্যাক্ট করতে পারে। ব্যবহারকারী কোনো ওয়েব অ্যাপকে অ্যাক্সেস দেওয়ার পর, এই এপিআই ওয়েব অ্যাপগুলোকে ব্যবহারকারীর ডিভাইসের ফাইল ও ফোল্ডারগুলো সরাসরি পড়তে বা সেগুলোতে করা পরিবর্তন সংরক্ষণ করতে দেয়।

একটি ফাইল পড়া হচ্ছে

নেটিভ ফাইল সিস্টেম এপিআই-এর "হ্যালো, ওয়ার্ল্ড" কাজটি হলো একটি লোকাল ফাইল পড়া এবং ফাইলের বিষয়বস্তু পাওয়া। একটি সাধারণ .txt ফাইল তৈরি করুন এবং কিছু টেক্সট লিখুন। এরপর, example.com-এর মতো যেকোনো সুরক্ষিত সাইটে (অর্থাৎ, HTTPS- এর মাধ্যমে পরিবেশিত একটি সাইট) যান এবং ডেভটুলস কনসোলটি খুলুন। নিচের কোড স্নিপেটটি কনসোলে পেস্ট করুন। যেহেতু নেটিভ ফাইল সিস্টেম এপিআই-এর জন্য ব্যবহারকারীর একটি অঙ্গভঙ্গি প্রয়োজন, তাই আমরা ডকুমেন্টটিতে একটি ডাবল-ক্লিক হ্যান্ডলার যুক্ত করি। পরে আমাদের ফাইল হ্যান্ডেলটির প্রয়োজন হবে, তাই আমরা এটিকে একটি গ্লোবাল ভেরিয়েবল বানিয়ে রাখি।

document.ondblclick = async () => {
  window.handle = await window.chooseFileSystemEntries();
  const file = await handle.getFile();
  document.body.textContent = await file.text();
};

c02679081eb4d538.png

এরপর আপনি example.com পেজের যেকোনো জায়গায় ডাবল-ক্লিক করলে একটি ফাইল পিকার প্রদর্শিত হবে।

d98962600d62d149.png

আপনার পূর্বে তৈরি করা .txt ফাইলটি নির্বাচন করুন। এরপর ফাইলটির বিষয়বস্তু example.com- এর মূল body কন্টেন্টকে প্রতিস্থাপন করবে।

eace3d15bd4f8192.png

একটি ফাইল সংরক্ষণ করা

এরপর, আমরা কিছু পরিবর্তন করতে চাই। এজন্য, নিচের কোড স্নিপেটটি পেস্ট করে body সম্পাদনাযোগ্য করে তুলি। এখন, আপনি ব্রাউজারটিকে একটি টেক্সট এডিটরের মতোই টেক্সটটি সম্পাদনা করতে পারবেন।

document.body.contentEditable = true;

ca32797417449343.png

এখন, আমরা এই পরিবর্তনগুলো মূল ফাইলে পুনরায় লিখতে চাই। এজন্য, আমাদের ফাইল হ্যান্ডেলে একটি রাইটার প্রয়োজন, যা আমরা কনসোলে নিচের কোড স্নিপেটটি পেস্ট করে পেতে পারি। এক্ষেত্রেও আমাদের একটি ইউজার জেসচার প্রয়োজন, তাই এবার আমরা মূল ডকুমেন্টে একটি ক্লিকের জন্য অপেক্ষা করব।

document.onclick = async () => {
  const writer = await handle.createWriter();
  await writer.truncate(0);
  await writer.write(0, document.body.textContent);
  await writer.close();
};

d2729a8f76f43073.png

এখন আপনি ডকুমেন্টটিতে ক্লিক করলে (ডাবল-ক্লিক নয়), একটি অনুমতির অনুরোধ আসবে। আপনি অনুমতি দিলে, ফাইলের বিষয়বস্তু হবে আপনি আগে body যা সম্পাদনা করেছেন তাই। অন্য কোনো এডিটরে ফাইলটি খুলে পরিবর্তনগুলো যাচাই করুন (অথবা ডকুমেন্টটিতে আবার ডাবল-ক্লিক করে ফাইলটি পুনরায় খুলে প্রক্রিয়াটি আবার শুরু করুন)।

2eccf61fe4a46109.png

202263abdedae737.png

অভিনন্দন! আপনি এইমাত্র বিশ্বের ক্ষুদ্রতম টেক্সট এডিটরটি তৈরি করেছেন [citation needed]

প্রতিক্রিয়া

এই এপিআইটি আপনার কেমন লেগেছে? অনুগ্রহ করে এই সমীক্ষায় সংক্ষেপে উত্তর দিয়ে আমাদের সাহায্য করুন:

এই এপিআইটি কি ব্যবহার করতে সহজবোধ্য ছিল?

হ্যাঁ না

আপনি কি উদাহরণটি চালাতে পেরেছেন?

হ্যাঁ না

আপনার কি আরও কিছু বলার আছে? কোনো বৈশিষ্ট্য কি বাদ পড়েছে? অনুগ্রহ করে এই সমীক্ষায় দ্রুত আপনার মতামত জানান। ধন্যবাদ!

৪. আকৃতি সনাক্তকরণ এপিআই

শেপ ডিটেকশন এপিআই (Shape Detection API) অ্যাক্সিলারেটেড শেপ ডিটেক্টর (যেমন, মানুষের মুখের জন্য) ব্যবহারের সুযোগ দেয় এবং এটি স্থির চিত্র এবং/অথবা লাইভ ইমেজ ফিডে কাজ করে। অপারেটিং সিস্টেমগুলিতে অ্যান্ড্রয়েড ফেসডিটেক্টর ( Android FaceDetector)-এর মতো পারফরম্যান্ট এবং অত্যন্ত অপ্টিমাইজড ফিচার ডিটেক্টর রয়েছে। শেপ ডিটেকশন এপিআই এই নেটিভ ইমপ্লিমেন্টেশনগুলিকে উন্মুক্ত করে এবং এক সেট জাভাস্ক্রিপ্ট ইন্টারফেসের মাধ্যমে সেগুলিকে প্রকাশ করে।

বর্তমানে সমর্থিত ফিচারগুলো হলো FaceDetector ইন্টারফেসের মাধ্যমে মুখমণ্ডল শনাক্তকরণ, BarcodeDetector ইন্টারফেসের মাধ্যমে বারকোড শনাক্তকরণ এবং TextDetector ইন্টারফেসের মাধ্যমে টেক্সট শনাক্তকরণ (অপটিক্যাল ক্যারেক্টার রিকগনিশন)।

মুখ সনাক্তকরণ

শেপ ডিটেকশন এপিআই-এর একটি আকর্ষণীয় বৈশিষ্ট্য হলো মুখমণ্ডল শনাক্তকরণ। এটি পরীক্ষা করার জন্য আমাদের মুখমণ্ডলযুক্ত একটি পৃষ্ঠা প্রয়োজন। লেখকের মুখমণ্ডলযুক্ত এই পৃষ্ঠাটি একটি ভালো সূচনা হতে পারে। এটি দেখতে নিচের স্ক্রিনশটের মতো হবে। একটি সমর্থিত ব্রাউজারে, মুখমণ্ডলের সীমানা এবং মুখের ল্যান্ডমার্কগুলো শনাক্ত করা যাবে।

গ্লিচ প্রজেক্টটি , বিশেষ করে script.js ফাইলটি রিমিক্স বা এডিট করলেই আপনি দেখতে পাবেন যে এই কাজটি করতে কতটা কম কোডের প্রয়োজন হয়েছিল।

f4aa7b77a0a1d1f5.png

আপনি যদি শুধু লেখকের মুখ নিয়ে কাজ না করে সম্পূর্ণ ডাইনামিকভাবে কাজ করতে চান, তাহলে একটি প্রাইভেট ট্যাবে বা গেস্ট মোডে মুখমণ্ডলে ভরা এই গুগল সার্চ রেজাল্ট পেজটিতে যান। এখন সেই পেজটিতে, যেকোনো জায়গায় রাইট-ক্লিক করে এবং তারপর 'Inspect'-এ ক্লিক করে Chrome Developer Tools খুলুন। এরপর, Console ট্যাবে, নিচের কোডটি পেস্ট করুন। কোডটি শনাক্ত করা মুখগুলোকে একটি আধা-স্বচ্ছ লাল বক্স দিয়ে হাইলাইট করবে।

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const faces = await new FaceDetector().detect(img);
    faces.forEach(face => {
      const div = document.createElement('div');
      const box = face.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left + left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      img.before(div);
    });
  } catch(e) {
    console.error(e);
  }
});

আপনি লক্ষ্য করবেন যে কিছু DOMException মেসেজ রয়েছে এবং সব ছবি প্রসেস করা হচ্ছে না। এর কারণ হলো , অ্যাবাভ-দ্য-ফোল্ড ছবিগুলো ডেটা ইউআরআই (Data URI) হিসেবে ইনলাইন করা থাকে এবং সে কারণে সেগুলো অ্যাক্সেস করা যায়, অপরদিকে বিলো-দ্য-ফোল্ড ছবিগুলো এমন একটি ভিন্ন ডোমেইন থেকে আসে যা CORS সাপোর্ট করার জন্য কনফিগার করা নেই। ডেমোর জন্য, আমাদের এই বিষয়টি নিয়ে চিন্তা করার প্রয়োজন নেই।

মুখের ল্যান্ডমার্ক সনাক্তকরণ

শুধুমাত্র মুখমণ্ডল ছাড়াও, macOS ফেস ল্যান্ডমার্ক শনাক্তকরণও সমর্থন করে। ফেস ল্যান্ডমার্ক শনাক্তকরণ পরীক্ষা করার জন্য, নিম্নলিখিত কোডটি কনসোলে পেস্ট করুন। মনে রাখবেন: crbug.com/914348 এর কারণে ল্যান্ডমার্কগুলোর বিন্যাস মোটেও নিখুঁত নয়, কিন্তু আপনি দেখতে পাবেন এটি কোন দিকে যাচ্ছে এবং এই ফিচারটি কতটা শক্তিশালী হতে পারে।

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const faces = await new FaceDetector().detect(img);
    faces.forEach(face => {
      const div = document.createElement('div');
      const box = face.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left + left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      img.before(div);

      const landmarkSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
      landmarkSVG.style.position = 'absolute';
      landmarkSVG.classList.add('landmarks');
      landmarkSVG.setAttribute('viewBox', `0 0 ${img.width} ${img.height}`);
      landmarkSVG.style.width = `${img.width}px`;
      landmarkSVG.style.height = `${img.height}px`;
      face.landmarks.map((landmark) => {                    
        landmarkSVG.innerHTML += `<polygon class="landmark-${landmark.type}" points="${
        landmark.locations.map((point) => {          
          return `${scaleX * point.x},${scaleY * point.y} `;
        }).join(' ')
      }" /></svg>`;          
      });
      div.before(landmarkSVG);
    });
  } catch(e) {
    console.error(e);
  }
});

বারকোড সনাক্তকরণ

শেপ ডিটেকশন এপিআই-এর দ্বিতীয় ফিচারটি হলো বারকোড ডিটেকশন। আগের মতোই, আমাদের বারকোডসহ একটি পেজ প্রয়োজন, যেমন এই পেজটি । যখন আপনি এটি একটি ব্রাউজারে খুলবেন, তখন আপনি বিভিন্ন কিউআর কোডগুলোর পাঠোদ্ধার দেখতে পাবেন। এটি কীভাবে করা হয় তা দেখতে গ্লিচ প্রজেক্টটি , বিশেষ করে script.js ফাইলটি রিমিক্স বা এডিট করুন।

7778003ff472389b.png

আপনি যদি আরও গতিশীল কিছু চান, তাহলে আমরা আবার গুগল ইমেজ সার্চ ব্যবহার করতে পারি। এবার, আপনার ব্রাউজারে একটি প্রাইভেট ট্যাবে বা গেস্ট মোডে এই গুগল সার্চ রেজাল্ট পেজটিতে যান। এখন নিচের কোডটি ক্রোম ডেভটুলস কনসোল ট্যাবে পেস্ট করুন। কিছুক্ষণ পরেই, শনাক্ত করা বারকোডগুলোতে র ভ্যালু এবং বারকোড টাইপ উল্লেখ করা হবে।

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const barcodes = await new BarcodeDetector().detect(img);
    barcodes.forEach(barcode => {
      const div = document.createElement('div');
      const box = barcode.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 255, 255, 0.75)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left - left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      div.style.color = 'black';
      div.style.fontSize = '14px';      
      div.textContent = `${barcode.rawValue}`;
      img.before(div);
    });
  } catch(e) {
    console.error(e);
  }
});

টেক্সট সনাক্তকরণ

শেপ ডিটেকশন এপিআই-এর সর্বশেষ ফিচারটি হলো টেক্সট ডিটেকশন। এতক্ষণে আপনি নিয়মটি জেনে গেছেন: আমাদের এমন একটি পেজ দরকার যেখানে ছবিতে টেক্সট রয়েছে, যেমন গুগল বুকস স্ক্যান রেজাল্টের এই পেজটি । সাপোর্টেড ব্রাউজারগুলোতে, আপনি টেক্সটটি শনাক্ত হতে দেখবেন এবং টেক্সটের অংশগুলোর চারপাশে একটি বাউন্ডিং বক্স আঁকা দেখতে পাবেন। এটি কীভাবে করা হয় তা দেখতে গ্লিচ প্রজেক্টটি , বিশেষ করে script.js ফাইলটি রিমিক্স বা এডিট করুন।

ec2be17d1e4d01ba.png

এটি ডাইনামিকভাবে পরীক্ষা করার জন্য, একটি প্রাইভেট ট্যাবে অথবা গেস্ট মোডে এই সার্চ রেজাল্ট পেজটিতে যান। এবার নিচের কোডটি Chrome DevTools Console ট্যাবে পেস্ট করুন। কিছুক্ষণ অপেক্ষা করলে, টেক্সটের কিছু অংশ শনাক্ত হবে।

document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
  try {
    const texts = await new TextDetector().detect(img);
    texts.forEach(text => {
      const div = document.createElement('div');
      const box = text.boundingBox;
      const computedStyle = getComputedStyle(img);
      const [top, right, bottom, left] = [
        computedStyle.marginTop,
        computedStyle.marginRight,
        computedStyle.marginBottom,
        computedStyle.marginLeft
      ].map(m => parseInt(m, 10));
      const scaleX = img.width / img.naturalWidth;
      const scaleY = img.height / img.naturalHeight;
      div.style.backgroundColor = 'rgba(255, 255, 255, 0.75)';
      div.style.position = 'absolute';
      div.style.top = `${scaleY * box.top + top}px`;
      div.style.left = `${scaleX * box.left - left}px`;
      div.style.width = `${scaleX * box.width}px`;
      div.style.height = `${scaleY * box.height}px`;
      div.style.color = 'black';
      div.style.fontSize = '14px';      
      div.innerHTML = text.rawValue;
      img.before(div);
    });
  } catch(e) {
    console.error(e);
  }
});

প্রতিক্রিয়া

এই এপিআইটি আপনার কেমন লেগেছে? অনুগ্রহ করে এই সমীক্ষায় সংক্ষেপে উত্তর দিয়ে আমাদের সাহায্য করুন:

এই এপিআইটি কি ব্যবহার করতে সহজবোধ্য ছিল?

হ্যাঁ না

আপনি কি উদাহরণটি চালাতে পেরেছেন?

হ্যাঁ না

আপনার কি আরও কিছু বলার আছে? কোনো বৈশিষ্ট্য কি বাদ পড়েছে? অনুগ্রহ করে এই সমীক্ষায় দ্রুত আপনার মতামত জানান। ধন্যবাদ!

৫. ওয়েব শেয়ার টার্গেট এপিআই

ওয়েব শেয়ার টার্গেট এপিআই ইনস্টল করা ওয়েব অ্যাপগুলোকে অন্তর্নিহিত অপারেটিং সিস্টেমের সাথে একটি শেয়ার টার্গেট হিসেবে নিবন্ধন করার সুযোগ দেয়, যাতে তারা ওয়েব শেয়ার এপিআই অথবা সিস্টেম ইভেন্ট (যেমন অপারেটিং-সিস্টেম-স্তরের শেয়ার বাটন) থেকে শেয়ার করা কন্টেন্ট গ্রহণ করতে পারে।

শেয়ার করার জন্য একটি PWA ইনস্টল করুন

প্রথম ধাপ হিসেবে, আপনার এমন একটি PWA প্রয়োজন যেখানে আপনি শেয়ার করতে পারবেন। এক্ষেত্রে, সৌভাগ্যবশত Airhorner দিয়ে কাজটি হবে না, কিন্তু Web Share Target ডেমো অ্যাপটি আপনার কাজে আসবে। অ্যাপটি আপনার ডিভাইসের হোম স্ক্রিনে ইনস্টল করুন।

925df16a12638bb2.png

PWA-তে কিছু শেয়ার করুন

এরপর, আপনার শেয়ার করার মতো কিছু একটা দরকার, যেমন গুগল ফটোস থেকে নেওয়া একটি ছবি। শেয়ার বাটনটি ব্যবহার করুন এবং শেয়ার করার লক্ষ্য হিসেবে স্ক্র্যাপবুক PWA-টি নির্বাচন করুন।

7216e8bb1be6d6db.png

যখন আপনি অ্যাপ আইকনটিতে ট্যাপ করবেন, তখন আপনি সরাসরি স্ক্র্যাপবুক PWA-তে চলে যাবেন এবং ছবিটি সেখানেই থাকবে।

9016985cb4bb48fe.png

তাহলে, এটি কীভাবে কাজ করে? তা জানতে, স্ক্র্যাপবুক PWA-এর ওয়েব অ্যাপ ম্যানিফেস্টটি দেখুন। ওয়েব শেয়ার টার্গেট এপিআই কার্যকর করার কনফিগারেশনটি ম্যানিফেস্টের "share_target" প্রপার্টিতে থাকে, যার "action" ফিল্ডটি এমন একটি URL-কে নির্দেশ করে, যা "params" এ তালিকাভুক্ত প্যারামিটারগুলো দিয়ে সজ্জিত হয়।

এরপর শেয়ারকারী পক্ষ সেই অনুযায়ী এই URL টেমপ্লেটটি পূরণ করে (যা একটি শেয়ার অ্যাকশনের মাধ্যমে অথবা ডেভেলপার কর্তৃক ওয়েব শেয়ার এপিআই ব্যবহার করে প্রোগ্রামগতভাবে নিয়ন্ত্রিত হতে পারে), যাতে গ্রহণকারী পক্ষ প্যারামিটারগুলো বের করে নিয়ে সেগুলো দিয়ে কোনো কাজ করতে পারে, যেমন—সেগুলো প্রদর্শন করা।

{
  "action": "/_share-target",
  "enctype": "multipart/form-data",
  "method": "POST",
  "params": {
    "files": [{
      "name": "media",
      "accept": ["audio/*", "image/*", "video/*"]
    }]
  }
}

প্রতিক্রিয়া

এই এপিআইটি আপনার কেমন লেগেছে? অনুগ্রহ করে এই সমীক্ষায় সংক্ষেপে উত্তর দিয়ে আমাদের সাহায্য করুন:

এই এপিআইটি কি ব্যবহার করতে সহজবোধ্য ছিল?

হ্যাঁ না

আপনি কি উদাহরণটি চালাতে পেরেছেন?

হ্যাঁ না

আপনার কি আরও কিছু বলার আছে? কোনো বৈশিষ্ট্য কি বাদ পড়েছে? অনুগ্রহ করে এই সমীক্ষায় দ্রুত আপনার মতামত জানান। ধন্যবাদ!

৬. ওয়েক লক এপিআই

ব্যাটারি দ্রুত শেষ হওয়া এড়াতে, বেশিরভাগ ডিভাইস নিষ্ক্রিয় থাকলে দ্রুত স্লিপ মোডে চলে যায়। যদিও বেশিরভাগ সময় এটি ঠিক আছে, কিছু অ্যাপ্লিকেশনের কাজ সম্পন্ন করার জন্য স্ক্রিন বা ডিভাইসটিকে জাগিয়ে রাখার প্রয়োজন হয়। ওয়েক লক এপিআই (Wake Lock API) ডিভাইসটির স্ক্রিন ডিম ও লক হওয়া অথবা স্লিপ মোডে যাওয়া প্রতিরোধ করার একটি উপায় প্রদান করে। এই সক্ষমতা এমন নতুন অভিজ্ঞতা প্রদান করে, যার জন্য এখন পর্যন্ত একটি নেটিভ অ্যাপের প্রয়োজন হতো।

একটি স্ক্রিনসেভার সেট আপ করুন

ওয়েক লক এপিআই (Wake Lock API) পরীক্ষা করার জন্য, আপনাকে প্রথমে নিশ্চিত করতে হবে যে আপনার ডিভাইসটি স্লিপ মোডে যাবে । এজন্য, আপনার অপারেটিং সিস্টেমের প্রেফারেন্স প্যানে (preference pane) আপনার পছন্দের একটি স্ক্রিনসেভার চালু করুন এবং নিশ্চিত করুন যে এটি ১ মিনিট পর চালু হয়। এটি কাজ করছে কিনা তা নিশ্চিত করতে, আপনার ডিভাইসটিকে ঠিক ওই সময়ের জন্য একা রেখে দিন (হ্যাঁ, আমি জানি, এটা কষ্টকর)। নিচের স্ক্রিনশটগুলোতে ম্যাকওএস (macOS) দেখানো হয়েছে, কিন্তু আপনি অবশ্যই এটি আপনার মোবাইল অ্যান্ড্রয়েড ডিভাইস বা যেকোনো সমর্থিত ডেস্কটপ প্ল্যাটফর্মে চেষ্টা করতে পারেন।

6f345e8c2b6c22c.png

স্ক্রিন ওয়েক লক সেট করুন

এখন যেহেতু আপনি জানেন যে আপনার স্ক্রিনসেভারটি কাজ করছে, তাই স্ক্রিনসেভারটিকে তার কাজ করা থেকে বিরত রাখতে আপনি "screen" টাইপের একটি ওয়েক লক ব্যবহার করবেন। ওয়েক লক ডেমো অ্যাপে যান এবং অ্যাক্টিভেট- এ ক্লিক করুন।

screen ওয়েক লক চেকবক্স।

12ed15dd94f51d4d.png

সেই মুহূর্ত থেকে একটি ওয়েক লক সক্রিয় হয়ে যায়। আপনি যদি এক মিনিটের জন্য আপনার ডিভাইসটি স্পর্শ না করে যথেষ্ট ধৈর্য ধরে রাখেন, তাহলে দেখতে পাবেন যে স্ক্রিনসেভারটি সত্যিই চালু হয়নি।

তাহলে এটা কীভাবে কাজ করে? তা জানতে, Glitch প্রজেক্টের Wake Lock ডেমো অ্যাপটিতে যান এবং script.js ফাইলটি দেখুন। কোডটির মূল অংশ নিচের স্নিপেটটিতে দেওয়া আছে। একটি নতুন ট্যাব খুলুন (অথবা আপনার খোলা থাকা যেকোনো ট্যাব ব্যবহার করুন) এবং নিচের কোডটি Chrome Developer Tools কনসোলে পেস্ট করুন। যখন আপনি উইন্ডোটিতে ক্লিক করবেন, তখন আপনি একটি ওয়েক লক দেখতে পাবেন যা ঠিক ১০ সেকেন্ডের জন্য সক্রিয় থাকবে (কনসোল লগ দেখুন), এবং আপনার স্ক্রিনসেভার চালু হবে না।

if ('wakeLock' in navigator && 'request' in navigator.wakeLock) {  
  let wakeLock = null;
  
  const requestWakeLock = async () => {
    try {
      wakeLock = await navigator.wakeLock.request('screen');
      wakeLock.addEventListener('release', () => {        
        console.log('Wake Lock was released');                    
      });
      console.log('Wake Lock is active');      
    } catch (e) {      
      console.error(`${e.name}, ${e.message}`);
    } 
  };

  requestWakeLock();
  window.setTimeout(() => {
    wakeLock.release();
  }, 10 * 1000);
}

621c2654d06a7cce.png

প্রতিক্রিয়া

এই এপিআইটি আপনার কেমন লেগেছে? অনুগ্রহ করে এই সমীক্ষায় সংক্ষেপে উত্তর দিয়ে আমাদের সাহায্য করুন:

এই এপিআইটি কি ব্যবহার করতে সহজবোধ্য ছিল?

হ্যাঁ না

আপনি কি উদাহরণটি চালাতে পেরেছেন?

হ্যাঁ না

আপনার কি আরও কিছু বলার আছে? কোনো বৈশিষ্ট্য কি বাদ পড়েছে? অনুগ্রহ করে এই সমীক্ষায় দ্রুত আপনার মতামত জানান। ধন্যবাদ!

৭. কন্টাক্ট পিকার এপিআই

একটি এপিআই যা নিয়ে আমরা খুবই উচ্ছ্বসিত, তা হলো কন্টাক্ট পিকার এপিআই। এটি একটি ওয়েব অ্যাপকে ডিভাইসের নিজস্ব কন্টাক্ট ম্যানেজার থেকে কন্টাক্ট অ্যাক্সেস করার সুযোগ দেয়, ফলে আপনার ওয়েব অ্যাপটি আপনার কন্টাক্টদের নাম, ইমেল অ্যাড্রেস এবং টেলিফোন নম্বর ব্যবহার করতে পারে। আপনি নির্দিষ্ট করে দিতে পারেন যে আপনি শুধু একটি নাকি একাধিক কন্টাক্ট চান এবং আপনি সমস্ত ফিল্ড চান নাকি শুধু নাম, ইমেল অ্যাড্রেস ও টেলিফোন নম্বরের একটি উপসেট চান।

গোপনীয়তার বিবেচনা

পিকারটি খুলে গেলে, আপনি যে কন্ট্যাক্টগুলো শেয়ার করতে চান তা বেছে নিতে পারেন। আপনি লক্ষ্য করবেন যে এখানে 'সবগুলো বেছে নিন' (select all) অপশন নেই, যা ইচ্ছাকৃতভাবেই করা হয়েছে: আমরা চাই শেয়ার করার বিষয়টি একটি সচেতন সিদ্ধান্ত হোক। একইভাবে, অ্যাক্সেস নিরবচ্ছিন্ন নয়, বরং এটি একটি এককালীন সিদ্ধান্ত।

যোগাযোগ অ্যাক্সেস করা

কন্ট্যাক্ট অ্যাক্সেস করা একটি সহজ কাজ। পিকারটি খোলার আগে, আপনি কোন ফিল্ডগুলো চান (অপশনগুলো হলো name , email এবং telephone ) এবং একাধিক নাকি শুধু একটি কন্ট্যাক্ট অ্যাক্সেস করতে চান, তা নির্দিষ্ট করে দিতে পারেন। ডেমো অ্যাপ্লিকেশনটি খুলে আপনি একটি অ্যান্ড্রয়েড ডিভাইসে এই API-টি পরীক্ষা করতে পারেন। সোর্স কোডের প্রাসঙ্গিক অংশটি মূলত নিচের কোড স্নিপেটটি:

getContactsButton.addEventListener('click', async () => {
  const contacts = await navigator.contacts.select(
      ['name', 'email'],
      {multiple: true});
  if (!contacts.length) {
    // No contacts were selected, or picker couldn't be opened.
    return;
  }
  console.log(contacts);
});

de94db2dfb7c67af.png

৮. অ্যাসিঙ্ক ক্লিপবোর্ড এপিআই

টেক্সট কপি এবং পেস্ট করা

এখন পর্যন্ত, সিস্টেমের ক্লিপবোর্ডে প্রোগ্রাম্যাটিকভাবে ছবি কপি ও পেস্ট করার কোনো উপায় ছিল না। সম্প্রতি, আমরা অ্যাসিঙ্ক ক্লিপবোর্ড এপিআই-তে ছবির সাপোর্ট যুক্ত করেছি।

ফলে এখন আপনি ছবি কপি ও পেস্ট করতে পারবেন। নতুন বিষয়টি হলো, আপনি ক্লিপবোর্ডে ছবি লিখতেও পারবেন। অ্যাসিঙ্ক্রোনাস ক্লিপবোর্ড এপিআই বেশ কিছুদিন ধরেই টেক্সট কপি ও পেস্ট করা সমর্থন করছিল। আপনি navigator.clipboard.writeText() কল করে ক্লিপবোর্ডে টেক্সট কপি করতে পারেন এবং পরে navigator.clipboard.readText() কল করে সেই টেক্সট পেস্ট করতে পারেন।

ছবি কপি এবং পেস্ট করা

এখন আপনি ক্লিপবোর্ডে ছবিও লিখতে পারবেন। এটি করার জন্য, ছবির ডেটা একটি ব্লব (blob) হিসেবে প্রয়োজন হবে, যা আপনাকে ক্লিপবোর্ড আইটেম কনস্ট্রাক্টরে পাস করতে হবে। সবশেষে, navigator.clipboard.write() কল করে আপনি এই ক্লিপবোর্ড আইটেমটি কপি করতে পারবেন।

// Copy: Writing image to the clipboard
try {
  const imgURL = 'https://developers.google.com/web/updates/images/generic/file.png';
  const data = await fetch(imgURL);
  const blob = await data.blob();
  await navigator.clipboard.write([
    new ClipboardItem(Object.defineProperty({}, blob.type, {
      value: blob,
      enumerable: true
    }))
  ]);
  console.log('Image copied.');
} catch(e) {
  console.error(e, e.message);
}

ক্লিপবোর্ড থেকে ছবিটি পুনরায় পেস্ট করা বেশ জটিল মনে হতে পারে, কিন্তু আসলে এটি কেবল ক্লিপবোর্ড আইটেম থেকে ব্লবটি ফিরিয়ে আনার বিষয়। যেহেতু একাধিক ব্লব থাকতে পারে, তাই আপনার কাঙ্ক্ষিতটি না পাওয়া পর্যন্ত সেগুলোর মধ্য দিয়ে লুপ করতে হবে। নিরাপত্তার কারণে, এই মুহূর্তে এটি শুধুমাত্র PNG ছবির জন্য সীমাবদ্ধ, তবে ভবিষ্যতে আরও ইমেজ ফরম্যাট সমর্থন করা হতে পারে।

async function getClipboardContents() {
  try {
    const clipboardItems = await navigator.clipboard.read();
    for (const clipboardItem of clipboardItems) {
      try {
        for (const type of clipboardItem.types) {
          const blob = await clipboardItem.getType(type);
          console.log(URL.createObjectURL(blob));
        }
      } catch (e) {
        console.error(e, e.message);
      }
    }
  } catch (e) {
    console.error(e, e.message);
  }
}

আপনি একটি ডেমো অ্যাপে এই এপিআই-টি বাস্তবে কাজ করতে দেখতে পারেন, যার সোর্স কোডের প্রাসঙ্গিক অংশগুলো উপরে এমবেড করা আছে। অনুমতি ছাড়াই ক্লিপবোর্ডে ছবি কপি করা যায়, কিন্তু ক্লিপবোর্ড থেকে পেস্ট করার জন্য আপনাকে অ্যাক্সেস দিতে হবে।

99f6dbf35ff4f393.png

অ্যাক্সেস দেওয়ার পর, আপনি ক্লিপবোর্ড থেকে ছবিটি পড়ে অ্যাপ্লিকেশনটিতে পেস্ট করতে পারবেন:

ace5945f4aca70ff.png

৯. আপনি পেরেছেন!

অভিনন্দন, আপনি কোডল্যাবের শেষ পর্যন্ত পৌঁছেছেন। আবারও মনে করিয়ে দেওয়া হচ্ছে যে, বেশিরভাগ এপিআই এখনও পরিবর্তনশীল এবং সেগুলোর ওপর সক্রিয়ভাবে কাজ চলছে। তাই, আপনার মতামত আমাদের দলের কাছে অত্যন্ত মূল্যবান, কারণ শুধুমাত্র আপনার মতো মানুষের সাথে আলোচনার মাধ্যমেই আমরা এই এপিআইগুলোকে নিখুঁত করতে পারব।

আমরা আপনাকে আমাদের ‘ক্যাপাবিলিটিজ’ ল্যান্ডিং পেজটি নিয়মিত দেখার জন্য উৎসাহিত করছি। আমরা এটিকে হালনাগাদ রাখব এবং এতে আমাদের তৈরি করা এপিআইগুলোর সমস্ত বিশদ নিবন্ধের লিঙ্ক রয়েছে। এগিয়ে চলুন!

টম এবং সম্পূর্ণ ক্যাপাবিলিটিজ টিম 🐡