5 पॉइंट द्वारा GN⁺ 2024-04-26 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • canvas-confetti वेब पेज पर canvas-आधारित confetti animation चलाने के लिए एक client-side लाइब्रेरी है, जो NPM इंस्टॉलेशन और CDN direct include दोनों को सपोर्ट करती है
  • बेसिक confetti() API एक options object के जरिए particle count, angle, spread, velocity, gravity, color, shape, position, z-index आदि को adjust करती है, और Promise सपोर्ट वाले environment में animation पूरा होने का समय भी दिया जा सकता है
  • Reduced Motion यूज़र्स के लिए disableForReducedMotion option दिया गया है; इसका डिफ़ॉल्ट मान अभी false है, लेकिन भविष्य की किसी major release में यह बदल सकता है
  • SVG Path और text-आधारित custom shapes बनाई जा सकती हैं, और square, circle, star जैसी बेसिक shapes के अलावा emoji confetti जैसे effect भी बनाए जा सकते हैं
  • confetti.create() किसी खास canvas पर instance बनाता है और resize, useWorker जैसे global options को सपोर्ट करता है, लेकिन useWorker: true में canvas का control web worker को चला जाता है, इसलिए main thread से उसे modify करने पर error होगा

इंस्टॉलेशन और चलाने के तरीके

  • demo page पर लाइब्रेरी का काम देख सकते हैं
  • इसे NPM package के रूप में install किया जा सकता है
npm install --save canvas-confetti
  • प्रोजेक्ट build में इसे require('canvas-confetti') से इस्तेमाल किया जा सकता है
  • यह लाइब्रेरी एक client component है और Node में नहीं चलती
    • README बताता है कि प्रोजेक्ट को webpack जैसे टूल से build करना होगा
  • HTML पेज में इसे CDN script के जरिए सीधे include किया जा सकता है
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/…;
  • CDN इस्तेमाल करते समय प्रोजेक्ट में include करते वक्त उपलब्ध latest version इस्तेमाल करने की सलाह दी जाती है; सभी versions releases page पर देखे जा सकते हैं

Reduced Motion सपोर्ट

  • कुछ यूज़र वेबसाइट पर movement नहीं चाहते या उसे कम पसंद करते हैं, और browser इसे prefers-reduced-motion के जरिए बता सकता है
  • disableForReducedMotion option इस्तेमाल करने पर ऐसे यूज़र्स के लिए confetti नहीं दिखाया जा सकता जिन्हें भ्रमित करने वाले animation से दिक्कत हो सकती है
  • इस option का मौजूदा default false है
  • भविष्य की major release में इसका default बदलने पर विचार किया जा रहा है; अगर आपकी मजबूत राय है तो issue के रूप में बता सकते हैं
  • अगर disableForReducedMotion लागू होने से confetti disable हो जाता है, तो confetti() Promise तुरंत resolve हो जाता है

बेसिक API और Promise व्यवहार

  • NPM install होने पर प्रोजेक्ट build में इसे client component की तरह require किया जा सकता है, और CDN version में यह window के confetti function के रूप में expose होता है
  • confetti([options]) एक optional options object लेता है
  • अगर window.Promise मौजूद है, तो यह animation पूरा होने की सूचना देने वाला Promise लौटाता है
    • Promise न होने वाले IE जैसे environment में यह null लौटाता है
    • Promise polyfill इस्तेमाल किया जा सकता है
    • confetti.Promise = MyPromise के रूप में Promise implementation सीधे दी जा सकती है
  • पूरा होने से पहले confetti को कई बार call करने पर हर बार वही Promise लौटता है
  • अंदरूनी तौर पर वही canvas element reuse होता है, और मौजूदा animation जारी रखते हुए नया confetti जोड़ दिया जाता है
  • हर call से लौटा Promise सभी animations खत्म होने के बाद resolve होता है

मुख्य options

  • particleCount: launch किए जाने वाले confetti की संख्या, default 50
  • angle: launch angle, default 90, जहाँ 90 ऊपर की दिशा है
  • spread: केंद्र से फैलाव की सीमा, default 45
  • startVelocity: शुरुआती velocity, default 45
  • decay: velocity घटने की दर, default 0.9
    • इसे 0 और 1 के बीच रखना चाहिए; range से बाहर होने पर velocity बढ़ भी सकती है
  • gravity: particles को नीचे खींचने की मात्रा, default 1
    • 0.5 आधी gravity है, और इसकी कोई सीमा नहीं है, इसलिए इसे ऊपर उठने जैसा भी बनाया जा सकता है
  • drift: बाएँ-दाएँ बहाव की मात्रा, default 0
    • negative का मतलब बाएँ, positive का मतलब दाएँ
  • flat: असली 3D confetti की तरह tilt और wobble effect को बंद कर सकता है; default false
  • ticks: confetti कितनी बार move करेगा, default 200
  • origin: launch की शुरुआती position
    • origin.x: पेज पर x position, 0 बायाँ, 1 दायाँ, default 0.5
    • origin.y: पेज पर y position, 0 ऊपर, 1 नीचे, default 0.5
  • colors: HEX format color strings की array
  • shapes: confetti shapes की array
    • built-in default values square, circle, star हैं
    • default रूप से square और circle बराबर अनुपात में मिलाए जाते हैं
    • ['circle', 'circle', 'square'] जैसी array ratio से mix proportion बदला जा सकता है
  • scalar: हर particle का scale, default 1
  • zIndex: confetti display layer, default 100
  • disableForReducedMotion: Reduced Motion preference वाले यूज़र्स के लिए confetti disable करता है

custom shapes बनाना

  • confetti.shapeFromPath({ path, matrix? }) SVG Path string से custom confetti shape बनाता है
  • Path-आधारित shapes पर कुछ सीमाएँ हैं
    • सभी path को filled shape की तरह treat किया जाता है; stroke path implement नहीं है
    • path एक single color तक सीमित है
    • हर path के लिए valid transform matrix ज़रूरी है
    • matrix calculate करना महँगा हो सकता है, इसलिए development के दौरान हर path के लिए एक बार calculate करके cache करना बेहतर है
    • वही path value होने पर matrix हमेशा एक जैसा रहेगा
    • लाइब्रेरी update होने पर forward compatibility के लिए matrix को फिर से generate करके cache करना बेहतर है
    • path-आधारित confetti उन्हीं browsers तक सीमित है जो Path2D को सपोर्ट करते हैं
  • return value एक Shape object होती है, जिसे सीधे shapes array में डालकर इस्तेमाल किया जा सकता है
var triangle = confetti.shapeFromPath({ path: 'M0 10 L5 0 L10 10z' });

confetti({
  shapes: [triangle]
});
  • confetti.shapeFromText({ text, scalar?, color?, fontFamily? }) text-आधारित confetti shape बनाता है, और standard Unicode emoji इस्तेमाल किए जा सकते हैं
  • text-आधारित shapes emoji confetti के लिए उपयुक्त हैं
    • wobble करने वाले confetti में आम तौर पर square-जैसे single character, खासकर emoji, बेहतर काम करते हैं
    • text को हर बार draw नहीं किया जाता बल्कि rasterize किया जाता है, इसलिए shape बनने के बाद scale बहुत बदलने पर वह blurry हो सकता है
    • अगर confetti options में scalar इस्तेमाल करना है, तो shape बनाते समय भी वही scalar value देना बेहतर है
  • text options में text, scalar, color, fontFamily दिए जाते हैं
    • fontFamily का default native OS emoji rendering convention को follow करता है और sans-serif को fallback के रूप में इस्तेमाल करता है
    • web font इस्तेमाल करते समय confetti render होने से पहले font load हो चुका होना चाहिए
var scalar = 2;
var pineapple = confetti.shapeFromText({ text: '🍍', scalar });

confetti({
  shapes: [pineapple],
  scalar
});

custom canvas और worker rendering

  • confetti.create(canvas, [globalOptions]) किसी खास canvas का इस्तेमाल करने वाला confetti function instance बनाता है
  • यह तब उपयोगी है जब confetti को पेज के सिर्फ किसी खास हिस्से तक सीमित रखना हो
  • डिफ़ॉल्ट रूप से यह method canvas पर draw करने के अलावा canvas को modify नहीं करता
  • canvas में CSS से display size बदलने पर असली canvas image size नहीं बदलती, इसलिए वह खिंचा हुआ और blurry दिख सकता है
    • resize option on करने पर लाइब्रेरी canvas image size को match करती है, और window resize या mobile rotation पर भी उसे maintain करती है
  • एक ही canvas element पर confetti instance को कई बार initialize नहीं करना चाहिए; बनाए गए custom instance को बनाए रखना चाहिए
  • global options

    • resize: canvas image size सेट करे और window changes के साथ उसे बनाए रखे या नहीं, default false
    • useWorker: जहाँ संभव हो, async web worker में confetti animation render करता है, default false
    • default स्थिति में animation हमेशा main thread पर चलता है
    • अगर browser सपोर्ट करता है, तो animation main thread के बाहर चल सकता है ताकि main thread block न हो
    • unsupported browsers में इस value को ignore कर दिया जाता है
    • disableForReducedMotion: इस confetti instance को यूज़र की Reduced Motion request का हमेशा सम्मान करने देता है
  • useWorker: true सावधानियाँ

    • useWorker: true इस्तेमाल करने पर canvas का control web worker को transfer हो जाता है
    • इस स्थिति में canvas को DOM से हटाने के अलावा main thread से उसे modify करने पर error होगा
    • अगर canvas को सीधे modify करना है, तो useWorker option इस्तेमाल नहीं करना चाहिए
    var myCanvas = document.createElement('canvas');
    document.body.appendChild(myCanvas);
    
    var myConfetti = confetti.create(myCanvas, {
      resize: true,
      useWorker: true
    });
    myConfetti({
      particleCount: 100,
      spread: 160
    });
    

animation रोकना और example patterns

  • confetti.reset() animation रोकता है, सारे confetti हटाता है, और pending Promise को तुरंत resolve कर देता है
  • confetti.create() से बने अलग instance का अपना reset method होता है
confetti();

setTimeout(() => {
  confetti.reset();
}, 100);
  • बेसिक execution में बिना argument के confetti() call किया जाता है
  • particleCount: 150 के साथ बहुत सारा confetti launch किया जा सकता है
  • spread: 180 से wide-spread confetti बनाया जा सकता है
  • origin में Math.random() इस्तेमाल करने पर पेज पर random position से छोटे explosion effect बनाए जा सकते हैं
  • README example requestAnimationFrame का इस्तेमाल करके 30 सेकंड तक बाएँ और दाएँ किनारों से लगातार confetti launch करने वाला pattern दिखाता है

1 टिप्पणियां

 
GN⁺ 2024-04-26
Hacker News की राय
  • यहां बेहतर performance वाली animation बनाने की तरकीब यह है कि canvas पर draw करें, फिर उस canvas को बाकी सभी elements के सामने रखें, लेकिन pointer events बंद कर दें ताकि page के साथ interaction जारी रह सके

    • सही. pointer events disable करना उम्मीद से ज़्यादा काम आता है
    • इसे बेहतर performance वाली animation की तरकीब कहा गया है, लेकिन इसे implement करने का कोई और तरीका मुझे तुरंत सूझ नहीं रहा. कोई naive implementation कैसी दिखेगी?
  • 2015 में high school में web development करने के अच्छे दिन याद आ गए. homecoming पर साथ चलने के लिए एक लड़की से पूछने के लिए मैंने confetti वाला छोटा website बनाया था, पीछे मुड़कर देखूं तो काफी nerdy था
    उस समय किसी बच्चे के लिए website बनाना superpower जैसा लगता था. timing के हिसाब से शायद यह package नहीं था, लेकिन animation काफी अच्छी थी
    मुझे ऐसे पूरी तरह मज़ेदार छोटे projects पसंद हैं. programming शुरू करने की वजह भी यही थी, और आज भी यह मेरे लिए बड़ी प्रेरणा है

    • काम बना? उसने yes कहा?
  • demo page का यह हिस्सा अच्छा लगा:

    If you happened to get curious and changed the particle count to 400 or so, you saw something disappointing. An even "flattened cone" look to the confetti, making it look way too perfect and ruining the illusion.

    ऐसी details को लेकर obsession दुर्लभ है, और चाहे statistical visualization हो, film props हों या website confetti, जब भी यह दिखता है तो बहुत कीमती लगता है
    solution के तौर पर मैं random distribution को ही बदलकर देखता. असल में verify तो करता, लेकिन अंदाज़ा है कि real-world distribution शायद Gaussian distribution के करीब होगा

  • जब sales rep कोई sale close करता है तो दिखने वाला admin dashboard confetti जोड़ा था, और यह आश्चर्यजनक रूप से मज़ेदार और motivating है

  • reset function को confetti.resetti() कहा होता तो अच्छा होता

    • JavaScript है, इसलिए कम-से-कम local पर "confetti.resetti = confetti.reset" से इसे आसानी से ठीक किया जा सकता है
      इस approach की थोड़ी software engineering cost तो होगी, लेकिन जैसा कि कोई भी सावधान observer साफ़ देख सकता है, फायदा भारी है, इसलिए मेरे हिसाब से कर ही देना चाहिए
    • इस इंसान को job मिलनी चाहिए. अगर पहले से job है तो कम-से-कम cookie तो देनी चाहिए
    • PR भी बनाया जा सकता है
  • cool और useful library होने से अलग, यह John Ousterhout की Philosophy of Software Design में बताए गए deep module का अच्छा example है
    सबसे basic version, यानी confetti summon करने वाला feature, इस्तेमाल में बहुत आसान है, लेकिन options देखें तो snow, specific colors, अलग-अलग confetti effects जैसी काफी चीज़ें मिलती हैं

  • बढ़िया और impressive है
    साथ ही, मैं इसे अपने इस्तेमाल वाले किसी भी website पर चलते हुए नहीं देखना चाहता. खासकर newsletter popup या cart में item डालते समय confetti साथ आए, यह नहीं चाहिए

    • अजीब बात है कि इस effect को काफी effective ढंग से इस्तेमाल किया जा सकता है. ऐसे full-screen तरीके का तो पता नहीं, लेकिन हाल में जिस client के यहां गया था, उनके project management software में item close करने पर button green हो जाता था और ऐसा effect आता था
      subtle था, लेकिन दिखने लायक था, और meeting के बाद एक दूसरे developer और मैंने दोनों ने कहा, “काफी ठीक effect था.” इससे “अच्छा, progress हो रही है!” वाला feel आता था
      बस इसे optional बना देना चाहिए

    • legitimate use case शायद YouTube के like button जैसा होगा. बढ़िया animation है, और mobile app में device भी vibrate करता है. बहुत pleasant user experience है

    • https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pref...

      browser में motion reduce prefer करने की setting कर सकते हैं. site operators और library maintainers को confetti जैसी चीज़ implement करते समय इसका सम्मान करना चाहिए. इस library में खास तौर पर disableForReducedMotion option है

    • कुछ जगहों पर ऐसे effects fit बैठते हैं. जैसे game complete होने पर

    • हम इस library का उपयोग तब करते हैं जब कोई व्यक्ति कोई particular qualification पूरी करता है. onboarding flow में इसका काफी अच्छा असर पड़ता है

  • Party.js library भी है: https://party.js.org/

    • तो कौन-सी छोटी है?
      10.4 kB minified, 4.2kB minified + Gzip
      https://bundlephobia.com/package/canvas-confetti@1.9.2

      28.3kB minified, 7.4kB minified + Gzip
      https://bundlephobia.com/package/party-js@2.2.0

      हालांकि bundlephobia कैसे काम करता है, यह मुझे ठीक से नहीं पता. हो सकता है यह package का final size सबसे अच्छे से न दिखाता हो. शायद code splitting या सिर्फ ज़रूरी चीज़ें import करने के तरीके को reflect नहीं करता. मैं इसे बस एक तेज़ और rough overview की तरह देख रहा हूं

      Gzip के हिसाब से confetti कुछ KB से जीतता दिखता है, इसलिए अगर उन कुछ KB को squeeze करना ज़रूरी नहीं है, तो कौन-से features चाहिए इस पर निर्भर करते हुए दोनों चल सकते हैं

    • original post का script mobile पर कहीं ज़्यादा performant दिखता है

    • original post वाली library काफी ज़्यादा performant लगती है. मेरे पुराने work computer पर Party.js में सिर्फ 3 clicks के बाद ही हल्का delay महसूस होता है
      canvas-confetti में delay तब शुरू हुआ जब मैंने कई seconds तक लगातार click किया और शायद 30 से ज़्यादा confetti instances और बहुत सारे particles बना दिए

  • downforacross.com पर crossword solve करता हूं, और puzzle solve होने पर confetti निकलता है
    इसे हल्का महसूस कराने के लिए यहां के ज़्यादा performant code का कुछ हिस्सा इस्तेमाल किया जा सकता है
    लेकिन अगर यह “fun” site या rare use नहीं है, तो ऐसी animations हर जगह दिखना मुझे पसंद नहीं होगा

  • title में useful डालने की खास ज़रूरत नहीं लगती

    • motivation tool और code compile हुआ या नहीं यह check करने के साधन के तौर पर कैसा है: https://squint-cljs.github.io/squint/
    • सही. फिर भी उसी word की वजह से सच में interest जगा, और असल में यह बहुत useful नहीं था इसलिए मज़ा आया. recommend करता हूं
    • real-world confetti जितना useful है, यानी 100% useful