5 điểm bởi GN⁺ 2024-04-26 | 1 bình luận | Chia sẻ qua WhatsApp
  • Cách cài đặt

    • Có thể cài dưới dạng module thông qua NPM
      npm install --save canvas-confetti
      
    • Có thể dùng trong dự án bằng require('canvas-confetti')
    • Vì là component phía client nên không chạy trên Node. Cần build dự án bằng webpack hoặc công cụ tương tự
    • Có thể nhúng trực tiếp vào trang HTML thông qua CDN
      <script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/…;
      
    • Khi đưa vào dự án, nên dùng phiên bản mới nhất từ trang releases
  • Chế độ giảm animation

    • Một số người dùng không thích chuyển động, nên cần cân nhắc điều này
    • Có thể dùng tùy chọn disableForReducedMotion để hỗ trợ những người dùng không muốn animation gây rối mắt
    • Mặc định đang tắt, nhưng dự kiến sẽ thay đổi giá trị mặc định trong bản phát hành major sau này

API

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

    • Nhận một đối tượng tùy chọn duy nhất làm tham số
    • Nếu dùng được window.Promise thì trả về Promise, nếu không dùng được (như IE) thì trả về null
    • Có thể cung cấp implementation Promise thông qua polyfill hoặc confetti.Promise
    • Nếu gọi confetti nhiều lần trước khi hoàn tất thì sẽ trả về cùng một Promise. Nội bộ tái sử dụng cùng một phần tử canvas
    • Khi mọi animation kết thúc, Promise trả về từ mỗi lần gọi sẽ được resolve
    • Các thuộc tính chính của đối tượng options
      • particleCount, angle, spread, startVelocity, decay, gravity, drift, ticks, origin, colors, shapes, scalar, zIndex v.v.
  • confetti.shapeFromPath({ path, matrix? })Shape

    • Tạo hình confetti tùy chỉnh bằng chuỗi SVG Path
    • Chỉ hỗ trợ màu đơn, chưa hỗ trợ Stroke
    • Cần ma trận biến đổi. Có thể truyền trực tiếp hoặc tính bằng helper
    • Chỉ dùng được trên trình duyệt hỗ trợ Path2D
    • Trả về đối tượng Shape
  • confetti.shapeFromText({ text, scalar?, color?, fontFamily? })Shape

    • Tính năng để render confetti emoji
    • Khuyến nghị dùng một ký tự đơn, đặc biệt là emoji
    • Vì văn bản được raster hóa nên không phù hợp để đổi kích thước sau khi tạo
    • Khi đổi kích thước bằng scalar thì cũng cần dùng cùng giá trị tại đây
    • Các tùy chọn text, scalar, color, fontFamily
  • confetti.create(canvas, [globalOptions])function

    • Tạo một instance của hàm confetti dùng canvas tùy chỉnh
    • Có thể giới hạn kích thước của canvas
    • Tùy chọn toàn cục
      • resize : thiết lập kích thước ảnh canvas và có giữ nguyên khi kích thước cửa sổ thay đổi hay không
      • useWorker : có dùng web worker bất đồng bộ để render nếu khả dụng hay không
      • disableForReducedMotion : có vô hiệu hóa hoàn toàn confetti với người dùng bật chế độ giảm animation hay không
    • Lưu ý khi dùng useWorker: true
      • Không được thao tác trực tiếp với canvas. Quyền điều khiển sẽ được chuyển cho web worker
  • confetti.reset()

    • Dừng animation và xóa toàn bộ confetti
    • Resolve ngay các Promise chưa được giải quyết
    • Instance tạo bằng confetti.create có phương thức reset riêng

Ví dụ sử dụng

  • Cách dùng cơ bản

    confetti();
    
  • Dùng nhiều confetti

    confetti({
      particleCount: 150
    });  
    
  • Tung rộng hơn

    confetti({
      spread: 180
    });
    
  • Bắn một lượng nhỏ từ vị trí ngẫu nhiên

    confetti({
      particleCount: 100, 
      startVelocity: 30,
      spread: 360,
      origin: { 
        x: Math.random(),  
        y: Math.random() - 0.2
      }
    });
    
  • Bắn liên tục từ nhiều hướng trong 30 giây

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

Ý kiến của GN⁺

  • canvas-confetti có vẻ là một thư viện gọn nhẹ giúp áp dụng hiệu ứng confetti lên trang web một cách dễ dàng. Nó hỗ trợ cả cài đặt qua NPM lẫn dùng qua CDN, nên khá tiện cho lập trình viên.

  • Thư viện hỗ trợ nhiều thiết lập cho hiệu ứng confetti nên rất linh hoạt. Có thể tự do điều chỉnh số lượng confetti, độ lan tỏa, kích thước, hình dạng, màu sắc... để tạo ra nhiều bầu không khí khác nhau.

  • Việc có thể tạo confetti với hình dạng tùy chỉnh bằng văn bản hoặc SVG path là một điểm thú vị. Đặc biệt, confetti dùng emoji là một ý tưởng khá vui nhộn.

  • Khả năng dùng Web Worker để chạy animation mà không chặn main thread cũng là một ưu điểm. Tuy vậy, đổi lại thì không thể điều khiển trực tiếp canvas trong trường hợp này.

  • Việc hỗ trợ chế độ giảm chuyển động để quan tâm tới những người dùng nhạy cảm với animation là một điểm tích cực về mặt khả năng truy cập web. Theo đó, ở các phiên bản tương lai chế độ này được dự kiến sẽ bật mặc định, nên cần lưu ý.

  • Nhìn chung đây có vẻ là một thư viện dễ dùng và cung cấp nhiều tùy chọn. Nó phù hợp cho các trang chúc mừng, game hoặc những nơi cần tạo không khí vui nhộn. Tuy nhiên, nếu lạm dụng thì có thể ảnh hưởng xấu tới trải nghiệm người dùng, nên nên sử dụng ở mức hợp lý.

1 bình luận

 
GN⁺ 2024-04-26
Ý kiến Hacker News
  • Mẹo để có hoạt ảnh hiệu năng tốt là vẽ trên canvas và đặt canvas lên trên tất cả các phần tử khác, nhưng vô hiệu hóa sự kiện con trỏ trên canvas để vẫn có thể tương tác với trang
  • Tôi vẫn nhớ khoảng thời gian vui vẻ khi làm web từ hồi còn học cấp 3 vào năm 2015. Tôi đã tạo một hoạt ảnh tung giấy màu trên một trang web nhỏ để mời một cô gái đến buổi homecoming cùng mình (nghĩ lại thì khá mọt sách). Có một thời, việc tạo website khi còn nhỏ khiến tôi cảm thấy như mình có siêu năng lực
  • Tôi rất thích những dự án nhỏ được làm chỉ vì niềm vui. Đó là lý do tôi bắt đầu lập trình và đến giờ vẫn là động lực của tôi
  • Nếu đổi số lượng hạt trên trang demo lên khoảng 400, bạn sẽ thấy một cảnh khá đáng thất vọng: đám giấy màu trông như một "hình nón phẳng" đồng đều. Nó quá hoàn hảo nên làm vỡ mất ảo giác
  • Sự chú ý đến kiểu chi tiết này khá hiếm trong thế giới, từ trực quan hóa thống kê đến đạo cụ phim ảnh hay giấy màu trên website, nên hễ bắt gặp ở đâu tôi cũng rất trân trọng
  • Tôi đoán phân bố thực tế sẽ gần với Gaussian, và giải pháp có lẽ là trực tiếp thay đổi phân bố ngẫu nhiên
  • Không chỉ là một thư viện hay và hữu ích, đây còn là một ví dụ tốt về "mô-đun sâu" mà John Ousterhout nói đến trong 'Triết lý thiết kế phần mềm'
  • Phiên bản thư viện cơ bản nhất (gọi giấy màu) rất dễ dùng, nhưng bạn cũng có thể khai thác được rất nhiều khi khám phá các tùy chọn được đưa ra (tuyết, màu sắc cụ thể, nhiều hiệu ứng giấy màu khác nhau, v.v.)
  • Tôi đã thêm hiệu ứng giấy màu vào dashboard quản trị của đội sales khi chốt được đơn, và thật bất ngờ là nó mang lại cảm giác vui vẻ và tạo động lực
  • Dù ấn tượng và ngầu, tôi lại không muốn thấy nó chạy trên các website mình dùng. Đặc biệt là tôi không muốn giấy màu bắn ra khi popup newsletter xuất hiện hoặc khi thêm sản phẩm vào giỏ hàng
  • Giá mà hàm reset được đặt tên là confetti.resetti()
  • Vài năm trước tôi đã làm một hoạt ảnh tương tự như một phần của sản phẩm. Luồng đó là khi người dùng mới đăng ký và lần đầu dùng sản phẩm để tạo ra một kết quả cụ thể thì hiệu ứng giấy màu sẽ xuất hiện. Các quản lý sản phẩm thấy nó vui nhộn và mới mẻ nên còn khoe với lãnh đạo, nhưng sau đó qua review UX và kiểm thử accessibility thì cuối cùng nó bị gỡ khỏi sản phẩm. Dùng để demo thì vui, nhưng với người dùng có thể lại gây khó chịu
  • Cũng có thư viện Party.js: https://party.js.org/
  • Tôi còn nhớ cảm giác kinh ngạc khi thêm hiệu ứng tuyết rơi vào một trang thương mại điện tử khoảng năm 2005. Nó cho thấy chúng ta đã đi xa đến mức nào (ít nhất là ở vài khía cạnh!)