Codelab เกี่ยวกับความสามารถเว็บ

1. ข้อมูลเบื้องต้นและการตั้งค่า

ความสามารถของเว็บ

เราต้องการลดช่องว่างด้านความสามารถระหว่างเว็บกับแอปเนทีฟ และช่วยให้นักพัฒนาแอปสร้างประสบการณ์ที่ยอดเยี่ยมบนเว็บแบบเปิดได้ง่ายๆ เราเชื่อมั่นว่านักพัฒนาซอฟต์แวร์ทุกคนควรมีสิทธิ์เข้าถึงความสามารถที่จำเป็นในการสร้างประสบการณ์การใช้งานเว็บที่ยอดเยี่ยม และเรามุ่งมั่นที่จะทำให้เว็บมีความสามารถมากขึ้น

อย่างไรก็ตาม ความสามารถบางอย่าง เช่น การเข้าถึงระบบไฟล์และการตรวจหาการไม่มีการใช้งาน จะใช้ได้ในแอปที่มาพร้อมเครื่อง แต่ใช้ไม่ได้บนเว็บ ความสามารถที่ขาดหายไปเหล่านี้หมายความว่าแอปบางประเภทไม่สามารถแสดงบนเว็บได้ หรือมีประโยชน์น้อยลง

เราจะออกแบบและพัฒนาความสามารถใหม่เหล่านี้ในลักษณะที่เปิดกว้างและโปร่งใส โดยใช้กระบวนการมาตรฐานของแพลตฟอร์มเว็บแบบเปิดที่มีอยู่ พร้อมรับความคิดเห็นในช่วงแรกจากนักพัฒนาซอฟต์แวร์และผู้ให้บริการเบราว์เซอร์รายอื่นๆ ขณะที่เราทำการออกแบบซ้ำ เพื่อให้มั่นใจว่าการออกแบบจะทำงานร่วมกันได้

สิ่งที่คุณจะสร้าง

ในโค้ดแล็บนี้ คุณจะได้ลองใช้ Web API หลายอย่างที่เพิ่งเปิดตัวหรือใช้ได้เฉพาะเมื่อเปิดใช้ฟีเจอร์ทดลอง ดังนั้น Codelab นี้จึงมุ่งเน้นที่ตัว API เองและ Use Case ที่ API เหล่านี้ปลดล็อก แทนที่จะมุ่งเน้นที่การสร้างผลิตภัณฑ์ขั้นสุดท้ายที่เฉพาะเจาะจง

สิ่งที่คุณจะได้เรียนรู้

Codelab นี้จะสอนกลไกพื้นฐานของ API ที่ล้ำสมัยหลายรายการ โปรดทราบว่ากลไกเหล่านี้ยังไม่แน่นอน และเราขอขอบคุณเป็นอย่างยิ่งสำหรับความคิดเห็นเกี่ยวกับขั้นตอนการทำงานของนักพัฒนาแอป

สิ่งที่คุณต้องมี

เนื่องจาก API ที่แสดงในโค้ดแล็บนี้เป็น API ที่ใหม่ล่าสุด ข้อกำหนดสำหรับ API แต่ละรายการจึงแตกต่างกัน โปรดอ่านข้อมูลความเข้ากันได้อย่างละเอียดที่ตอนต้นของแต่ละส่วน

วิธีเข้าถึง Codelab

คุณไม่จำเป็นต้องทำตาม Codelab ตามลำดับ แต่ละส่วนแสดงถึง API ที่เป็นอิสระ ดังนั้นคุณจึงเลือกส่วนที่สนใจมากที่สุดได้

2. Badging API

เป้าหมายของ Badging API คือการดึงดูดความสนใจของผู้ใช้ไปยังสิ่งที่เกิดขึ้นในเบื้องหลัง เพื่อความสะดวกในการสาธิตในโค้ดแล็บนี้ เราจะใช้ API เพื่อดึงดูดความสนใจของผู้ใช้ไปยังสิ่งที่เกิดขึ้นในเบื้องหน้า จากนั้นคุณจะสามารถเชื่อมโยงกับสิ่งที่เกิดขึ้นในเบื้องหลังได้

ติดตั้ง Airhorner

หากต้องการให้ API นี้ทำงานได้ คุณต้องมี PWA ที่ติดตั้งไว้ในหน้าจอหลัก ดังนั้นขั้นตอนแรกคือการติดตั้ง PWA เช่น airhorner.com ที่โด่งดังไปทั่วโลก กดปุ่มติดตั้งที่มุมขวาบนหรือใช้เมนู 3 จุดเพื่อติดตั้งด้วยตนเอง

8b7fa8b3c94c6bdd.png

ข้อความแจ้งให้ยืนยันจะปรากฏขึ้น ให้คลิกติดตั้ง

98e90422167ac786.png

ตอนนี้คุณมีไอคอนใหม่ในแถบแอปของระบบปฏิบัติการแล้ว คลิกเพื่อเปิด PWA โดยจะมีหน้าต่างแอปของตัวเองและทำงานในโหมดสแตนด์อโลน

การตั้งค่าป้าย

เมื่อติดตั้ง PWA แล้ว คุณจะต้องมีข้อมูลตัวเลข (ป้ายมีได้เฉพาะตัวเลข) เพื่อแสดงบนป้าย สิ่งหนึ่งที่นับได้ง่ายๆ ใน The Air Horner คือ sigh จำนวนครั้งที่มีการกดแตร จริงๆ แล้วเมื่อติดตั้งแอป Airhorner แล้ว ให้ลองกดแตรและดูป้าย โดยจะนับเพิ่มขึ้นทุกครั้งที่คุณบีบแตร

b5e39de7a1775054.png

แล้วฟีเจอร์นี้ทำงานอย่างไร โดยพื้นฐานแล้ว โค้ดคือ

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

เป่าแตรลม 2-3 ครั้งแล้วตรวจสอบไอคอนของ PWA ซึ่งจะอัปเดตทุกครั้งที่มีเสียงแตรลม ง่ายๆ เพียงเท่านี้

eed10c3ffe59999.png

การล้างป้าย

โดยตัวนับจะเพิ่มขึ้นไปจนถึง 99 แล้วจึงเริ่มใหม่ หรือจะรีเซ็ตด้วยตนเองก็ได้ เปิดแท็บคอนโซลของเครื่องมือสำหรับนักพัฒนาเว็บ วางบรรทัดด้านล่าง แล้วกด Enter

navigator.setExperimentalAppBadge(0);

หรือคุณจะนำป้ายออกโดยล้างป้ายอย่างชัดเจนตามที่แสดงในข้อมูลโค้ดต่อไปนี้ก็ได้ ตอนนี้ไอคอนของ PWA ควรกลับมามีลักษณะเหมือนตอนแรกอีกครั้ง คือชัดเจนและไม่มีป้าย

navigator.clearExperimentalAppBadge();

33eafb314a3a9f30.png

ความคิดเห็น

คุณคิดอย่างไรกับ API นี้ โปรดช่วยเราโดยตอบแบบสำรวจนี้สั้นๆ

API นี้ใช้งานง่ายไหม

ใช่ ไม่ใช่

คุณได้ตัวอย่างไปเรียกใช้ไหม

ใช่ ไม่ใช่

หากมีเรื่องอื่นๆ ที่อยากบอก มีฟีเจอร์ใดขาดหายไปหรือไม่ โปรดแสดงความคิดเห็นสั้นๆ ในแบบสำรวจนี้ ขอขอบคุณ

3. Native File System API

Native File System API ช่วยให้นักพัฒนาซอฟต์แวร์สร้างเว็บแอปที่มีประสิทธิภาพซึ่งโต้ตอบกับไฟล์ในอุปกรณ์ของผู้ใช้ได้ หลังจากที่ผู้ใช้ให้สิทธิ์เข้าถึงเว็บแอปแล้ว API นี้จะอนุญาตให้เว็บแอปอ่านหรือบันทึกการเปลี่ยนแปลงลงในไฟล์และโฟลเดอร์ในอุปกรณ์ของผู้ใช้ได้โดยตรง

การอ่านไฟล์

"Hello, world" ของ Native File System API คือการอ่านไฟล์ในเครื่องและรับเนื้อหาของไฟล์ สร้างไฟล์ .txt ธรรมดาและป้อนข้อความ จากนั้นไปที่เว็บไซต์ที่ปลอดภัย (เช่น เว็บไซต์ที่แสดงผ่าน HTTPS) เช่น example.com แล้วเปิดคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ วางข้อมูลโค้ดด้านล่างในคอนโซล เนื่องจาก Native File System API ต้องใช้ท่าทางของผู้ใช้ เราจึงแนบตัวแฮนเดิลการดับเบิลคลิกในเอกสาร เราจะต้องใช้ตัวแฮนเดิลไฟล์ในภายหลัง ดังนั้นเราจึงกำหนดให้เป็นตัวแปรส่วนกลาง

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ไฟล์ที่คุณสร้างไว้ก่อนหน้านี้ จากนั้นเนื้อหาของไฟล์จะแทนที่bodyเนื้อหาจริงของ example.com

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]

ความคิดเห็น

คุณคิดอย่างไรกับ API นี้ โปรดช่วยเราโดยตอบแบบสำรวจนี้สั้นๆ

API นี้ใช้งานง่ายไหม

ใช่ ไม่ใช่

คุณได้ตัวอย่างไปเรียกใช้ไหม

ใช่ ไม่ใช่

หากมีเรื่องอื่นๆ ที่อยากบอก มีฟีเจอร์ใดขาดหายไปหรือไม่ โปรดแสดงความคิดเห็นสั้นๆ ในแบบสำรวจนี้ ขอขอบคุณ

4. Shape Detection API

Shape Detection API ให้สิทธิ์เข้าถึงเครื่องตรวจจับรูปร่างที่เร่งความเร็ว (เช่น ใบหน้าของมนุษย์) และทำงานกับภาพนิ่งและ/หรือฟีดภาพสด ระบบปฏิบัติการมีเครื่องตรวจหาฟีเจอร์ที่มีประสิทธิภาพและได้รับการเพิ่มประสิทธิภาพอย่างสูง เช่น FaceDetector ของ Android Shape Detection API จะเปิดการใช้งานดั้งเดิมเหล่านี้และแสดงผ่านชุดอินเทอร์เฟซ JavaScript

ปัจจุบันฟีเจอร์ที่รองรับคือการตรวจจับใบหน้าผ่านอินเทอร์เฟซ FaceDetector การตรวจจับบาร์โค้ดผ่านอินเทอร์เฟซ BarcodeDetector และการตรวจจับข้อความ (การรู้จำอักขระด้วยภาพ) ผ่านอินเทอร์เฟซ TextDetector

การตรวจจับใบหน้า

ฟีเจอร์ที่น่าสนใจของ Shape Detection API คือการตรวจจับใบหน้า หากต้องการทดสอบ เราต้องมีหน้าเว็บที่มีใบหน้า หน้านี้ที่มีใบหน้าของผู้เขียนเป็นจุดเริ่มต้นที่ดี โดยจะมีลักษณะคล้ายกับในภาพหน้าจอด้านล่าง ในเบราว์เซอร์ที่รองรับ ระบบจะจดจำกรอบขอบเขตของใบหน้าและจุดสังเกตบนใบหน้า

คุณจะเห็นว่าใช้โค้ดเพียงเล็กน้อยในการทำให้ฟีเจอร์นี้ทำงานได้โดยการรีมิกซ์หรือแก้ไขโปรเจ็กต์ Glitch โดยเฉพาะไฟล์ script.js

f4aa7b77a0a1d1f5.png

หากต้องการใช้แบบไดนามิกอย่างเต็มรูปแบบและไม่ได้ใช้แค่ใบหน้าของผู้เขียน ให้ไปที่หน้าผลการค้นหาของ Google Search ที่มีใบหน้าเต็มไปหมดในแท็บส่วนตัวหรือในโหมดผู้มาเยือน ตอนนี้ในหน้านั้น ให้เปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome โดยคลิกขวาที่ใดก็ได้ แล้วคลิกตรวจสอบ จากนั้นในแท็บคอนโซล ให้วางข้อมูลโค้ดด้านล่าง โค้ดจะไฮไลต์ใบหน้าที่ตรวจพบด้วยกรอบสีแดงแบบกึ่งโปร่งใส

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 บางรายการ และระบบไม่ได้ประมวลผลรูปภาพทั้งหมด เนื่องจากรูปภาพเหนือพับจะฝังเป็น 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);
  }
});

การตรวจจับบาร์โค้ด

ฟีเจอร์ที่ 2 ของ Shape Detection API คือการตรวจจับบาร์โค้ด เช่นเดียวกับก่อนหน้านี้ เราต้องการหน้าที่มีบาร์โค้ด เช่น หน้านี้ เมื่อเปิดในเบราว์เซอร์ คุณจะเห็นคิวอาร์โค้ดต่างๆ ที่ถอดรหัสแล้ว รีมิกซ์หรือแก้ไขโปรเจ็กต์ Glitch โดยเฉพาะไฟล์ script.js เพื่อดูวิธีการ

7778003ff472389b.png

หากต้องการอะไรที่ไดนามิกมากขึ้น เราก็ใช้ Google Image Search ได้อีกครั้ง คราวนี้ในเบราว์เซอร์ ให้ไปที่หน้าผลการค้นหาของ Google Search นี้ในแท็บส่วนตัวหรือในโหมดผู้มาเยือน ตอนนี้ให้วางข้อมูลโค้ดด้านล่างในแท็บคอนโซลของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome หลังจากนั้นไม่นาน ระบบจะใส่คำอธิบายประกอบบาร์โค้ดที่จดจำได้พร้อมค่าดิบและประเภทบาร์โค้ด

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

การตรวจหาข้อความ

ฟีเจอร์สุดท้ายของ Shape Detection API คือการตรวจหาข้อความ ตอนนี้คุณคงทราบแล้วว่าเราต้องการหน้าเว็บที่มีรูปภาพซึ่งมีข้อความ เช่น หน้านี้ที่มีผลการสแกนจาก Google Books ในเบราว์เซอร์ที่รองรับ คุณจะเห็นข้อความที่ระบบจดจำและกรอบล้อมรอบข้อความ รีมิกซ์หรือแก้ไขโปรเจ็กต์ Glitch โดยเฉพาะไฟล์ script.js เพื่อดูวิธีการ

ec2be17d1e4d01ba.png

หากต้องการทดสอบแบบไดนามิก ให้ไปที่หน้าผลการค้นหานี้ในแท็บส่วนตัวหรือในโหมดผู้มาเยือน ตอนนี้ให้วางข้อมูลโค้ดด้านล่างในแท็บคอนโซลของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome หากรอสักครู่ ระบบจะจดจำข้อความบางส่วนได้

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

ความคิดเห็น

คุณคิดอย่างไรกับ API นี้ โปรดช่วยเราโดยตอบแบบสำรวจนี้สั้นๆ

API นี้ใช้งานง่ายไหม

ใช่ ไม่ใช่

คุณได้ตัวอย่างไปเรียกใช้ไหม

ใช่ ไม่ใช่

หากมีเรื่องอื่นๆ ที่อยากบอก มีฟีเจอร์ใดขาดหายไปหรือไม่ โปรดแสดงความคิดเห็นสั้นๆ ในแบบสำรวจนี้ ขอขอบคุณ

5. Web Share Target API

Web Share Target API ช่วยให้เว็บแอปที่ติดตั้งลงทะเบียนกับระบบปฏิบัติการพื้นฐานเป็นเป้าหมายการแชร์เพื่อรับเนื้อหาที่แชร์จาก Web Share API หรือเหตุการณ์ของระบบ เช่น ปุ่มแชร์ระดับระบบปฏิบัติการ

ติดตั้ง PWA เพื่อแชร์ไปยัง

ขั้นตอนแรก คุณต้องมี PWA ที่แชร์ได้ คราวนี้ Airhorner (โชคดี) จะไม่ทำงาน แต่แอปเดโมเป้าหมายการแชร์บนเว็บจะช่วยคุณได้ ติดตั้งแอปในหน้าจอหลักของอุปกรณ์

925df16a12638bb2.png

แชร์ไปยัง PWA

จากนั้นคุณต้องมีสิ่งที่ต้องการแชร์ เช่น รูปภาพจาก Google Photos ใช้ปุ่มแชร์และเลือก PWA ของ Scrapbook เป็นเป้าหมายการแชร์

7216e8bb1be6d6db.png

เมื่อแตะไอคอนแอป คุณจะไปที่ PWA ของ Scrapbook โดยตรงและเห็นรูปภาพทันที

9016985cb4bb48fe.png

แล้วฟีเจอร์นี้ทำงานอย่างไร หากต้องการทราบ ให้สำรวจไฟล์ Manifest ของเว็บแอปของ PWA Scrapbook การกำหนดค่าเพื่อให้ Web Share Target API ทำงานจะอยู่ในพร็อพเพอร์ตี้ "share_target" ของไฟล์ Manifest ซึ่งในช่อง "action" จะชี้ไปยัง URL ที่ได้รับการตกแต่งด้วยพารามิเตอร์ตามที่ระบุไว้ใน "params"

จากนั้นฝั่งที่แชร์จะสร้างเทมเพลต URL นี้ตามนั้น (ไม่ว่าจะผ่านการดำเนินการแชร์หรือควบคุมโดยโปรแกรมเมอร์โดยใช้ Web Share API) เพื่อให้ฝั่งที่รับสามารถแยกพารามิเตอร์และดำเนินการกับพารามิเตอร์เหล่านั้นได้ เช่น แสดงพารามิเตอร์

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

ความคิดเห็น

คุณคิดอย่างไรกับ API นี้ โปรดช่วยเราโดยตอบแบบสำรวจนี้สั้นๆ

API นี้ใช้งานง่ายไหม

ใช่ ไม่ใช่

คุณได้ตัวอย่างไปเรียกใช้ไหม

ใช่ ไม่ใช่

หากมีเรื่องอื่นๆ ที่อยากบอก มีฟีเจอร์ใดขาดหายไปหรือไม่ โปรดแสดงความคิดเห็นสั้นๆ ในแบบสำรวจนี้ ขอขอบคุณ

6. Wake Lock API

อุปกรณ์ส่วนใหญ่จะเข้าสู่โหมดสลีปอย่างรวดเร็วเมื่อไม่มีการใช้งานเพื่อป้องกันไม่ให้แบตเตอรี่หมด แม้ว่าโดยส่วนใหญ่แล้วการตั้งค่านี้จะไม่มีปัญหา แต่แอปพลิเคชันบางอย่างจำเป็นต้องเปิดหน้าจอหรืออุปกรณ์ไว้เพื่อให้ทำงานเสร็จ Wake Lock API มีวิธีป้องกันไม่ให้อุปกรณ์หรี่แสงและล็อกหน้าจอ หรือป้องกันไม่ให้อุปกรณ์เข้าสู่โหมดสลีป ความสามารถนี้ช่วยให้เกิดประสบการณ์ใหม่ๆ ซึ่งก่อนหน้านี้ต้องใช้แอปเนทีฟ

ตั้งค่าการพักหน้าจอ

หากต้องการทดสอบ Wake Lock API คุณต้องตรวจสอบก่อนว่าอุปกรณ์จะเข้าสู่โหมดพัก ดังนั้น ในแผงค่ากำหนดของระบบปฏิบัติการ ให้เปิดใช้งานโปรแกรมรักษาหน้าจอที่คุณเลือกและตรวจสอบว่าโปรแกรมจะเริ่มทำงานหลังจากผ่านไป 1 นาที ตรวจสอบว่าการตั้งค่าใช้งานได้โดยปล่อยให้อุปกรณ์อยู่เฉยๆ เป็นเวลาดังกล่าว (เราทราบว่าอาจเป็นเรื่องยาก) ภาพหน้าจอด้านล่างแสดง macOS แต่คุณสามารถลองใช้ฟีเจอร์นี้ในอุปกรณ์เคลื่อนที่ Android หรือแพลตฟอร์มเดสก์ท็อปที่รองรับได้

6f345e8c2b6c22c.png

ตั้งค่า Wake Lock ของหน้าจอ

เมื่อทราบว่าโปรแกรมรักษาหน้าจอทำงานแล้ว คุณจะใช้ Wake Lock ประเภท "screen" เพื่อป้องกันไม่ให้โปรแกรมรักษาหน้าจอทำงาน ไปที่แอปสาธิต Wake Lock แล้วคลิกเปิดใช้งาน

screen ช่องทำเครื่องหมาย Wake Lock

12ed15dd94f51d4d.png

ตั้งแต่ช่วงเวลานั้นเป็นต้นไป Wake Lock จะทำงาน หากรอจนครบ 1 นาทีโดยไม่แตะต้องอุปกรณ์ คุณจะเห็นว่าโปรแกรมรักษาหน้าจอไม่ได้เริ่มทำงาน

แล้วฟีเจอร์นี้ทำงานอย่างไร หากต้องการดู ให้ไปที่โปรเจ็กต์ Glitch สำหรับแอปสาธิต Wake Lock แล้วดู script.js ส่วนสำคัญของโค้ดอยู่ในข้อมูลโค้ดด้านล่าง เปิดแท็บใหม่ (หรือใช้แท็บใดก็ได้ที่เปิดอยู่) แล้ววางโค้ดด้านล่างในคอนโซลเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome เมื่อคลิกหน้าต่าง คุณจะเห็น Wake Lock ที่ทำงานเป็นเวลา 10 วินาที (ดูบันทึกของคอนโซล) และโปรแกรมพักหน้าจอไม่ควรเริ่มทำงาน

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

ความคิดเห็น

คุณคิดอย่างไรกับ API นี้ โปรดช่วยเราโดยตอบแบบสำรวจนี้สั้นๆ

API นี้ใช้งานง่ายไหม

ใช่ ไม่ใช่

คุณได้ตัวอย่างไปเรียกใช้ไหม

ใช่ ไม่ใช่

หากมีเรื่องอื่นๆ ที่อยากบอก มีฟีเจอร์ใดขาดหายไปหรือไม่ โปรดแสดงความคิดเห็นสั้นๆ ในแบบสำรวจนี้ ขอขอบคุณ

7. Contact Picker API

API ที่เราตื่นเต้นมากคือ Contact Picker API ซึ่งจะช่วยให้เว็บแอปเข้าถึงรายชื่อติดต่อจากเครื่องมือจัดการรายชื่อติดต่อดั้งเดิมของอุปกรณ์ได้ เพื่อให้เว็บแอปเข้าถึงชื่อ อีเมล และหมายเลขโทรศัพท์ของรายชื่อติดต่อได้ คุณระบุได้ว่าต้องการรายชื่อติดต่อเพียงรายเดียวหรือหลายราย และต้องการฟิลด์ทั้งหมดหรือเพียงชุดย่อยของชื่อ อีเมล และหมายเลขโทรศัพท์

ข้อควรพิจารณาด้านความเป็นส่วนตัว

เมื่อเครื่องมือเลือกเปิดขึ้น คุณจะเลือกรายชื่อติดต่อที่ต้องการแชร์ได้ คุณจะเห็นว่าไม่มีตัวเลือก "เลือกทั้งหมด" ซึ่งเป็นสิ่งที่เราตั้งใจไว้ เนื่องจากเราต้องการให้การแชร์เป็นสิ่งที่เกิดจากการตัดสินใจอย่างรอบคอบ ในทำนองเดียวกัน การเข้าถึงไม่ได้ต่อเนื่อง แต่เป็นการตัดสินใจแบบครั้งเดียว

การเข้าถึงรายชื่อติดต่อ

การเข้าถึงรายชื่อติดต่อเป็นงานที่ตรงไปตรงมา ก่อนที่เครื่องมือเลือกจะเปิดขึ้น คุณสามารถระบุฟิลด์ที่ต้องการ (ตัวเลือกคือ name, email และ telephone) และเลือกว่าต้องการเข้าถึงรายชื่อติดต่อหลายรายการหรือเพียงรายการเดียว คุณทดสอบ API นี้ในอุปกรณ์ Android ได้โดยเปิดแอปพลิเคชันเดโม ส่วนที่เกี่ยวข้องของซอร์สโค้ดคือข้อมูลโค้ดด้านล่าง

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

8. Async Clipboard API

การคัดลอกและวางข้อความ

ก่อนหน้านี้ไม่มีวิธีคัดลอกและวางรูปภาพลงในคลิปบอร์ดของระบบโดยใช้โปรแกรม เมื่อเร็วๆ นี้ เราได้เพิ่มการรองรับรูปภาพลงใน Async Clipboard API

เพื่อให้คุณคัดลอกและวางรูปภาพได้ สิ่งใหม่คือคุณยังเขียนรูปภาพไปยังคลิปบอร์ดได้ด้วย API คลิปบอร์ดแบบไม่พร้อมกันรองรับการคัดลอกและวางข้อความมาสักระยะหนึ่งแล้ว คุณคัดลอกข้อความไปยังคลิปบอร์ดได้โดยเรียกใช้ 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);
}

การวางรูปภาพจากคลิปบอร์ดอาจดูซับซ้อน แต่จริงๆ แล้วก็แค่การนำ Blob กลับมาจากรายการในคลิปบอร์ด เนื่องจากอาจมีหลายรายการ คุณจึงต้องวนซ้ำจนกว่าจะพบรายการที่ต้องการ ปัจจุบันระบบรองรับเฉพาะรูปภาพ 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);
  }
}

คุณดูการทำงานของ API นี้ได้ในแอปเดโม โดยเราได้ฝังข้อมูลโค้ดที่เกี่ยวข้องจากซอร์สโค้ดไว้ด้านบน คุณสามารถคัดลอกรูปภาพไปยังคลิปบอร์ดได้โดยไม่ต้องขอสิทธิ์ แต่ต้องให้สิทธิ์เข้าถึงเพื่อวางจากคลิปบอร์ด

99f6dbf35ff4f393.png

หลังจากให้สิทธิ์เข้าถึงแล้ว คุณจะอ่านรูปภาพจากคลิปบอร์ดและวางในแอปพลิเคชันได้โดยทำดังนี้

ace5945f4aca70ff.png

9. สำเร็จแล้ว!

ขอแสดงความยินดี คุณมาถึงตอนท้ายของโค้ดแล็บแล้ว อีกครั้งที่ขอแจ้งเตือนว่า API ส่วนใหญ่ยังอยู่ระหว่างการเปลี่ยนแปลงและเรากำลังดำเนินการอย่างต่อเนื่อง ดังนั้น ทีมงานจึงขอขอบคุณสำหรับความคิดเห็นของคุณเป็นอย่างยิ่ง เพราะการโต้ตอบกับผู้ใช้เช่นคุณเท่านั้นที่จะช่วยให้เราสร้าง API เหล่านี้ได้อย่างถูกต้อง

นอกจากนี้ เราขอแนะนำให้คุณดูหน้า Landing Page ของความสามารถเป็นประจำด้วย เราจะอัปเดตข้อมูลนี้อยู่เสมอ และมีลิงก์ไปยังบทความเชิงลึกทั้งหมดสำหรับ API ที่เราใช้งาน ขอให้สนุกกับการฟังเพลง

ทอมและทีมความสามารถทั้งหมด 🐡