5 คะแนน โดย GN⁺ 2024-04-26 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • วิธีติดตั้ง

    • ติดตั้งเป็นโมดูลผ่าน NPM ได้
      npm install --save canvas-confetti
      
    • ใช้งานในโปรเจกต์ได้ด้วย require('canvas-confetti')
    • เนื่องจากเป็นคอมโพเนนต์ฝั่งไคลเอนต์ จึงไม่ทำงานบน Node ต้องบิลด์โปรเจกต์ด้วย webpack เป็นต้น
    • สามารถใส่ลงในหน้า HTML ได้โดยตรงผ่าน CDN
      <script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/…;
      
    • เมื่อนำไปใช้ในโปรเจกต์ แนะนำให้ใช้เวอร์ชันล่าสุดจากหน้า releases
  • โหมดลดแอนิเมชัน

    • ผู้ใช้บางคนไม่ชอบการเคลื่อนไหว จึงควรคำนึงถึงเรื่องนี้
    • สามารถดูแลผู้ใช้ที่ไม่ต้องการแอนิเมชันที่รบกวนสายตาได้ด้วยตัวเลือก disableForReducedMotion
    • โดยค่าเริ่มต้นจะปิดอยู่ แต่มีแผนจะเปลี่ยนค่าเริ่มต้นในเมเจอร์รีลีสถัดไป

API

  • confetti([options {Object}])Promise|null

    • รับอ็อบเจ็กต์ตัวเลือกเพียงตัวเดียวเป็นพารามิเตอร์
    • หากใช้ window.Promise ได้ จะคืนค่า Promise และหากใช้ไม่ได้ (เช่น IE) จะคืนค่า null
    • สามารถส่ง implementation ของ Promise ผ่าน Polyfill หรือ confetti.Promise ได้
    • หากเรียก confetti หลายครั้งก่อนเสร็จ จะคืน Promise เดิม และภายในจะใช้ element canvas เดิมซ้ำ
    • เมื่อแอนิเมชันทั้งหมดเสร็จสิ้น Promise ที่คืนจากแต่ละการเรียกจะถูก resolve
    • พร็อพเพอร์ตีหลักของอ็อบเจ็กต์ options
      • particleCount, angle, spread, startVelocity, decay, gravity, drift, ticks, origin, colors, shapes, scalar, zIndex เป็นต้น
  • confetti.shapeFromPath({ path, matrix? })Shape

    • สร้างรูปทรง confetti แบบกำหนดเองด้วยสตริง SVG Path
    • รองรับเฉพาะสีเดียว และยังไม่รองรับ Stroke
    • ต้องใช้เมทริกซ์การแปลง สามารถส่งมาเองหรือคำนวณด้วย helper ก็ได้
    • ใช้ได้เฉพาะเบราว์เซอร์ที่รองรับ Path2D
    • คืนค่าอ็อบเจ็กต์ Shape
  • confetti.shapeFromText({ text, scalar?, color?, fontFamily? })Shape

    • ฟีเจอร์สำหรับเรนเดอร์ confetti แบบอีโมจิ
    • แนะนำให้ใช้ตัวอักษรเดี่ยว โดยเฉพาะอีโมจิ
    • เนื่องจากข้อความจะถูกแปลงเป็นแรสเตอร์ จึงไม่เหมาะกับการปรับขนาดหลังจากสร้างแล้ว
    • หากปรับขนาดด้วย scalar ต้องใช้ค่าเดียวกันที่นี่ด้วย
    • ตัวเลือก text, scalar, color, fontFamily
  • confetti.create(canvas, [globalOptions])function

    • สร้างอินสแตนซ์ของฟังก์ชัน confetti ที่ใช้ canvas แบบกำหนดเอง
    • สามารถจำกัดขนาดของ canvas ได้
    • ตัวเลือกแบบโกลบอล
      • resize : ตั้งค่าขนาดภาพของ canvas และจะคงไว้เมื่อขนาดหน้าต่างเปลี่ยนหรือไม่
      • useWorker : จะใช้ asynchronous web worker สำหรับการเรนเดอร์เมื่อเป็นไปได้หรือไม่
      • disableForReducedMotion : จะปิดการทำงานของ confetti ทั้งหมดหรือไม่สำหรับผู้ใช้ที่เปิดโหมดลดแอนิเมชัน
    • ข้อควรระวังเมื่อใช้ useWorker: true
      • ห้ามจัดการ canvas โดยตรง เพราะสิทธิ์ควบคุมจะถูกย้ายไปยัง web worker
  • confetti.reset()

    • หยุดแอนิเมชันและลบ confetti ทั้งหมด
    • resolve Promise ที่ยังไม่ถูก resolve ทันที
    • อินสแตนซ์ที่สร้างด้วย confetti.create จะมีเมธอด reset ของตัวเอง

ตัวอย่างการใช้งาน

  • การใช้งานพื้นฐาน

    confetti();
    
  • ใช้ confetti จำนวนมาก

    confetti({
      particleCount: 150
    });  
    
  • กระจายให้กว้าง

    confetti({
      spread: 180
    });
    
  • ยิงปริมาณน้อยจากตำแหน่งแบบสุ่ม

    confetti({
      particleCount: 100, 
      startVelocity: 30,
      spread: 360,
      origin: { 
        x: Math.random(),  
        y: Math.random() - 0.2
      }
    });
    
  • ยิงต่อเนื่องจากหลายทิศทางเป็นเวลา 30 วินาที

    var duration = 30 * 1000;
    var end = Date.now() + duration;
    
    (function frame() {
      confetti({
        particleCount: 7,
        angle: 60, 
        spread: 55,
        origin: { x: 0 }
      });
    
      confetti({  
        particleCount: 7,
        angle: 120,
        spread: 55, 
        origin: { x: 1 }
      });
    
      if (Date.now() < end) {
        requestAnimationFrame(frame);
      }
    }());
    

ความเห็นของ GN⁺

  • canvas-confetti ดูเป็นไลบรารีขนาดเบาที่ช่วยใส่เอฟเฟกต์คอนเฟตตีลงในเว็บเพจได้ง่าย รองรับทั้งการติดตั้งผ่าน NPM และการใช้งานผ่าน CDN จึงดูสะดวกสำหรับนักพัฒนา

  • รองรับการตั้งค่าเอฟเฟกต์คอนเฟตตีได้หลากหลาย จึงมีความยืดหยุ่นสูง สามารถปรับจำนวนคอนเฟตตี ระดับการกระจาย ขนาด รูปทรง สีสัน ฯลฯ ได้อย่างอิสระ น่าจะเหมาะกับการสร้างบรรยากาศได้หลายแบบ

  • การสร้างคอนเฟตตีรูปทรงกำหนดเองด้วยข้อความหรือ SVG path ก็น่าสนใจ โดยเฉพาะคอนเฟตตีที่ใช้อีโมจิถือเป็นไอเดียที่สนุกดี

  • การใช้ Web Worker เพื่อรันแอนิเมชันโดยไม่บล็อกเมนเธรดก็ดูเป็นข้อดี อย่างไรก็ตาม ในกรณีนี้จะไม่สามารถควบคุม canvas โดยตรงได้ จึงมี trade-off อยู่

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

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

1 ความคิดเห็น

 
GN⁺ 2024-04-26
ความคิดเห็นจาก Hacker News
  • เคล็ดลับของแอนิเมชันที่มีประสิทธิภาพคือวาดลงบนแคนวาส แล้ววางแคนวาสไว้เหนือองค์ประกอบอื่นทั้งหมด แต่ปิดการทำงานของ pointer events บนแคนวาสเพื่อให้ยังโต้ตอบกับหน้าเว็บได้
  • ยังจำได้ว่าตอนสมัยมัธยมปลายในปี 2015 เคยสนุกกับการทำเว็บมาก ขนาดทำแอนิเมชันโปรยกระดาษสีบนเว็บเล็ก ๆ เพื่อชวนผู้หญิงไปงานโฮมคัมมิงด้วยกัน (มองย้อนกลับไปตอนนี้ก็ดูเนิร์ดดี) มีช่วงหนึ่งในวัยเด็กที่การสร้างเว็บไซต์ให้ความรู้สึกเหมือนมีพลังวิเศษ
  • ชอบโปรเจกต์เล็ก ๆ ที่ทำเพื่อความสนุกเพียงอย่างเดียว นั่นคือเหตุผลที่เริ่มเขียนโปรแกรม และก็ยังเป็นแรงผลักดันอยู่จนถึงตอนนี้
  • ถ้าปรับจำนวนอนุภาคในหน้าเดโมเป็นราว 400 ชิ้น จะเห็นภาพน่าผิดหวังที่กระดาษสีดูเป็นทรง "กรวยแบน" อย่างสม่ำเสมอเกินไป ซึ่งดูสมบูรณ์แบบเกินจนทำลายภาพลวงตา
  • ไม่ค่อยพบเห็นความใส่ใจในรายละเอียดแบบนี้ในโลกมากนัก ไม่ว่าจะเป็นงานทำภาพข้อมูลประกอบสถิติ อุปกรณ์ประกอบฉากภาพยนตร์ หรือกระดาษสีบนเว็บไซต์ ดังนั้นพอเจอที่ไหนก็รู้สึกชื่นชม
  • คาดว่าการกระจายจริงน่าจะใกล้เคียงแบบ Gaussian และทางแก้ก็น่าจะเป็นการปรับการกระจายแบบสุ่มโดยตรง
  • นอกจากจะเป็นไลบรารีที่เท่และมีประโยชน์แล้ว ยังเป็นตัวอย่างที่ดีของ "deep module" ตามที่ John Ousterhout กล่าวไว้ใน 'A Philosophy of Software Design' อีกด้วย
  • เวอร์ชันพื้นฐานที่สุดของไลบรารีนี้ (เรียกกระดาษสีออกมา) ใช้งานง่ายมาก แต่พอไล่ดูตัวเลือกต่าง ๆ ที่มีให้ (หิมะ สีเฉพาะ เอฟเฟกต์กระดาษสีหลายแบบ ฯลฯ) ก็จะได้อะไรเพิ่มขึ้นอีกมาก
  • เคยเพิ่มเอฟเฟกต์กระดาษสีลงในแดชบอร์ดผู้จัดการของฝ่ายขายตอนมีการขายเกิดขึ้น ซึ่งน่าแปลกที่มันทั้งสนุกและช่วยสร้างแรงจูงใจ
  • แม้จะน่าประทับใจและเท่มาก แต่ก็ไม่อยากเห็นมันทำงานบนเว็บไซต์ที่ตัวเองใช้อยู่ โดยเฉพาะไม่อยากได้กระดาษสีเด้งขึ้นมาตอนป๊อปอัปจดหมายข่าวหรือเวลาหยิบสินค้าใส่รถเข็น
  • อยากให้ตั้งชื่อฟังก์ชันรีเซ็ตว่า confetti.resetti()
  • เมื่อหลายปีก่อนเคยทำแอนิเมชันคล้ายกันเป็นส่วนหนึ่งของผลิตภัณฑ์ เป็นโฟลว์ที่เมื่อผู้ใช้ใหม่สมัครและใช้ผลิตภัณฑ์ครั้งแรกเพื่อสร้างผลลัพธ์บางอย่างสำเร็จ ก็จะแสดงแอนิเมชันกระดาษสี ผู้จัดการผลิตภัณฑ์มองว่ามันสนุกและสดใหม่จนเอาไปอวดผู้บริหาร แต่หลังจากผ่านการรีวิว UX และการทดสอบการเข้าถึง สุดท้ายก็ถูกถอดออกจากผลิตภัณฑ์ สนุกดีเวลาเอาไปเดโม แต่สำหรับผู้ใช้อาจน่ารำคาญได้
  • ยังมีไลบรารี Party.js ด้วย: https://party.js.org/
  • ยังจำความรู้สึกทึ่งตอนใส่เอฟเฟกต์หิมะตกลงไปในเว็บอีคอมเมิร์ซราวปี 2005 ได้ดี มันแสดงให้เห็นว่าเรามาไกลแค่ไหนแล้ว (อย่างน้อยก็ในบางแง่!)