Skip to main content
HTMLWeb Technologies

เซฟหน้า HTML ให้เป็นภาพด้วย HTML2Canvas

เคยไหมกับการที่เราต้องการทำระบบเซฟภาพจากเว็บไซต์ของเรา แต่ที่เราต้องการเซฟดันเป็น HTML แทนที่จะเป็นไฟล์ภาพ จะให้ user แคปจอเอาเองก็ดูจะเป็นการลำบาก user ไปหน่อย ในบทความนี้จะขอนำเสนอ Library ที่จะแปลง HTML ให้กลายเป็นรูปภาพ นั่นก็คือ HTML2Canvas นั่นเอง!

เขียนโดย
Thanawat Udchachon
Internship @ borntoDev

Canvas คืออะไร

ก่อนอื่นเรามาทำความรู้จักกับ Canvas กันก่อนดีกว่าว่ามันคืออะไร เจ้า Canvas มันก็คือ element หนึ่งใน HTML5 ที่ใช้สำหรับการวาดกราฟฟิก ไม่ว่าจะเป็น text เส้น หรือรูปทรงต่าง ๆ ซึ่งเราสามารถคลิกขวาแล้วเซฟเป็นไฟล์ภาพได้ โดย canvas จะมี attribute 2 ตัวคือ width และ height ซึ่งก็คือความกว้างและความสูงของ canvas โดยมีข้อควรรู้คือ canvas จะเริ่มจุด 0, 0 ที่มุมซ้ายบน ต่างจากที่เราคุ้นชินกันที่จะเริ่มจุด 0, 0 ที่ตรงกลาง

 

การใช้งาน HTML2Canvas

ทีนี้เราก็มาถึงพระเอกของบทความนี้กันแล้ว นั่นก็คือ HTML2Canvas โดยมันคือสคริปที่ใช้สำหรับการแปลง HTML ให้กลายเป็นภาพ png, jpg หรือ pdf ได้โดยการแปลง HTML เหล่านั้นเป็น Canvas นั่นเอง

สำหรับการใช้งานก็สามารถไปติดตั้งตามลิงก์นี้ได้เลยครับ https://www.npmjs.com/package/html2canvas

สำหรับการใช้งาน ในที่นี้เราก็จะใช้เป็น react เช่นเคย และตัวอย่างของเราก็คือ ใบ certificate ของ devlab นั่นเอง

จะเห็นได้จากตัวอย่างจะเห็นได้ว่าเราไม่สามารถคลิกขวาที่ certificate เพื่อ save as image ได้ เพราะตัว certificate นี้เป็น HTML ดังนั้นสิ่งที่เราจะทำกันก็คือแปลง HTML นี้ให้เป็น canvas มาดูตัวอย่างโค้ดกันเลยดีกว่า

import React, { useRef } from 'react';
import html2canvas from 'html2canvas';

const Certification = () => {

  const certificateRef = useRef(null);

  const screenShot = (element) => {
    html2canvas(element).then((canvas) => {
      document.body.appendChild(canvas);
    });
};

return (
  <div>
  <div ref={certificateRef}>
    <Certificate />
  </div>
    <button onClick={() => screenShot(certificateRef.current)}>
  ดาวน์โหลด
     </button>
  </div>
 );
};

export default CertificationOnline;

จากโค้ดตัวอย่าง เราได้สร้าง function ที่ชื่อว่า screenShot โดย function นี้ก็จะทำการใช้ html2canvas เพื่อแปลง HTML element ที่เราใส่เข้ามาให้กลายเป็น canvas แล้วหลังจากนั้นก็ทำการแสดงผล canvas นั้น และสำหรับในฝั่ง return ก็จะมี component ที่เราต้องการที่จะแปลงเป็น canvas เราก็ใช้ useRef ที่เป็น hook ของ react สำหรับการอ้างอิง (ถ้าหากเพื่อน ๆ ไม่ได้ใช้ react ก็สามารถใช้ id แทนได้นะครับ) จากนั้นเราก็สร้างปุ่มที่เมื่อกดจะไปเรียกฟังก์ชัน screenShot โดยใส่ element เป็นตัว certificate ของเราโดยอ้างอิงจาก useRef ที่เราได้ใส่ไปนั่นเอง

ทีนี้ตัว certificate ที่เราได้ทำการ append ออกมาก็สามารถที่จะเซฟเป็นภาพได้แล้วครับผม

โดยถ้าหากเพื่อน ๆ ไม่ได้ต้องการให้เป็นการกดปุ่มเพื่อ append ต่อออกมา แต่ต้องการให้เมื่อกดปุ่มแล้วเป็นการเซฟภาพลงเครื่องเลยก็สามารถทำได้เช่นกันครับ เรามาดูตัวอย่างโค้ดกันดีกว่า

const printDocument = (domElement) => {
  html2canvas(domElement).then((canvas) => {
    const image = canvas.toDataURL('png');
    const a = document.createElement('a');
    a.setAttribute('download', 'certificate.png');
    a.setAttribute('href', image);
    a.click();
  });
};

ในส่วนของ function นี้เราก็แค่เปลี่ยนจาก document.body.appendChild(canvas); เป็นการแปลง canvas ที่ได้ออกมาเป็นไฟล์ png แล้วเมื่อกดปุ่มก็จะเป็นการดาวน์โหลดภาพนั้น โดยจะมีชื่อว่า certificate.png ครับ

 

Options ของ HTML2Canvas

นอกจากการเปลี่ยง HTML ให้เป็น canvas เฉย ๆ แล้ว library ตัวนี้ก็ยังมี options เพิ่มเติมในการสร้าง canvas อยู่อีก ตัวอย่างเช่น หากหน้าที่เราต้องการที่จะ screenshot นั้นเป็นหน้ายาว เราก็สามารถใส่ option scrollY ตามตัวอย่างโค้ดด้านล่างนี้

html2canvas(element, { scrollY: -window.scrollY }).then((canvas) => {
  document.body.appendChild(canvas);
});

หรือเราต้องการให้ canvas ที่ออกมาใหญ่กว่า HTML ที่เราเขียนไว้ด้วย ก็สามารถใส่ option scale ได้ตามตัวอย่างโค้ดนี้

html2canvas(element, { scrollY: -window.scrollY, scale: 2 }).then((canvas) => {
  document.body.appendChild(canvas);
});

นอกจากนี้ก็ยังมี options อื่น ๆ อีกมากมาย เพื่อน ๆ สามารถดูรายละเอียดเพิ่มเติมได้ที่ลิงก์นี้เลยครับผม https://html2canvas.hertzen.com/configuration

ข้อจำกัดของ HTML2Canvas

ถึงจะดูใช้ง่ายใช้ดีอย่างนี้ แต่ HTML2Canvas ก็มีข้อจำกัดอยู่บ้างเหมือนกันเพราะด้วยความที่มันไม่ได้เป็นการ screenshot หน้านั้นมาตรง ๆ เหมือนกับการแคปหน้าจอโทรศัพท์ แต่เป็นการสร้างภาพนั้นจาก browser ของฝั่ง client เอง ทำให้ไม่สามารถสร้างภาพที่เรนเดอร์จากฝั่ง server ได้ ยังมีการติดในเรื่องของ cross-origin และ proxy อยู่ในการสร้างภาพ จะทำให้ไม่สามารถแสดงภาพเหล่านั้นได้ ดังรูป

จะเห็นได้ว่าภาพที่ติดปัญหาจะไม่ขึ้น ซึ่งเกิดมาจากการที่โหลดข้อมูลจาก origin อื่นที่ไม่ผ่าน CORS ทำให้ canvas นั้นเป็น taint ซึ่งจะส่งผลทางด้านความปลอดภัย แต่ก็สามารถแก้ได้ด้วยการใส่ allowTaint: true เพื่อเป็นการอนุญาตให้แสดงภาพที่เป็น taint ได้ ไปในส่วนของ option ดังตัวอย่างโค้ด

html2canvas(element, { allowTaint: false }).then((canvas) => {
  document.body.appendChild(canvas);
});

ซึ่งก็จะสามารถสร้าง canvas ที่มีภาพที่ติดปัญหาได้แล้ว แต่ถ้าหาก function ของเราเป็นการเซฟภาพลงเครื่องแล้วก็จะเจอกับ error DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported. ดังนั้นการตรวจสอบที่อยู่ไฟล์น่าจะเป็นทางออกที่ดีที่สุดครับ นอกจากนี้ก็ยังมีปัญหากับบางภาษา เช่น สระลอยในภาษาไทย

 

สรุปสุดท้ายสิ่งที่ผู้อ่านจะได้รับ

เป็นยังไงกันบ้างครับสำหรับการนำ HTML2Canvas มาเปลี่ยน HTML เป็น Canvas เรียกได้ว่าค่อนข้างง่ายไม่ซับซ้อนกันเลยทีเดียว แต่สำหรับ library ตัวนี้ทางผู้พัฒนาได้บอกไว้ว่ายังเป็น script สำหรับ experimental อยู่ แต่ก็ถือว่าเป็นทางเลือกหนึ่งสำหรับการนำ library นี้ไปปรับใช้กับโปรเจกต์ของเพื่อน ๆ ครับผม

 

อ้างอิงจาก

  1. HTML5 Canvas คืออะไร? + วิธีใช้งานเบื้องต้น, สืบค้นเมื่อ 18 กุมภาพันธ์ 2565 จาก: https://devahoy.com/blog/2015/02/html5-canvas-tutorial/
  2. html2canvas Screenshots with JavaScript, สืบค้นเมื่อ 14 กุมภาพันธ์ 2565 จาก: https://html2canvas.hertzen.com/
  3. Html2canvas configuration, สืบค้นเมื่อ 17 กุมภาพันธ์ 2565 จาก: https://html2canvas.hertzen.com/configuration
  4. html2canvas, สืบค้นเมื่อ 14 กุมภาพันธ์ 2565 จาก: https://www.npmjs.com/package/html2canvas
  5. Allowing cross-origin use of images and canvas, สืบค้นเมื่อ 17 กุมภาพันธ์ 2565 จาก: https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image

หากคุณสนใจพัฒนา สตาร์ทอัพ แอปพลิเคชัน
และ เทคโนโลยีของตัวเอง ?

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

BorntoDev

Author BorntoDev

BorntoDev Co., Ltd.

More posts by BorntoDev

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

ตั้งค่าความเป็นส่วนตัว

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

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

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

  • คุกกี้สำหรับการติดตามทางการตลาด

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

บันทึกการตั้งค่า