हमारे होम पेज पर फेंके जा सकने वाले ऐप आइकन

हमारे होम पेज पर एक बॉक्स है, जिसमें हमारे ऐप के आइकन रखे हैं। आपके पेज पर आते ही वे ऊपर से गिरते हैं, और आप उन्हें उठाकर फेंक सकते हैं। किसी आइकन को बिना खींचे टैप करें, तो उस ऐप का पेज खुल जाता है। इसमें एक दोपहर लगी, और कुछ बातें हमारी उम्मीद से ज़्यादा दिलचस्प निकलीं।

बॉक्स ही क्यों

पहला विचार यह था कि आइकन पेज के पूरे ऊपरी हिस्से में उड़ते फिरें। लेकिन वहीं हमारी हेडलाइन और बटन हैं, और थोड़े-से मज़े के लिए “Start a project” के ऊपर आइकन गिरें, यह अच्छा सौदा नहीं है। इंट्रो के बगल में एक बॉक्स, जिसके किनारे पर एक लेबल है, खेल को एक दायरे में रखता है। यह उस जगह में भी ठीक बैठा जो पहले से खाली थी: चौड़ी स्क्रीन पर इंट्रो और बटनों के दाईं ओर की खाली जगह। फ़ोन पर यह बटनों के नीचे आता है।

Matter.js से असली फ़िज़िक्स

आपस में टकराते गोले खुद लिख लेना आसान है। लेकिन ऐप आइकन गोल कोनों वाले चौकोर होते हैं, और सिक्के की तरह लुढ़कता चौकोर आइकन फ़ौरन अटपटा लगता है। सही ढंग से लुढ़कने और एक-दूसरे पर टिकने के लिए असली फ़िज़िक्स इंजन चाहिए, इसलिए हमने Matter.js इस्तेमाल किया। हर आइकन गोल कोनों वाला एक आयत है (chamfer), जो आइकन के 22% कॉर्नर रेडियस से मेल खाता है, और वह चार स्थिर दीवारों के अंदर रहता है।

इंजन 83KB का है, इसलिए यह सिर्फ़ होम पेज पर लोड होता है, पेज तैयार होने के बाद ही लोड होता है, और तभी लोड होता है जब विज़िटर ने कम मोशन की माँग न की हो।

DOM एलिमेंट, कैनवास नहीं

Matter.js कैनवास पर ड्रॉ कर सकता है, लेकिन हम इसे सिर्फ़ गणित के लिए इस्तेमाल करते हैं। आइकन इमेज वाले सामान्य लिंक हैं, जिन्हें हर फ़्रेम में CSS transform से सही जगह पर रखा जाता है:

st.setProperty("--x", (b.position.x - size / 2) + "px");
st.setProperty("--y", (b.position.y - size / 2) + "px");
st.setProperty("--a", b.angle + "rad");

इसलिए टैप एक असली लिंक है, इमेज किसी भी ज़ूम पर साफ़ दिखती हैं, और आइकन का बॉर्डर और स्टाइल साइट पर हर जगह जैसा ही रहता है।

वह परछाईं जो अपनी जगह टिकी रहती है

हमारी स्टाइल में हर चीज़ के नीचे और दाईं ओर एक सख़्त परछाईं होती है। इसे किसी घूमने वाले एलिमेंट पर लगा दें, तो परछाईं भी उसके साथ घूमने लगती है, और घूमते आइकन की परछाईं घड़ी की सुई की तरह चक्कर काटती है। इसका हल यह है कि हर फ़्रेम में परछाईं के ऑफ़सेट को उलटी दिशा में घुमा दिया जाए:

// keep the shadow at (3px, 3px) in screen space while the icon turns by a
st.setProperty("--shadow-x", 3 * (Math.cos(a) + Math.sin(a)) + "px");
st.setProperty("--shadow-y", 3 * (Math.cos(a) - Math.sin(a)) + "px");

पकड़ना और फेंकना

पॉइंटर दबाते ही हम पॉइंटर और आइकन के उस ठीक बिंदु के बीच एक स्प्रिंग (Matter.js का constraint) जोड़ देते हैं जहाँ आपने उसे पकड़ा है, उसके केंद्र पर नहीं, इसलिए कोने से पकड़ने पर वह स्वाभाविक रूप से झूलता है। छोड़ने पर वह अपनी रफ़्तार बनाए रखता है, जिसकी एक सीमा तय है ताकि ज़ोर का झटका उसे दीवार के पार न भेज दे। अगर पॉइंटर छह पिक्सल से कम हिला, तो इसे टैप माना जाता है और लिंक खुल जाता है।

जब आइकन ऊपर से गिर रहे होते हैं, तब बॉक्स का ऊपरी हिस्सा खुला रहता है, और सब अंदर आ जाने पर बंद हो जाता है, ताकि फेंकने पर कोई आइकन ऊपर से बाहर न निकल जाए।

छोटी-छोटी बातें

  • ज़ोर से गिरने पर पेज की बिंदीदार बैकग्राउंड में एक लहर दौड़ जाती है।
  • जब सब कुछ स्थिर होता है तो सिमुलेशन सो जाता है, और बॉक्स स्क्रीन से बाहर हो तो रुक जाता है, इसलिए आपके पढ़ते समय इसका कोई खर्च नहीं होता।
  • आइकन तभी गिरते हैं जब बॉक्स स्क्रीन पर आ जाता है। फ़ोन पर यह तब होता है जब आप स्क्रॉल करके वहाँ पहुँचते हैं।
  • JavaScript के बिना, या कम मोशन चालू होने पर, आइकन एक सलीकेदार ढेर में स्थिर रहते हैं, और फिर भी लिंक रहते हैं।

यह एक छोटी-सी चीज़ है, लेकिन हमारे बनाए ऐप्स के बारे में यह किसी वाक्य से ज़्यादा कहती है। अगर आप अपनी साइट के लिए ऐसा कुछ चाहते हैं, तो हमें बताएँ।

आगे पढ़ें: हमारी साइटों को एजेंट-रेडी बनाने में क्या करना पड़ा, या WordPress 7.2, 8 दिसंबर को आ रहा है: हम अपने प्लगइन में क्या टेस्ट कर रहे हैं।

क्या इस पोस्ट से आपने कुछ नया सीखा?

मुझे आपका ईमेल पता चाहिए, ताकि जब भी कोई नई पोस्ट प्रकाशित हो, मैं आपको ऐसी ही और पोस्ट भेज सकूँ।

    मैं आपको स्पैम नहीं भेजूँगा। आप कभी भी सदस्यता छोड़ सकते हैं।