এই আর্টিকেলটি iOS-এ CA Animation ব্যবহার করে মুলায়ন অ্যানিমেশন তৈরি করার উপর ফোকাস করে।
iOS-এ কাজ করার আমার শুরুতে, যখনই একজন ডিজাইনার আমার কাছে আসে এবং তাদের কাজ করা অ্যাপে কিছু অ্যানিমেশনের চাহিদা প্রকাশ করে, আমি খুবনার্ভাস হতাম।
আমি মনে করতাম অ্যানিমেশনের ডিজাইন করা সহজ — কিন্তু ইমপ্লিমেন্টেশন, অন্যদিকে, খুব কঠিন কাজ।
আমি Google, StackOverflow, এবং সহকর্মীদের সাহায্য নিতাম ইমপ্লিমেন্টেশনের জন্য।
প্রক্রিয়ায় আমি অ্যানিমেশনের प्रति একটি ফোবিয়া ডেভেলপ করলাম এবং সবসময় এড়াতে চেয়েছিলাম। কিন্তু একদিন সবকিছু পরিবর্তন হয়েছে।
CAAnimation খুঁজে পাওয়া
একবার, আমাকে একটি ভিউতে ইমেজের একটি সিকোয়েন্স অ্যানিমেট করতে হয়েছিল। তাহলে আমার প্রথম ধাপ কী ছিল? জाहিরে, StackOverflow!
প্রথম লিংকটি কোডটি দিয়ে দিয়েছিল।
let image_1 = UIImage(named: "image-1")! let image_2 = UIImage(named: "image-2")! let image_3 = UIImage(named: "image-3")! let images = [image_1, image_2, image_3] let animatedImage = UIImage.animatedImage(with: images, duration: 2.0) imageView.image = animatedImage
দেখতে די সরল লাগছে, ঠিক? যদি এটি এতই সহজ হতো, আমি এই আর্টিকেলটি লিখতাম না।
যে অ্যানিমেশনটি প্রয়োজন ছিল:
এবং যেমন স্পষ্ট হয়ে গেছে, আমি তার কাছাকাছি নিই। আমি আটকে পড়েছিলাম। এতটুকু কাস্টোমাইজেশন ও সেগুলো সিঙ্ক করার উপায় কী?
তখন আমার একজন সহকর্মী আমাকে CAAnimation ট্রাই করার পরামর্শ দিলেন। আমি সেটি পড়লাম এবং একটি স্যাম্পল প্রজেক্টে ট্রাই করলাম। আমার বিস্ময়ের চেয়ে বড়, এটি খুব শক্তিশালী এবং ব্যবহারে সহজ ছিল।
Core Animation কী?
Core Animation আপনাকে প্রায় শূন্য CPU ব্যবহারে একাধিক অ্যানিমেশন এক্সিকিউট করতে সাহায্য করে।
এটি আপনাকে হাই ফ্রেম রেট এবং অনেক কাস্টোমাইজেশন দেয় যা খুব কম কোডে ব্যবহার করা যায়।
আরও ডিটেইল ডকুমেন্টেশনে পাবেন: https://developer.apple.com/documentation/quartzcore
আমি কিছু ঘন্টার মধ্যেই একটি বেসিক ইমপ্লিমেন্টেশন করতে পেরেছিলাম:
func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) { let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition) firstImageView.layer.add(basicAnimation1, forKey: "position") let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition) secondImageView.layer.add(basicAnimation2, forKey: "position") self.addNextImage(forImageView: firstImageView) } func getBasicAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CABasicAnimation { let basicAnimation = CABasicAnimation(keyPath: "position") basicAnimation.fromValue = NSValue(cgPoint: initialPos) basicAnimation.toValue = NSValue(cgPoint: finalPos) basicAnimation.duration = 1 basicAnimation.isRemovedOnCompletion = false basicAnimation.fillMode = CAMediaTimingFillMode.forwards basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) return basicAnimation }
এই ইমপ্লিমেন্টেশনে, আমি CABasicAnimation ব্যবহার করেছি।
CABasicAnimation ক্লাস আপনাকে একটি লেয়ার প্রোপার্টি (যা হতে পারে ব্যাকগ্রাউন্ড কালার, অপাসিটি, পজিশন, স্কেল) দুটি ভ্যালুর মধ্যে অ্যানিমেট করতে সাহায্য করে। আপনাকে শুধু একটি শুরু এবং শেষ ভ্যালু দিতে হবে, বাকিটা এটি নিজে নিবেয়ে নেবে। অ্যানিমেশন পরবর্তী রান লুপে অবিলম্বে শুরু হয়, যেমন আরও বিস্তারিত বর্ণনা করা আছে।
এখন, আমাদের সমস্যার দিকে ফিরে যাই।
এটি ইমপ্লিমেন্ট করতে, আমি দুটি ইমেজ ভিউ নিলাম এবং সেগুলোতে দুটি আলাদা ইমেজ যোগ করলাম। তারপর CAAnimation ব্যবহার করে একে পর একে সেগুলো অ্যানিমেট করলাম।
সোর্স কোডটি এখানে পাবেন।
আপনি যদি লাস্ট GIF-টি পরীক্ষা করেন, দেখবেন কিছু অদ্ভুত হচ্ছে। প্রথম গিফট বক্সের ইমেজ ভিউ থেকে বের হওয়ার আগে, হেডফোনটি ক্ষণিক ফ্ল্যাশ করে এবং তারপর ইমেজটি উপরে চলে যায়।
এটি কেন হচ্ছে?
কারণ, যারowany আমরা ইমেজ ভিউতে অ্যানিমেশন যোগ করি, আমরা সেটিতে পরবর্তী ইমেজ যোগ করি (লাইন নম্বর ৫ এবং ৬):
private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) { let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition) firstImageView.layer.add(basicAnimation1, forKey: "position") let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition) secondImageView.layer.add(basicAnimation2, forKey: "position") self.addNextImage(forImageView: firstImageView) }
এখানে আমরা দুটি ইমেজকে অ্যানিমেশনে সিঙ্ক করার সমস্যায় আটকে পড়েছি। কিন্তু CAAnimation-এ সবসময় সমাধান আছে।
CA Transactions
CA Transactions আমাদের একাধিক অ্যানিমেশন একসাথে সিঙ্ক করতে সাহায্য করে। এটি নিশ্চিত করে যে আমরা যে সব অ্যানিমেশন বান্ডেল করেছি সেগুলো একসাথে শুরু হয়।
এছাড়া, আপনি আপনার অ্যানিমেশনের জন্য একটি কমপ্লিশন ব্লক দিতে পারেন, যা তখন এক্সিকিউট হবে যখন এক বান্ডেলের সব অ্যানিমেশন কমপ্লিট হবে।
এ সম্পর্কে আরও জানতে এখানে যান।
private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) { CATransaction.begin() CATransaction.setCompletionBlock { self.addNextImage(forImageView: firstImageView) } let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition) firstImageView.layer.add(basicAnimation1, forKey: "position") CATransaction.commit() let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition) secondImageView.layer.add(basicAnimation2, forKey: "position") }
আপনি CATransaction.begin() লিখে শুরু করুন। তারপর, যে সব অ্যানিমেশন আপনি সিঙ্কে করতে চান সেগুলো লিখুন। চূড়ান্তভাবে, CATransaction.commit() কল করুন যা ব্লকের অ্যানিমেশন শুরু করবে।
দেখি আমাদের অ্যানিমেশনটি কেমন লাগছে এখন:
আমার আর একটা কাজ বাকি ছিল — অ্যানিমেশনে স্প্রিং ইফেক্ট যোগ করা। خوشখবর, CAAnimation-এ এরও সমাধান ছিল।
CA Spring Animation
CA Spring Animation, যখন একটি লেয়ারে যোগ করা হয়, তখন সেটি একটি স্প্রিং-সদৃশ ইফেক্ট দেয়, যেন সেটি একটি স্প্রিং দ্বারা টার্গেট দিকে টানানো হচ্ছে।
লেয়ারটি টার্গেট থেকে যত দূরে থাকবে, সেটির দিকে ত্বরণ তত বেশি হবে।
এটি ফিজিক্যালি-বেসড অ্যাট্রিবিউট যেমন স্প্রিং-এর ড্যাম্পিং এবং স্টিফনেস নিয়ন্ত্রণ করতে দেয়। – Docs
Apple ডকুমেন্টেশন থেকে আরও পড়ুন: https://developer.apple.com/documentation/quartzcore/caspringanimation
এটি আমাদের বিদ্যমান কোডে ইমপ্লিমেন্ট করি:
private func getSpringAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CASpringAnimation { let basicAnimation = CASpringAnimation(keyPath: "position") basicAnimation.fromValue = NSValue(cgPoint: initialPos) basicAnimation.toValue = NSValue(cgPoint: finalPos) basicAnimation.duration = basicAnimation.settlingDuration basicAnimation.damping = 14 basicAnimation.initialVelocity = 5 basicAnimation.isRemovedOnCompletion = false basicAnimation.fillMode = CAMediaTimingFillMode.forwards return basicAnimation }
আমার কাজ শেষ।
সারসংক্ষেপে, CA Animations ব্যবহারের কিছু সুবিধা:
- ব্যবহার এবং ইমপ্লিমেন্ট করা সহজ
- অনেক কাস্টোমাইজেশন উপলব্ধ
- একাধিক অ্যানিমেশন সিঙ্ক করা সম্ভব
- প্রায় শূন্য CPU ব্যবহার
এই مجرد কিছু সুবিধা। সম্ভাবনারা অসীম।
এখন, যখনই অ্যানিমেশনের রিকোয়ারমেন্ট আসে, আমি আত্মবিশ্বাসের সাথে সেগুলো ডিজাইন এবং ইমপ্লিমেন্ট করি। এবং আশা করি এই আর্টিকেল পড়ার পর আপনাও একই অনুভূতি করবেন।
যেকোনো পরামর্শ বা ফিডব্যাক জানাতে স্বচ্ছন্দ মনে করুন।