कंटेंट पर जाएँ
charmotion

watchOS और visionOS पर कैरेक्टर एनिमेशन

Charmotion टीम द्वारा · अपडेट:

iOS और Swift गाइड का कवर इलस्ट्रेशन: watchOS और visionOS पर कैरेक्टर एनिमेशन, Charmotion डेमो कैरेक्टर के साथ

न Rive और न Lottie आधिकारिक रूप से watchOS सपोर्ट करते हैं: rive-ios में iOS, visionOS, tvOS, macOS और Mac Catalyst घोषित हैं, और lottie-spm में iOS, macOS, tvOS और visionOS। Apple Watch पर SwiftUI के PhaseAnimator या KeyframeAnimator (watchOS 10+) से एनिमेट करें या pre-rendered फ़्रेम चलाएँ। visionOS पर दोनों सामान्य SwiftUI window में चलते हैं।

मुख्य बातें

  • rive-ios Package.swift: iOS 14, visionOS 1, tvOS 16, macOS 13.1, Mac Catalyst 14। watchOS नहीं।
  • lottie-spm Package.swift में iOS, macOS, tvOS और visionOS सूचीबद्ध हैं। watchOS नहीं।
  • watchOS पर SwiftUI animators या TimelineView से चलने वाला frame sequence इस्तेमाल करें।
  • visionOS पर 2D मैस्कॉट की जगह SwiftUI window या ornament में है; RealityKit 3D models के लिए है।
  • उसी कैरेक्टर के ट्रांसपेरेंट वीडियो से फ़्रेम एक्सपोर्ट करें, ताकि Watch, फ़ोन और Vision Pro पर सब एक जैसा दिखे।

क्या Rive watchOS सपोर्ट करता है?

आधिकारिक रूप से नहीं। rive-ios के Package.swift में ये platforms हैं:

platforms: [.iOS("14.0"), .visionOS("1.0"), .tvOS("16.0"), .macOS("13.1"), .macCatalyst("14.0")]

Swift Package Manager इस package को watchOS target से link नहीं करेगा, क्योंकि watchOS उस सूची में नहीं है। Rive के Apple migration page के एक सारांश से कभी-कभी नए runtime के लिए watchOS सपोर्ट का संकेत मिला है, लेकिन Xcode वही लागू करता है जो shipped manifest में है, इसलिए यह मानकर योजना बनाएँ कि Watch पर Rive उपलब्ध नहीं है। Package अपडेट करते समय manifest फिर से चेक करें, क्योंकि releases के बीच platform सूचियाँ बदल सकती हैं।

यही बात Rive के legacy runtime पर भी लागू होती है: दोनों runtimes एक ही package में platforms के एक ही सेट के साथ आते हैं। अगर आपका iPhone ऐप और Watch ऐप UI components का एक Swift package साझा करते हैं, तो Rive पर आधारित views को ऐसे module में रखें जिस पर केवल iOS (और visionOS) targets निर्भर हों, वरना Watch build dependency resolve नहीं कर पाएगा।

क्या Lottie watchOS सपोर्ट करता है?

नहीं। lottie-spm manifest, जिसकी सिफ़ारिश Airbnb Swift Package Manager के लिए करता है, iOS, macOS, tvOS और visionOS घोषित करता है। इसमें watchOS की कोई entry नहीं है।

विकल्पiOSvisionOSwatchOS
RiveRuntime (rive-ios)14.0+1.0+घोषित नहीं
Lottie (lottie-spm)YesYesघोषित नहीं
SwiftUI PhaseAnimator / KeyframeAnimator17.0+1.0+10.0+
SwiftUI TimelineView फ़्रेम सीक्वेंसYesYesYes
AVKit VideoPlayerYesYesYes

Lottie के सटीक minimum versions के लिए, जिस release को आप pin करते हैं उसकी platforms line पढ़ें।

watchOS के लिए Lottie के पुराने forks और community ports मौजूद हैं, लेकिन वे Airbnb package नहीं हैं और उनका maintenance अलग-अलग होता है। जिस ऐप को आप लगातार अपडेट करना चाहते हैं, उसके लिए नीचे की पंक्तियों वाले native विकल्प कम जोखिम वाले हैं: वे OS के साथ आते हैं, सिस्टम की एक्सेसिबिलिटी सेटिंग्स का पालन करते हैं, और Watch target में किसी अतिरिक्त dependency की ज़रूरत नहीं होती।

इसके बजाय Apple Watch पर मैं क्या इस्तेमाल कर सकता हूँ?

तीन विकल्प, सबसे हल्के से सबसे भारी तक:

  1. Still image पर SwiftUI animators। phaseAnimator और keyframeAnimator watchOS 10 से उपलब्ध हैं। एक ही pose पर bounce, tilt या pulse के लिए एक इमेज के अलावा कोई asset नहीं लगता। देखें PhaseAnimator vs KeyframeAnimator।
  2. Frame sequence। एक छोटा लूप numbered PNGs के रूप में एक्सपोर्ट करें, उन्हें Watch ऐप के asset catalog में जोड़ें, और TimelineView से उन्हें बारी-बारी चलाएँ। इससे असली कैरेक्टर मोशन (पलक झपकना, हाथ हिलाना) बना रहता है, लेकिन ऐप का साइज़ बढ़ता है।
  3. वीडियो। AVKit का SwiftUI VideoPlayer watchOS पर उपलब्ध है। यह player chrome दिखाता है और ambient मैस्कॉट की तुलना में ऐसी क्लिप के लिए ज़्यादा सही है जिसे यूज़र खुद देखना चुने।

एक frame-sequence view:

import SwiftUI

struct FrameSequence: View {
    let frames: [String]          // ["wave_00", "wave_01", ...] in the asset catalog
    var fps: Double = 12
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    var body: some View {
        if reduceMotion || frames.count < 2 {
            Image(frames.first ?? "")
                .resizable()
                .scaledToFit()
        } else {
            TimelineView(.animation(minimumInterval: 1 / fps)) { context in
                let tick = Int(context.date.timeIntervalSinceReferenceDate * fps)
                Image(frames[tick % frames.count])
                    .resizable()
                    .scaledToFit()
            }
        }
    }
}

// Usage
FrameSequence(frames: (0..<24).map { String(format: "wave_%02d", $0) })
    .frame(width: 80, height: 80)

लूप छोटे और हल्के रखें: Watch की स्क्रीन बहुत छोटी है, और हर फ़्रेम ऐप का साइज़ बढ़ाता है। Sequence को पूरे दिन लूप करने के बजाय किसी खास पल पर चलाएँ (वर्कआउट पूरा होने पर, किसी reminder पर)।

अपने एनिमेशन सेट से watchOS के लिए फ़्रेम कैसे एक्सपोर्ट करूँ?

ट्रांसपेरेंट source से शुरू करें, ताकि कैरेक्टर Watch के काले बैकग्राउंड पर साफ़ दिखे। ffmpeg और alpha वाले VP9 WebM के साथ:

# 12 fps, 160 px wide, keep transparency
ffmpeg -c:v libvpx-vp9 -i wave.webm -vf "fps=12,scale=160:-1" wave_%02d.png

फिर PNGs को Watch target के asset catalog में drag करें। सुझाव:

  • Display के हिसाब से साइज़। Source resolution पर नहीं, बल्कि आप जिस सबसे बड़े point size पर दिखाते हैं उसे screen scale से गुणा करके एक्सपोर्ट करें।
  • लूप छोटा करें। 12 fps पर दो सेकंड का लूप 24 इमेज का होता है; idle या wave के लिए यह अक्सर काफ़ी है।
  • Reduce Motion के लिए एक still चुनें। पहला फ़्रेम ही static pose का काम भी करता है।

पेड प्लान पर Charmotion सेट में हर एनिमेशन की ट्रांसपेरेंट WebM और HEVC-alpha MOV फ़ाइलें शामिल हैं, iPhone पर इस्तेमाल होने वाली .riv के साथ, इसलिए Watch के फ़्रेम ठीक उसी मोशन से आते हैं जो फ़ोन ऐप में है।

iPhone, Watch और Vision Pro पर एक ही मैस्कॉट view कैसे शेयर करें?

प्लेटफ़ॉर्म का फ़र्क एक ऐसे view के पीछे छिपाएँ जो हर जगह एक ही इनपुट ले, जैसे मूड नंबर। iOS और visionOS वाली branch Rive इस्तेमाल करती है, और watchOS वाली branch फ़्रेम:

import SwiftUI
#if !os(watchOS)
import RiveRuntime
#endif

struct Mascot: View {
    let mood: Int

    var body: some View {
        #if os(watchOS)
        FrameSequence(frames: Self.frames(for: mood))
        #else
        RiveMascot(mood: mood)       // wraps RiveUIViewRepresentable and setValue(of:to:)
        #endif
    }

    #if os(watchOS)
    static func frames(for mood: Int) -> [String] {
        (0..<24).map { String(format: "mood%d_%02d", mood, $0) }
    }
    #endif
}

rive-ios package सिर्फ़ iOS और visionOS target में जोड़ें, और फ़्रेम इमेज सिर्फ़ Watch target में, ताकि कोई भी प्लेटफ़ॉर्म दूसरे के assets साथ लेकर न चले। शेयर्ड कोड (आपका model, mood enum) किसी प्लेटफ़ॉर्म से बंधा नहीं रहता।

क्या Rive visionOS पर चलता है?

हाँ। rive-ios की प्लेटफ़ॉर्म लिस्ट में visionOS 1.0 है, और Lottie के manifest में भी visionOS शामिल है। Vision Pro पर SwiftUI ऐप अपने views को windows में दिखाता है, इसलिए iPhone वाला वही कोड यहाँ भी काम करता है:

import SwiftUI
import RiveRuntime

struct MascotWindow: View {
    @StateObject private var model = CharacterModel()   // loads the .riv and keeps the view model instance

    var body: some View {
        RiveUIViewRepresentable(rive: model.rive)
            .frame(width: 320, height: 320)
            .padding(32)
            .glassBackgroundEffect()
            .task { await model.load() }
    }
}

यहाँ CharacterModel वही controller है जो SwiftUI में Rive data binding में है: यह Worker, File, view model instance और bound स्टेट मशीन बनाता है। glassBackgroundEffect() visionOS का glass material है, दूसरे प्लेटफ़ॉर्म पर इसे हटा दें।

सिम्युलेटर के साथ-साथ असली डिवाइस पर भी टेस्ट करें। दोनों रनटाइम में रेंडरिंग Metal पर आधारित है, और कमरे में तैरते एक फ़्लैट कैरेक्टर का विज़ुअल असर Mac स्क्रीन पर आँकना मुश्किल है।

visionOS पर 2D मैस्कॉट SwiftUI window में रखें या RealityKit में?

2D कैरेक्टर को SwiftUI में रखें। RealityKit और Reality Composer Pro 3D कंटेंट के लिए बने हैं: models, materials और skeletal एनिमेशन। RealityKit में रखा गया फ़्लैट Rive या Lottie कैरेक्टर कुछ हासिल नहीं करता, उल्टा आसान view-based API खो देता है।

जगहकिसके लिए
main window के अंदरऑनबोर्डिंग, एम्प्टी स्टेट, assistant avatar: iPhone जैसा ही
window से जुड़ा ornamentआपके कंटेंट के पास हमेशा दिखने वाला छोटा हेल्पर
अलग छोटी windowएक साथी जिसे यूज़र इधर-उधर ले जा सके
RealityKit entityसिर्फ़ तब, जब कैरेक्टर असली 3D model हो

हेडसेट में Reduce Motion और ज़्यादा अहम है, क्योंकि वहाँ मोशन नज़र के बड़े हिस्से में फैला होता है। @Environment(\.accessibilityReduceMotion) पढ़ें (visionOS 1 पर उपलब्ध) और एनिमेशन रोकें या स्थिर पोज़ दिखाएँ; देखें SwiftUI और UIKit में Reduce Motion।

Apple Watch ऐप में कैरेक्टर एनिमेशन जोड़ें

  1. तरीका चुनें. आसान मोशन के लिए स्थिर पोज़ पर SwiftUI animator इस्तेमाल करें, या असली कैरेक्टर मोशन के लिए फ़्रेम सीक्वेंस।
  2. फ़्रेम एक्सपोर्ट करें. ट्रांसपेरेंट WebM पर ffmpeg -c:v libvpx-vp9 -i wave.webm -vf "fps=12,scale=160:-1" wave_%02d.png चलाएँ।
  3. Watch target में जोड़ें. PNG फ़ाइलों को Watch ऐप के asset catalog में ड्रैग करें।
  4. इन्हें चलाएँ. एक्सपोर्ट वाले frame rate पर TimelineView(.animation(minimumInterval:)) से इमेज बारी-बारी दिखाएँ।
  5. Reduce Motion संभालें. जब accessibilityReduceMotion true हो, तो पहला फ़्रेम स्थिर इमेज के रूप में दिखाएँ।

अक्सर पूछे जाने वाले सवाल

क्या मैं अपना iOS Rive view कोड watchOS target के साथ शेयर कर सकता हूँ?

सीधे नहीं, क्योंकि RiveRuntime package watchOS declare नहीं करता और Watch target में link नहीं होगा। मैस्कॉट को अपने view में platform conditionals के साथ लपेटें: iOS और visionOS पर Rive, watchOS पर फ़्रेम सीक्वेंस या SwiftUI animator, और सबको एक ही मूड वैल्यू मिले।

क्या Apple Watch पर GIF चलता है?

SwiftUI का Image किसी भी Apple प्लेटफ़ॉर्म पर GIF एनिमेट नहीं करता। GIF के फ़्रेम को इमेज में decode करके बारी-बारी दिखाएँ, या बेहतर है कि ट्रांसपेरेंट सोर्स से PNG फ़्रेम एक्सपोर्ट करके TimelineView से चलाएँ। इससे frame rate, साइज़ और Reduce Motion पर आपका कंट्रोल रहता है।

क्या Lottie visionOS पर उपलब्ध है?

हाँ। lottie-spm manifest में iOS, macOS और tvOS के साथ visionOS भी declare है, इसलिए LottieView visionOS की SwiftUI window में वैसे ही काम करता है जैसे iPhone पर। Rive का package भी visionOS 1.0 declare करता है, इसलिए visionOS window या ornament में 2D कैरेक्टर के लिए दोनों रनटाइम विकल्प हैं।

इस गाइड से झटपट जवाब

स्रोत

संबंधित गाइड