├── .gitignore ├── LottieInVideo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── lvpengwei.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── LottieInVideo.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── LottieInVideo ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── asset_slider_thumb.imageset │ │ ├── Contents.json │ │ └── knob.pdf │ ├── icon_pause.imageset │ │ ├── Contents.json │ │ └── icPause.pdf │ ├── icon_play.imageset │ │ ├── Contents.json │ │ └── icPlaySmall.pdf │ └── sticker_drag.imageset │ │ ├── Contents.json │ │ └── editorElementsExpand.pdf ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Classes │ ├── Editor │ │ ├── CustomLayerInstruction.swift │ │ └── CustomVideoCompositor.swift │ ├── ResizableSlider.swift │ ├── Sticker │ │ ├── Model │ │ │ └── Sticker.swift │ │ └── View │ │ │ ├── StickerView.swift │ │ │ └── StickerWrapView.swift │ ├── UIView+Positioning.swift │ ├── Util.swift │ └── VideoPreview.swift ├── Info.plist ├── Resource │ ├── 1532072337.63853.MP4 │ ├── HamburgerArrow.json │ ├── PinJump.json │ ├── WelcomeToIsland.json │ ├── drinks.json │ ├── hunluan.json │ └── xingxing.json └── ViewController.swift ├── Podfile ├── Podfile.lock └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/xcode,objective-c,swift 3 | 4 | SDKs/ 5 | 6 | ### Xcode ### 7 | # Xcode 8 | # 9 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 10 | 11 | ## Build generated 12 | build/ 13 | DerivedData/ 14 | 15 | ## Various settings 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata/ 25 | 26 | ## Other 27 | *.moved-aside 28 | *.xccheckout 29 | *.xcscmblueprint 30 | 31 | 32 | ### Objective-C ### 33 | # Xcode 34 | # 35 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 36 | 37 | ## Build generated 38 | build/ 39 | DerivedData/ 40 | 41 | ## Various settings 42 | *.pbxuser 43 | !default.pbxuser 44 | *.mode1v3 45 | !default.mode1v3 46 | *.mode2v3 47 | !default.mode2v3 48 | *.perspectivev3 49 | !default.perspectivev3 50 | xcuserdata/ 51 | 52 | ## Other 53 | *.moved-aside 54 | *.xcuserstate 55 | 56 | ## Obj-C/Swift specific 57 | *.hmap 58 | *.ipa 59 | *.dSYM.zip 60 | *.dSYM 61 | 62 | # CocoaPods 63 | # 64 | # We recommend against adding the Pods directory to your .gitignore. However 65 | # you should judge for yourself, the pros and cons are mentioned at: 66 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 67 | # 68 | Pods/ 69 | 70 | # Carthage 71 | # 72 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 73 | 74 | Carthage/Checkouts 75 | Carthage/Build 76 | 77 | # fastlane 78 | # 79 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 80 | # screenshots whenever they are needed. 81 | # For more information about the recommended setup visit: 82 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 83 | 84 | fastlane/report.xml 85 | fastlane/Preview.html 86 | fastlane/screenshots 87 | fastlane/test_output 88 | 89 | # Code Injection 90 | # 91 | # After new code Injection tools there's a generated folder /iOSInjectionProject 92 | # https://github.com/johnno1962/injectionforxcode 93 | 94 | iOSInjectionProject/ 95 | 96 | ### Objective-C Patch ### 97 | *.xcscmblueprint 98 | 99 | 100 | ### Swift ### 101 | # Xcode 102 | # 103 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 104 | 105 | ## Build generated 106 | build/ 107 | DerivedData/ 108 | 109 | ## Various settings 110 | *.pbxuser 111 | !default.pbxuser 112 | *.mode1v3 113 | !default.mode1v3 114 | *.mode2v3 115 | !default.mode2v3 116 | *.perspectivev3 117 | !default.perspectivev3 118 | xcuserdata/ 119 | 120 | ## Other 121 | *.moved-aside 122 | *.xcuserstate 123 | 124 | ## Obj-C/Swift specific 125 | *.hmap 126 | *.ipa 127 | *.dSYM.zip 128 | *.dSYM 129 | 130 | ## Playgrounds 131 | timeline.xctimeline 132 | playground.xcworkspace 133 | 134 | # Swift Package Manager 135 | # 136 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 137 | # Packages/ 138 | .build/ 139 | 140 | # Carthage 141 | # 142 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 143 | # Carthage/Checkouts 144 | 145 | Carthage/Build 146 | 147 | # fastlane 148 | # 149 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 150 | # screenshots whenever they are needed. 151 | # For more information about the recommended setup visit: 152 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 153 | 154 | fastlane/report.xml 155 | fastlane/Preview.html 156 | fastlane/screenshots 157 | fastlane/test_output 158 | 159 | .DS_Store 160 | -------------------------------------------------------------------------------- /LottieInVideo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 456FE9D1BB0940BB7E889D27 /* Pods_LottieInVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECA835062A34378171B70D7C /* Pods_LottieInVideo.framework */; }; 11 | E611F60321C4F8AF00B4FAA0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E611F60221C4F8AF00B4FAA0 /* AppDelegate.swift */; }; 12 | E611F60521C4F8AF00B4FAA0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E611F60421C4F8AF00B4FAA0 /* ViewController.swift */; }; 13 | E611F60821C4F8AF00B4FAA0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E611F60621C4F8AF00B4FAA0 /* Main.storyboard */; }; 14 | E611F60A21C4F8B000B4FAA0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E611F60921C4F8B000B4FAA0 /* Assets.xcassets */; }; 15 | E611F60D21C4F8B000B4FAA0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E611F60B21C4F8B000B4FAA0 /* LaunchScreen.storyboard */; }; 16 | E6517BA021D099BA00F670A3 /* drinks.json in Resources */ = {isa = PBXBuildFile; fileRef = E6517B9F21D099BA00F670A3 /* drinks.json */; }; 17 | E664EBC721F878F4007123FE /* CustomVideoCompositor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E664EBC521F878F4007123FE /* CustomVideoCompositor.swift */; }; 18 | E664EBC821F878F4007123FE /* CustomLayerInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E664EBC621F878F4007123FE /* CustomLayerInstruction.swift */; }; 19 | E69CE85D21C50811006B13E8 /* Sticker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69CE85C21C50811006B13E8 /* Sticker.swift */; }; 20 | E69CE86021C50840006B13E8 /* StickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69CE85E21C50840006B13E8 /* StickerView.swift */; }; 21 | E69CE86121C50840006B13E8 /* StickerWrapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69CE85F21C50840006B13E8 /* StickerWrapView.swift */; }; 22 | E69CE86321C509D4006B13E8 /* Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69CE86221C509D4006B13E8 /* Util.swift */; }; 23 | E69D369D21C63268003C80D2 /* VideoPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69D369C21C63268003C80D2 /* VideoPreview.swift */; }; 24 | E69D369F21C63392003C80D2 /* ResizableSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69D369E21C63392003C80D2 /* ResizableSlider.swift */; }; 25 | E69D36A121C63C0D003C80D2 /* UIView+Positioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69D36A021C63C0D003C80D2 /* UIView+Positioning.swift */; }; 26 | E69D36A821C64344003C80D2 /* 1532072337.63853.MP4 in Resources */ = {isa = PBXBuildFile; fileRef = E69D36A621C64344003C80D2 /* 1532072337.63853.MP4 */; }; 27 | E69D36AC21C64355003C80D2 /* PinJump.json in Resources */ = {isa = PBXBuildFile; fileRef = E69D36AB21C64355003C80D2 /* PinJump.json */; }; 28 | E69D36B021C65374003C80D2 /* WelcomeToIsland.json in Resources */ = {isa = PBXBuildFile; fileRef = E69D36AF21C65374003C80D2 /* WelcomeToIsland.json */; }; 29 | E69D36B221C65378003C80D2 /* HamburgerArrow.json in Resources */ = {isa = PBXBuildFile; fileRef = E69D36B121C65378003C80D2 /* HamburgerArrow.json */; }; 30 | E69D36B621C65596003C80D2 /* hunluan.json in Resources */ = {isa = PBXBuildFile; fileRef = E69D36B521C65596003C80D2 /* hunluan.json */; }; 31 | E69D36B821C65620003C80D2 /* xingxing.json in Resources */ = {isa = PBXBuildFile; fileRef = E69D36B721C65620003C80D2 /* xingxing.json */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 48A383B9FB37A398635568D2 /* Pods-LottieInVideo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LottieInVideo.release.xcconfig"; path = "Pods/Target Support Files/Pods-LottieInVideo/Pods-LottieInVideo.release.xcconfig"; sourceTree = ""; }; 36 | 8E1DF4586636AF0E4A2FD818 /* Pods-LottieInVideo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LottieInVideo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LottieInVideo/Pods-LottieInVideo.debug.xcconfig"; sourceTree = ""; }; 37 | E611F5FF21C4F8AF00B4FAA0 /* LottieInVideo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LottieInVideo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | E611F60221C4F8AF00B4FAA0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 39 | E611F60421C4F8AF00B4FAA0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 40 | E611F60721C4F8AF00B4FAA0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 41 | E611F60921C4F8B000B4FAA0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 42 | E611F60C21C4F8B000B4FAA0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 43 | E611F60E21C4F8B000B4FAA0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 44 | E6517B9F21D099BA00F670A3 /* drinks.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = drinks.json; sourceTree = ""; }; 45 | E664EBC521F878F4007123FE /* CustomVideoCompositor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomVideoCompositor.swift; sourceTree = ""; }; 46 | E664EBC621F878F4007123FE /* CustomLayerInstruction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomLayerInstruction.swift; sourceTree = ""; }; 47 | E69CE85C21C50811006B13E8 /* Sticker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sticker.swift; sourceTree = ""; }; 48 | E69CE85E21C50840006B13E8 /* StickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerView.swift; sourceTree = ""; }; 49 | E69CE85F21C50840006B13E8 /* StickerWrapView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerWrapView.swift; sourceTree = ""; }; 50 | E69CE86221C509D4006B13E8 /* Util.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Util.swift; sourceTree = ""; }; 51 | E69D369C21C63268003C80D2 /* VideoPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPreview.swift; sourceTree = ""; }; 52 | E69D369E21C63392003C80D2 /* ResizableSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResizableSlider.swift; sourceTree = ""; }; 53 | E69D36A021C63C0D003C80D2 /* UIView+Positioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Positioning.swift"; sourceTree = ""; }; 54 | E69D36A621C64344003C80D2 /* 1532072337.63853.MP4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = 1532072337.63853.MP4; sourceTree = ""; }; 55 | E69D36AB21C64355003C80D2 /* PinJump.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = PinJump.json; sourceTree = ""; }; 56 | E69D36AF21C65374003C80D2 /* WelcomeToIsland.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = WelcomeToIsland.json; sourceTree = ""; }; 57 | E69D36B121C65378003C80D2 /* HamburgerArrow.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = HamburgerArrow.json; sourceTree = ""; }; 58 | E69D36B521C65596003C80D2 /* hunluan.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = hunluan.json; sourceTree = ""; }; 59 | E69D36B721C65620003C80D2 /* xingxing.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = xingxing.json; sourceTree = ""; }; 60 | ECA835062A34378171B70D7C /* Pods_LottieInVideo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LottieInVideo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | E611F5FC21C4F8AF00B4FAA0 /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 456FE9D1BB0940BB7E889D27 /* Pods_LottieInVideo.framework in Frameworks */, 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXFrameworksBuildPhase section */ 73 | 74 | /* Begin PBXGroup section */ 75 | 2D04DABA761D01A40873AC4F /* Pods */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 8E1DF4586636AF0E4A2FD818 /* Pods-LottieInVideo.debug.xcconfig */, 79 | 48A383B9FB37A398635568D2 /* Pods-LottieInVideo.release.xcconfig */, 80 | ); 81 | name = Pods; 82 | sourceTree = ""; 83 | }; 84 | 9586BEB2E8F8C766E72D91AA /* Frameworks */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | ECA835062A34378171B70D7C /* Pods_LottieInVideo.framework */, 88 | ); 89 | name = Frameworks; 90 | sourceTree = ""; 91 | }; 92 | E611F5F621C4F8AF00B4FAA0 = { 93 | isa = PBXGroup; 94 | children = ( 95 | E611F60121C4F8AF00B4FAA0 /* LottieInVideo */, 96 | E611F60021C4F8AF00B4FAA0 /* Products */, 97 | 2D04DABA761D01A40873AC4F /* Pods */, 98 | 9586BEB2E8F8C766E72D91AA /* Frameworks */, 99 | ); 100 | sourceTree = ""; 101 | }; 102 | E611F60021C4F8AF00B4FAA0 /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | E611F5FF21C4F8AF00B4FAA0 /* LottieInVideo.app */, 106 | ); 107 | name = Products; 108 | sourceTree = ""; 109 | }; 110 | E611F60121C4F8AF00B4FAA0 /* LottieInVideo */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | E69D36A421C64328003C80D2 /* Resource */, 114 | E69CE85821C50801006B13E8 /* Classes */, 115 | E611F60221C4F8AF00B4FAA0 /* AppDelegate.swift */, 116 | E611F60421C4F8AF00B4FAA0 /* ViewController.swift */, 117 | E611F60621C4F8AF00B4FAA0 /* Main.storyboard */, 118 | E611F60921C4F8B000B4FAA0 /* Assets.xcassets */, 119 | E611F60B21C4F8B000B4FAA0 /* LaunchScreen.storyboard */, 120 | E611F60E21C4F8B000B4FAA0 /* Info.plist */, 121 | ); 122 | path = LottieInVideo; 123 | sourceTree = ""; 124 | }; 125 | E664EBC421F878ED007123FE /* Editor */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | E664EBC621F878F4007123FE /* CustomLayerInstruction.swift */, 129 | E664EBC521F878F4007123FE /* CustomVideoCompositor.swift */, 130 | ); 131 | path = Editor; 132 | sourceTree = ""; 133 | }; 134 | E69CE85821C50801006B13E8 /* Classes */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | E664EBC421F878ED007123FE /* Editor */, 138 | E69D36A021C63C0D003C80D2 /* UIView+Positioning.swift */, 139 | E69CE85921C50801006B13E8 /* Sticker */, 140 | E69CE86221C509D4006B13E8 /* Util.swift */, 141 | E69D369C21C63268003C80D2 /* VideoPreview.swift */, 142 | E69D369E21C63392003C80D2 /* ResizableSlider.swift */, 143 | ); 144 | path = Classes; 145 | sourceTree = ""; 146 | }; 147 | E69CE85921C50801006B13E8 /* Sticker */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | E69CE85A21C50801006B13E8 /* Model */, 151 | E69CE85B21C50801006B13E8 /* View */, 152 | ); 153 | path = Sticker; 154 | sourceTree = ""; 155 | }; 156 | E69CE85A21C50801006B13E8 /* Model */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | E69CE85C21C50811006B13E8 /* Sticker.swift */, 160 | ); 161 | path = Model; 162 | sourceTree = ""; 163 | }; 164 | E69CE85B21C50801006B13E8 /* View */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | E69CE85E21C50840006B13E8 /* StickerView.swift */, 168 | E69CE85F21C50840006B13E8 /* StickerWrapView.swift */, 169 | ); 170 | path = View; 171 | sourceTree = ""; 172 | }; 173 | E69D36A421C64328003C80D2 /* Resource */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | E6517B9F21D099BA00F670A3 /* drinks.json */, 177 | E69D36B721C65620003C80D2 /* xingxing.json */, 178 | E69D36B521C65596003C80D2 /* hunluan.json */, 179 | E69D36B121C65378003C80D2 /* HamburgerArrow.json */, 180 | E69D36AF21C65374003C80D2 /* WelcomeToIsland.json */, 181 | E69D36AB21C64355003C80D2 /* PinJump.json */, 182 | E69D36A621C64344003C80D2 /* 1532072337.63853.MP4 */, 183 | ); 184 | path = Resource; 185 | sourceTree = ""; 186 | }; 187 | /* End PBXGroup section */ 188 | 189 | /* Begin PBXNativeTarget section */ 190 | E611F5FE21C4F8AF00B4FAA0 /* LottieInVideo */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = E611F61121C4F8B000B4FAA0 /* Build configuration list for PBXNativeTarget "LottieInVideo" */; 193 | buildPhases = ( 194 | A83FBC3423F670680EF54204 /* [CP] Check Pods Manifest.lock */, 195 | E611F5FB21C4F8AF00B4FAA0 /* Sources */, 196 | E611F5FC21C4F8AF00B4FAA0 /* Frameworks */, 197 | E611F5FD21C4F8AF00B4FAA0 /* Resources */, 198 | 3C969EF0956B2AE8B49CFF72 /* [CP] Embed Pods Frameworks */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | ); 204 | name = LottieInVideo; 205 | productName = LottieInVideo; 206 | productReference = E611F5FF21C4F8AF00B4FAA0 /* LottieInVideo.app */; 207 | productType = "com.apple.product-type.application"; 208 | }; 209 | /* End PBXNativeTarget section */ 210 | 211 | /* Begin PBXProject section */ 212 | E611F5F721C4F8AF00B4FAA0 /* Project object */ = { 213 | isa = PBXProject; 214 | attributes = { 215 | LastSwiftUpdateCheck = 1010; 216 | LastUpgradeCheck = 1010; 217 | ORGANIZATIONNAME = lvpengwei; 218 | TargetAttributes = { 219 | E611F5FE21C4F8AF00B4FAA0 = { 220 | CreatedOnToolsVersion = 10.1; 221 | }; 222 | }; 223 | }; 224 | buildConfigurationList = E611F5FA21C4F8AF00B4FAA0 /* Build configuration list for PBXProject "LottieInVideo" */; 225 | compatibilityVersion = "Xcode 9.3"; 226 | developmentRegion = en; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | Base, 231 | ); 232 | mainGroup = E611F5F621C4F8AF00B4FAA0; 233 | productRefGroup = E611F60021C4F8AF00B4FAA0 /* Products */; 234 | projectDirPath = ""; 235 | projectRoot = ""; 236 | targets = ( 237 | E611F5FE21C4F8AF00B4FAA0 /* LottieInVideo */, 238 | ); 239 | }; 240 | /* End PBXProject section */ 241 | 242 | /* Begin PBXResourcesBuildPhase section */ 243 | E611F5FD21C4F8AF00B4FAA0 /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | E69D36AC21C64355003C80D2 /* PinJump.json in Resources */, 248 | E611F60D21C4F8B000B4FAA0 /* LaunchScreen.storyboard in Resources */, 249 | E69D36B221C65378003C80D2 /* HamburgerArrow.json in Resources */, 250 | E69D36B021C65374003C80D2 /* WelcomeToIsland.json in Resources */, 251 | E69D36B621C65596003C80D2 /* hunluan.json in Resources */, 252 | E611F60A21C4F8B000B4FAA0 /* Assets.xcassets in Resources */, 253 | E6517BA021D099BA00F670A3 /* drinks.json in Resources */, 254 | E69D36B821C65620003C80D2 /* xingxing.json in Resources */, 255 | E69D36A821C64344003C80D2 /* 1532072337.63853.MP4 in Resources */, 256 | E611F60821C4F8AF00B4FAA0 /* Main.storyboard in Resources */, 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | /* End PBXResourcesBuildPhase section */ 261 | 262 | /* Begin PBXShellScriptBuildPhase section */ 263 | 3C969EF0956B2AE8B49CFF72 /* [CP] Embed Pods Frameworks */ = { 264 | isa = PBXShellScriptBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | ); 268 | inputFileListPaths = ( 269 | ); 270 | inputPaths = ( 271 | "${PODS_ROOT}/Target Support Files/Pods-LottieInVideo/Pods-LottieInVideo-frameworks.sh", 272 | "${BUILT_PRODUCTS_DIR}/AVPlayerSeeker/AVPlayerSeeker.framework", 273 | "${BUILT_PRODUCTS_DIR}/RxAtomic/RxAtomic.framework", 274 | "${BUILT_PRODUCTS_DIR}/RxCocoa/RxCocoa.framework", 275 | "${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework", 276 | "${BUILT_PRODUCTS_DIR}/SCRecorder/SCRecorder.framework", 277 | "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework", 278 | "${BUILT_PRODUCTS_DIR}/UIColor_Hex_Swift/UIColor_Hex_Swift.framework", 279 | "${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework", 280 | ); 281 | name = "[CP] Embed Pods Frameworks"; 282 | outputFileListPaths = ( 283 | ); 284 | outputPaths = ( 285 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AVPlayerSeeker.framework", 286 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxAtomic.framework", 287 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxCocoa.framework", 288 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework", 289 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SCRecorder.framework", 290 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework", 291 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UIColor_Hex_Swift.framework", 292 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lottie.framework", 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | shellPath = /bin/sh; 296 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LottieInVideo/Pods-LottieInVideo-frameworks.sh\"\n"; 297 | showEnvVarsInLog = 0; 298 | }; 299 | A83FBC3423F670680EF54204 /* [CP] Check Pods Manifest.lock */ = { 300 | isa = PBXShellScriptBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | ); 304 | inputFileListPaths = ( 305 | ); 306 | inputPaths = ( 307 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 308 | "${PODS_ROOT}/Manifest.lock", 309 | ); 310 | name = "[CP] Check Pods Manifest.lock"; 311 | outputFileListPaths = ( 312 | ); 313 | outputPaths = ( 314 | "$(DERIVED_FILE_DIR)/Pods-LottieInVideo-checkManifestLockResult.txt", 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | shellPath = /bin/sh; 318 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 319 | showEnvVarsInLog = 0; 320 | }; 321 | /* End PBXShellScriptBuildPhase section */ 322 | 323 | /* Begin PBXSourcesBuildPhase section */ 324 | E611F5FB21C4F8AF00B4FAA0 /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | E69CE86021C50840006B13E8 /* StickerView.swift in Sources */, 329 | E69CE86321C509D4006B13E8 /* Util.swift in Sources */, 330 | E69D36A121C63C0D003C80D2 /* UIView+Positioning.swift in Sources */, 331 | E611F60521C4F8AF00B4FAA0 /* ViewController.swift in Sources */, 332 | E664EBC821F878F4007123FE /* CustomLayerInstruction.swift in Sources */, 333 | E69CE85D21C50811006B13E8 /* Sticker.swift in Sources */, 334 | E664EBC721F878F4007123FE /* CustomVideoCompositor.swift in Sources */, 335 | E69D369F21C63392003C80D2 /* ResizableSlider.swift in Sources */, 336 | E69CE86121C50840006B13E8 /* StickerWrapView.swift in Sources */, 337 | E69D369D21C63268003C80D2 /* VideoPreview.swift in Sources */, 338 | E611F60321C4F8AF00B4FAA0 /* AppDelegate.swift in Sources */, 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | /* End PBXSourcesBuildPhase section */ 343 | 344 | /* Begin PBXVariantGroup section */ 345 | E611F60621C4F8AF00B4FAA0 /* Main.storyboard */ = { 346 | isa = PBXVariantGroup; 347 | children = ( 348 | E611F60721C4F8AF00B4FAA0 /* Base */, 349 | ); 350 | name = Main.storyboard; 351 | sourceTree = ""; 352 | }; 353 | E611F60B21C4F8B000B4FAA0 /* LaunchScreen.storyboard */ = { 354 | isa = PBXVariantGroup; 355 | children = ( 356 | E611F60C21C4F8B000B4FAA0 /* Base */, 357 | ); 358 | name = LaunchScreen.storyboard; 359 | sourceTree = ""; 360 | }; 361 | /* End PBXVariantGroup section */ 362 | 363 | /* Begin XCBuildConfiguration section */ 364 | E611F60F21C4F8B000B4FAA0 /* Debug */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | ALWAYS_SEARCH_USER_PATHS = NO; 368 | CLANG_ANALYZER_NONNULL = YES; 369 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 371 | CLANG_CXX_LIBRARY = "libc++"; 372 | CLANG_ENABLE_MODULES = YES; 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | CLANG_ENABLE_OBJC_WEAK = YES; 375 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 376 | CLANG_WARN_BOOL_CONVERSION = YES; 377 | CLANG_WARN_COMMA = YES; 378 | CLANG_WARN_CONSTANT_CONVERSION = YES; 379 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 380 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 381 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 382 | CLANG_WARN_EMPTY_BODY = YES; 383 | CLANG_WARN_ENUM_CONVERSION = YES; 384 | CLANG_WARN_INFINITE_RECURSION = YES; 385 | CLANG_WARN_INT_CONVERSION = YES; 386 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 387 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 388 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 389 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 390 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 391 | CLANG_WARN_STRICT_PROTOTYPES = YES; 392 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 393 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 394 | CLANG_WARN_UNREACHABLE_CODE = YES; 395 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 396 | CODE_SIGN_IDENTITY = "iPhone Developer"; 397 | COPY_PHASE_STRIP = NO; 398 | DEBUG_INFORMATION_FORMAT = dwarf; 399 | ENABLE_STRICT_OBJC_MSGSEND = YES; 400 | ENABLE_TESTABILITY = YES; 401 | GCC_C_LANGUAGE_STANDARD = gnu11; 402 | GCC_DYNAMIC_NO_PIC = NO; 403 | GCC_NO_COMMON_BLOCKS = YES; 404 | GCC_OPTIMIZATION_LEVEL = 0; 405 | GCC_PREPROCESSOR_DEFINITIONS = ( 406 | "DEBUG=1", 407 | "$(inherited)", 408 | ); 409 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 410 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 411 | GCC_WARN_UNDECLARED_SELECTOR = YES; 412 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 413 | GCC_WARN_UNUSED_FUNCTION = YES; 414 | GCC_WARN_UNUSED_VARIABLE = YES; 415 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 416 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 417 | MTL_FAST_MATH = YES; 418 | ONLY_ACTIVE_ARCH = YES; 419 | SDKROOT = iphoneos; 420 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 422 | }; 423 | name = Debug; 424 | }; 425 | E611F61021C4F8B000B4FAA0 /* Release */ = { 426 | isa = XCBuildConfiguration; 427 | buildSettings = { 428 | ALWAYS_SEARCH_USER_PATHS = NO; 429 | CLANG_ANALYZER_NONNULL = YES; 430 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 431 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 432 | CLANG_CXX_LIBRARY = "libc++"; 433 | CLANG_ENABLE_MODULES = YES; 434 | CLANG_ENABLE_OBJC_ARC = YES; 435 | CLANG_ENABLE_OBJC_WEAK = YES; 436 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 437 | CLANG_WARN_BOOL_CONVERSION = YES; 438 | CLANG_WARN_COMMA = YES; 439 | CLANG_WARN_CONSTANT_CONVERSION = YES; 440 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 441 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 442 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 443 | CLANG_WARN_EMPTY_BODY = YES; 444 | CLANG_WARN_ENUM_CONVERSION = YES; 445 | CLANG_WARN_INFINITE_RECURSION = YES; 446 | CLANG_WARN_INT_CONVERSION = YES; 447 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 448 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 449 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 450 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 451 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 452 | CLANG_WARN_STRICT_PROTOTYPES = YES; 453 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 454 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 455 | CLANG_WARN_UNREACHABLE_CODE = YES; 456 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 457 | CODE_SIGN_IDENTITY = "iPhone Developer"; 458 | COPY_PHASE_STRIP = NO; 459 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 460 | ENABLE_NS_ASSERTIONS = NO; 461 | ENABLE_STRICT_OBJC_MSGSEND = YES; 462 | GCC_C_LANGUAGE_STANDARD = gnu11; 463 | GCC_NO_COMMON_BLOCKS = YES; 464 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 465 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 466 | GCC_WARN_UNDECLARED_SELECTOR = YES; 467 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 468 | GCC_WARN_UNUSED_FUNCTION = YES; 469 | GCC_WARN_UNUSED_VARIABLE = YES; 470 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 471 | MTL_ENABLE_DEBUG_INFO = NO; 472 | MTL_FAST_MATH = YES; 473 | SDKROOT = iphoneos; 474 | SWIFT_COMPILATION_MODE = wholemodule; 475 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 476 | VALIDATE_PRODUCT = YES; 477 | }; 478 | name = Release; 479 | }; 480 | E611F61221C4F8B000B4FAA0 /* Debug */ = { 481 | isa = XCBuildConfiguration; 482 | baseConfigurationReference = 8E1DF4586636AF0E4A2FD818 /* Pods-LottieInVideo.debug.xcconfig */; 483 | buildSettings = { 484 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 485 | CODE_SIGN_STYLE = Automatic; 486 | DEVELOPMENT_TEAM = 3A75DREAB8; 487 | INFOPLIST_FILE = LottieInVideo/Info.plist; 488 | LD_RUNPATH_SEARCH_PATHS = ( 489 | "$(inherited)", 490 | "@executable_path/Frameworks", 491 | ); 492 | PRODUCT_BUNDLE_IDENTIFIER = com.lvpengwei.LottieInVideo; 493 | PRODUCT_NAME = "$(TARGET_NAME)"; 494 | SWIFT_VERSION = 4.2; 495 | TARGETED_DEVICE_FAMILY = "1,2"; 496 | }; 497 | name = Debug; 498 | }; 499 | E611F61321C4F8B000B4FAA0 /* Release */ = { 500 | isa = XCBuildConfiguration; 501 | baseConfigurationReference = 48A383B9FB37A398635568D2 /* Pods-LottieInVideo.release.xcconfig */; 502 | buildSettings = { 503 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 504 | CODE_SIGN_STYLE = Automatic; 505 | DEVELOPMENT_TEAM = 3A75DREAB8; 506 | INFOPLIST_FILE = LottieInVideo/Info.plist; 507 | LD_RUNPATH_SEARCH_PATHS = ( 508 | "$(inherited)", 509 | "@executable_path/Frameworks", 510 | ); 511 | PRODUCT_BUNDLE_IDENTIFIER = com.lvpengwei.LottieInVideo; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | SWIFT_VERSION = 4.2; 514 | TARGETED_DEVICE_FAMILY = "1,2"; 515 | }; 516 | name = Release; 517 | }; 518 | /* End XCBuildConfiguration section */ 519 | 520 | /* Begin XCConfigurationList section */ 521 | E611F5FA21C4F8AF00B4FAA0 /* Build configuration list for PBXProject "LottieInVideo" */ = { 522 | isa = XCConfigurationList; 523 | buildConfigurations = ( 524 | E611F60F21C4F8B000B4FAA0 /* Debug */, 525 | E611F61021C4F8B000B4FAA0 /* Release */, 526 | ); 527 | defaultConfigurationIsVisible = 0; 528 | defaultConfigurationName = Release; 529 | }; 530 | E611F61121C4F8B000B4FAA0 /* Build configuration list for PBXNativeTarget "LottieInVideo" */ = { 531 | isa = XCConfigurationList; 532 | buildConfigurations = ( 533 | E611F61221C4F8B000B4FAA0 /* Debug */, 534 | E611F61321C4F8B000B4FAA0 /* Release */, 535 | ); 536 | defaultConfigurationIsVisible = 0; 537 | defaultConfigurationName = Release; 538 | }; 539 | /* End XCConfigurationList section */ 540 | }; 541 | rootObject = E611F5F721C4F8AF00B4FAA0 /* Project object */; 542 | } 543 | -------------------------------------------------------------------------------- /LottieInVideo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LottieInVideo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LottieInVideo.xcodeproj/xcuserdata/lvpengwei.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LottieInVideo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 9 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LottieInVideo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LottieInVideo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LottieInVideo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // LottieInVideo 4 | // 5 | // Created by lvpengwei on 2018/12/15. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/asset_slider_thumb.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "knob.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/asset_slider_thumb.imageset/knob.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvpengwei/LottieInVideo/2c470a3bdda73b33f733cddd726f95a8c4eaffd6/LottieInVideo/Assets.xcassets/asset_slider_thumb.imageset/knob.pdf -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/icon_pause.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icPause.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/icon_pause.imageset/icPause.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvpengwei/LottieInVideo/2c470a3bdda73b33f733cddd726f95a8c4eaffd6/LottieInVideo/Assets.xcassets/icon_pause.imageset/icPause.pdf -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/icon_play.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icPlaySmall.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/icon_play.imageset/icPlaySmall.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvpengwei/LottieInVideo/2c470a3bdda73b33f733cddd726f95a8c4eaffd6/LottieInVideo/Assets.xcassets/icon_play.imageset/icPlaySmall.pdf -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/sticker_drag.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "editorElementsExpand.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /LottieInVideo/Assets.xcassets/sticker_drag.imageset/editorElementsExpand.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvpengwei/LottieInVideo/2c470a3bdda73b33f733cddd726f95a8c4eaffd6/LottieInVideo/Assets.xcassets/sticker_drag.imageset/editorElementsExpand.pdf -------------------------------------------------------------------------------- /LottieInVideo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /LottieInVideo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 35 | 42 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/Editor/CustomLayerInstruction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomLayerInstruction.swift 3 | // MixPhotoAndVideo 4 | // 5 | // Created by lvpengwei on 2018/12/26. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | import CoreImage 11 | import UIKit 12 | 13 | public class TimeRangeStore { 14 | public init() {} 15 | private(set) var data: [(CMTimeRange, T)] = [] 16 | public func setItem(_ item: T, timeRange: CMTimeRange, at index: Int = -1) { 17 | if index >= 0, index < data.count { 18 | data.insert((timeRange, item), at: index) 19 | } else { 20 | data.append((timeRange, item)) 21 | } 22 | } 23 | @discardableResult 24 | public func remove(at index: Int) -> (CMTimeRange, T) { 25 | return data.remove(at: index) 26 | } 27 | public func getItems(at time: CMTime) -> [(CMTimeRange, T)] { 28 | var result = [(CMTimeRange, T)]() 29 | data.forEach { (item) in 30 | if item.0.containsTime(time) { 31 | result.append(item) 32 | } 33 | } 34 | return result 35 | } 36 | public func getItems(at timeRange: CMTimeRange) -> [(CMTimeRange, T)] { 37 | var result = [(CMTimeRange, T)]() 38 | data.forEach { (item) in 39 | if item.0.intersection(timeRange).duration.seconds > 0 { 40 | result.append(item) 41 | } 42 | } 43 | 44 | return result 45 | } 46 | } 47 | 48 | public protocol ImageProvider: class { 49 | 50 | /// 根据时间渲染出 CIImage 51 | /// 52 | /// - Parameters: 53 | /// - time: 当前显示到的时间点 54 | /// - renderSize: 渲染画布尺寸 55 | /// - presentationTimeRange: 这个 ImageProvider 显示的时间段 56 | /// - Returns: CIImage 57 | func image(at time: CMTime, renderSize: CGSize, presentationTimeRange: CMTimeRange) -> CIImage? 58 | 59 | } 60 | 61 | public class CustomLayerInstruction: AVMutableVideoCompositionLayerInstruction { 62 | public override func copy(with zone: NSZone? = nil) -> Any { 63 | return self 64 | } 65 | public var overlayStore = TimeRangeStore() 66 | func apply(request: AVAsynchronousVideoCompositionRequest, sourceImage: CIImage) -> CIImage { 67 | var sourceImage = sourceImage 68 | if let sourcePixel = request.sourceFrame(byTrackID: trackID) { 69 | sourceImage = CIImage(cvPixelBuffer: sourcePixel).composited(over: sourceImage) 70 | } 71 | let compositionTime = request.compositionTime 72 | let renderSize = request.renderContext.size 73 | 74 | var flipYTransform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: sourceImage.extent.origin.y * 2 + sourceImage.extent.height) // 反转Y轴 75 | sourceImage = sourceImage.transformed(by: flipYTransform) 76 | var timeRange = CMTimeRange.zero 77 | var result = false 78 | 79 | // Crop 80 | let originalRect = sourceImage.extent 81 | var startCropRect = CGRect.zero 82 | var endCropRect = CGRect.zero 83 | result = getCropRectangleRamp(for: compositionTime, startCropRectangle: &startCropRect, endCropRectangle: &endCropRect, timeRange: &timeRange) 84 | if (timeRange.containsTime(compositionTime) && result && !startCropRect.equalTo(originalRect)) { 85 | sourceImage = sourceImage.cropped(to: startCropRect) 86 | } 87 | 88 | // Transform 89 | var startTransform = CGAffineTransform.identity 90 | var endTransfrom = CGAffineTransform.identity 91 | var transform = CGAffineTransform.identity 92 | result = getTransformRamp(for: compositionTime, start: &startTransform, end: &endTransfrom, timeRange: &timeRange) 93 | transform = endTransfrom 94 | 95 | // Opacity 96 | var opacityStart: Float = 1 97 | var opacityEnd: Float = 1 98 | result = getOpacityRamp(for: compositionTime, startOpacity: &opacityStart, endOpacity: &opacityEnd, timeRange: &timeRange) 99 | var currentAlpha: Float = 1 100 | if (timeRange.containsTime(compositionTime) && result) { 101 | let elapsed = CMTimeSubtract(compositionTime, timeRange.start) 102 | let tweenFactor = CMTimeGetSeconds(elapsed) / CMTimeGetSeconds(timeRange.duration) 103 | currentAlpha = (opacityEnd - opacityStart) * (Float)(tweenFactor) + opacityStart 104 | } 105 | sourceImage = sourceImage.transformed(by: transform) 106 | flipYTransform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: sourceImage.extent.origin.y * 2 + sourceImage.extent.height) // 反转Y轴 107 | sourceImage = sourceImage.transformed(by: flipYTransform) 108 | if (currentAlpha != 1) { 109 | let colorMatrixFilter = CustomVideoCompositor.colorMatrixFilter 110 | colorMatrixFilter.setDefaults() 111 | colorMatrixFilter.setValue(CIVector(x: 0, y: 0, z: 0, w: (CGFloat)(currentAlpha)), forKey: "inputAVector") 112 | colorMatrixFilter.setValue(sourceImage, forKey: "inputImage") 113 | if let image = colorMatrixFilter.outputImage { 114 | sourceImage = image 115 | } 116 | } 117 | let overlays = overlayStore.getItems(at: compositionTime) 118 | overlays.forEach { (overlayInfo) in 119 | if let overlayImage = overlayInfo.1.image(at: compositionTime, renderSize: renderSize, presentationTimeRange: overlayInfo.0) { 120 | sourceImage = overlayImage.composited(over: sourceImage) 121 | } 122 | } 123 | return sourceImage 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/Editor/CustomVideoCompositor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomVideoCompositor.swift 3 | // MixPhotoAndVideo 4 | // 5 | // Created by lvpengwei on 2018/12/26. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import AVFoundation 12 | import CoreImage 13 | 14 | class CustomVideoCompositor: NSObject, AVFoundation.AVVideoCompositing { 15 | 16 | override public init() { 17 | super.init() 18 | } 19 | 20 | private static let eaglContext = EAGLContext(api: EAGLRenderingAPI.openGLES2) 21 | public static let ciContext: CIContext = { 22 | let options = [ CIContextOption.workingColorSpace: NSNull(), CIContextOption.outputColorSpace: NSNull(), CIContextOption.useSoftwareRenderer: false ] as [CIContextOption : Any] 23 | return CIContext(eaglContext: eaglContext!, options: options) 24 | }() 25 | static let colorMatrixFilter: CIFilter = { 26 | return CIFilter(name: "CIColorMatrix")! 27 | }() 28 | 29 | private let renderContextQueue: DispatchQueue = DispatchQueue(label: "videoedit.rendercontextqueue") 30 | private let renderingQueue: DispatchQueue = DispatchQueue(label: "videoedit.renderingqueue") 31 | private var renderContextDidChange = false 32 | private var shouldCancelAllRequests = false 33 | private var renderContext: AVVideoCompositionRenderContext? 34 | 35 | public var sourcePixelBufferAttributes: [String: Any]? { 36 | return [String(kCVPixelBufferPixelFormatTypeKey): kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, 37 | String(kCVPixelBufferOpenGLESCompatibilityKey): true] 38 | } 39 | 40 | public var requiredPixelBufferAttributesForRenderContext: [String: Any] { 41 | return [String(kCVPixelBufferPixelFormatTypeKey): kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, 42 | String(kCVPixelBufferOpenGLESCompatibilityKey): true] 43 | } 44 | 45 | public func renderContextChanged(_ newRenderContext: AVVideoCompositionRenderContext) { 46 | renderContextQueue.sync { [weak self] in 47 | guard let strongSelf = self else { return } 48 | strongSelf.renderContext = newRenderContext 49 | strongSelf.renderContextDidChange = true 50 | } 51 | } 52 | 53 | public func startRequest(_ request: AVAsynchronousVideoCompositionRequest) { 54 | renderingQueue.async { [weak self] in 55 | guard let strongSelf = self else { return } 56 | if strongSelf.shouldCancelAllRequests { 57 | request.finishCancelledRequest() 58 | } else { 59 | autoreleasepool(invoking: { () -> () in 60 | do { 61 | if let resultPixels = try strongSelf.newRenderedPixelBufferForRequest(request: request) { 62 | request.finish(withComposedVideoFrame: resultPixels) 63 | } else { 64 | request.finishCancelledRequest() 65 | } 66 | } catch let e { 67 | request.finish(with: e) 68 | } 69 | }) 70 | } 71 | } 72 | } 73 | 74 | public func cancelAllPendingVideoCompositionRequests() { 75 | shouldCancelAllRequests = true 76 | renderingQueue.async(flags: .barrier) { [weak self] in 77 | guard let strongSelf = self else { return } 78 | strongSelf.shouldCancelAllRequests = false 79 | } 80 | } 81 | 82 | public func newRenderedPixelBufferForRequest(request: AVAsynchronousVideoCompositionRequest) throws -> CVPixelBuffer? { 83 | guard let renderContext = renderContext else { 84 | let e = NSError(domain: "videoedit.customvideocompositor", code: 1000, userInfo: nil) 85 | throw e 86 | } 87 | guard let outputPixels = renderContext.newPixelBuffer() else { 88 | return nil 89 | } 90 | 91 | var image = CIImage(cvPixelBuffer: outputPixels) 92 | 93 | let backgroundColor = CIColor(color: UIColor.black) 94 | let backgroundImage = CIImage(color: backgroundColor).cropped(to: image.extent) 95 | image = backgroundImage.composited(over: image) 96 | 97 | let instruction = request.videoCompositionInstruction as! AVVideoCompositionInstruction 98 | instruction.layerInstructions.forEach { (layerInstruction) in 99 | guard let layerInstruction = layerInstruction as? CustomLayerInstruction else { return } 100 | image = layerInstruction.apply(request: request, sourceImage: image) 101 | } 102 | CustomVideoCompositor.ciContext.render(image, to: outputPixels) 103 | 104 | return outputPixels 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/ResizableSlider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ResizableSlider.swift 3 | // LottieInVideo 4 | // 5 | // Created by lvpengwei on 2018/12/16. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ResizableSlider: UISlider { 12 | 13 | var trackHeight: CGFloat = 2 { 14 | didSet { 15 | setNeedsLayout() 16 | } 17 | } 18 | 19 | override func trackRect(forBounds bounds: CGRect) -> CGRect { 20 | var rect = super.trackRect(forBounds: bounds) 21 | rect.size.height = trackHeight 22 | rect.origin.y = (bounds.height - trackHeight) * 0.5 23 | return rect 24 | } 25 | 26 | } 27 | 28 | extension ResizableSlider { 29 | static func editorSlider() -> ResizableSlider { 30 | let slider = ResizableSlider() 31 | slider.trackHeight = 4 32 | 33 | slider.minimumValue = 0 34 | slider.maximumValue = 2 35 | slider.minimumTrackTintColor = UIColor.iosBrownishGrey 36 | slider.maximumTrackTintColor = UIColor.iosBlack 37 | slider.setThumbImage(#imageLiteral(resourceName: "asset_slider_thumb"), for: .normal) 38 | 39 | return slider 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/Sticker/Model/Sticker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sticker.swift 3 | // LottieInVideo 4 | // 5 | // Created by lvpengwei on 2018/12/15. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import AVFoundation 12 | 13 | class Sticker { 14 | var url = "" 15 | var centerX: CGFloat = 50 16 | var centerY: CGFloat = 50 17 | var width: CGFloat = 100 18 | var transform: CGAffineTransform = .identity 19 | var compSize: CGSize = .zero 20 | var aspectRatio: CGFloat { // 宽高比 21 | get { 22 | if compSize == .zero { 23 | return 100 24 | } 25 | return (compSize.width / compSize.height) * 100 26 | } 27 | } 28 | @objc dynamic var range: CMTimeRange = CMTimeRange.zero 29 | @objc dynamic var speed: Float = 1 30 | 31 | func bounds(containerBounds: CGRect) -> CGRect { 32 | var newWidth = containerBounds.width * width / 100 33 | var newHeight = newWidth / (aspectRatio / 100) 34 | if newHeight > containerBounds.height { 35 | newHeight = containerBounds.height 36 | newWidth = newHeight * (aspectRatio / 100) 37 | } 38 | return CGRect(x: 0, y: 0, width: newWidth, height: newHeight) 39 | } 40 | 41 | func setBounds(_ bounds: CGRect, containerBounds: CGRect) { 42 | width = bounds.width / containerBounds.width * 100 43 | } 44 | 45 | func center(containerBounds: CGRect) -> CGPoint { 46 | let newCenterX = containerBounds.width * centerX / 100 47 | let newCenterY = containerBounds.height * centerY / 100 48 | return CGPoint(x: newCenterX, y: newCenterY) 49 | } 50 | 51 | func setCenter(_ center: CGPoint, containerBounds: CGRect) { 52 | centerX = center.x / containerBounds.width * 100 53 | centerY = center.y / containerBounds.height * 100 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/Sticker/View/StickerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StickerView.swift 3 | // XDtv 4 | // 5 | // Created by lvpengwei on 19/02/2017. 6 | // Copyright © 2017 xiaodao.tv. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import AVFoundation 12 | 13 | private func CGRectGetCenter(rect: CGRect) -> CGPoint { 14 | return CGPoint(x: rect.midX, y: rect.midY) 15 | } 16 | private func CGRectScale(rect: CGRect, wScale: CGFloat, hScale: CGFloat) -> CGRect { 17 | return CGRect(x: rect.origin.x * wScale, 18 | y: rect.origin.y * hScale, 19 | width: rect.size.width * wScale, 20 | height: rect.size.height * hScale) 21 | } 22 | private func CGPointGetDistance(point1: CGPoint, point2: CGPoint) -> CGFloat { 23 | let fx = point2.x - point1.x 24 | let fy = point2.y - point1.y 25 | return sqrt(fx*fx + fy*fy) 26 | } 27 | private func CGAffineTransformGetAngle(t: CGAffineTransform) -> CGFloat { 28 | return atan2(t.b, t.a) 29 | } 30 | 31 | class StickerView: StickerWrapView, UIGestureRecognizerDelegate { 32 | private var beginningPoint: CGPoint = .zero 33 | private var beginningCenter: CGPoint = .zero 34 | @objc private func handleMoveAction(_ recognizer: UIPanGestureRecognizer) { 35 | guard let superview = superview else { return } 36 | let touchLocation = recognizer.location(in: superview) 37 | if recognizer.state == .began { 38 | beginningPoint = touchLocation 39 | beginningCenter = center 40 | } else if recognizer.state == .changed { 41 | let xSpacing: CGFloat = 0 42 | let ySpacing: CGFloat = 0 43 | var x = beginningCenter.x + (touchLocation.x - beginningPoint.x) 44 | x = x < xSpacing ? xSpacing : min(x, superview.bounds.width - xSpacing) 45 | var y = beginningCenter.y + (touchLocation.y - beginningPoint.y) 46 | y = y < ySpacing ? ySpacing : min(y, superview.bounds.height - ySpacing) 47 | center = CGPoint(x: x, y: y) 48 | } else if recognizer.state == .cancelled || recognizer.state == .failed || recognizer.state == .ended { 49 | } 50 | } 51 | 52 | private var deltaAngle: CGFloat = 0 53 | private var initialBounds: CGRect = .zero 54 | private var initialDistance: CGFloat = 0 55 | @objc private func handlePanAction(_ recognizer: UIPanGestureRecognizer) { 56 | guard let superview = superview else { return } 57 | let touchLocation = recognizer.location(in: superview) 58 | let center = CGRectGetCenter(rect: frame) 59 | if recognizer.state == .began { 60 | deltaAngle = atan2(touchLocation.y - center.y, touchLocation.x - center.x) - CGAffineTransformGetAngle(t: transform) 61 | initialBounds = bounds 62 | initialDistance = CGPointGetDistance(point1: center, point2: touchLocation) 63 | } else if recognizer.state == .changed { 64 | let ang = atan2(touchLocation.y - center.y, touchLocation.x - center.x) 65 | let angleDiff = deltaAngle - ang 66 | transform = CGAffineTransform(rotationAngle: -angleDiff) 67 | let scale = sqrt(CGPointGetDistance(point1: center, point2: touchLocation) / initialDistance) 68 | let scaleRect = CGRectScale(rect: initialBounds, wScale: scale, hScale: scale) 69 | bounds = CGRect(x: 0, y: 0, width: scaleRect.size.width, height: scaleRect.size.height) 70 | } else if recognizer.state == .cancelled || recognizer.state == .failed || recognizer.state == .ended { 71 | } 72 | } 73 | 74 | override func layoutSubviews() { 75 | if let superview = superview { 76 | let stickerBounds = sticker.bounds(containerBounds: superview.bounds) 77 | let wrapBounds = CGRect(x: 0, y: 0, width: stickerBounds.width + padding * 2, height: stickerBounds.height + padding * 2) 78 | if !bounds.equals(wrapBounds) { 79 | bounds = wrapBounds 80 | } 81 | if !center.equals(sticker.center(containerBounds: superview.bounds)) { 82 | center = sticker.center(containerBounds: superview.bounds) 83 | } 84 | if transform != sticker.transform { 85 | transform = sticker.transform 86 | } 87 | } 88 | super.layoutSubviews() 89 | CATransaction.begin() 90 | CATransaction.setDisableActions(true) 91 | rotateImageView.bounds = CGRect(x: 0, y: 0, width: padding * 2, height: padding * 2) 92 | rotateImageView.center = CGPoint(x: bounds.width - padding, y: bounds.height - padding) 93 | borderLayer.bounds = bounds.insetBy(dx: padding, dy: padding) 94 | borderLayer.position = CGPoint(x: bounds.midX, y: bounds.midY) 95 | if let borderLayer = borderLayer as? CAShapeLayer { 96 | borderLayer.path = UIBezierPath.init(rect: borderLayer.bounds).cgPath 97 | } 98 | CATransaction.commit() 99 | } 100 | 101 | override var bounds: CGRect { 102 | didSet { 103 | if let superview = superview { 104 | sticker.setBounds(bounds.insetBy(dx: padding, dy: padding), containerBounds: superview.bounds) 105 | } 106 | } 107 | } 108 | 109 | override var center: CGPoint { 110 | didSet { 111 | if let superview = superview { 112 | sticker.setCenter(center, containerBounds: superview.bounds) 113 | } 114 | } 115 | } 116 | 117 | override var transform: CGAffineTransform { 118 | didSet { 119 | sticker.transform = transform 120 | } 121 | } 122 | 123 | var isSelected: Bool = true { 124 | didSet { 125 | updateUI() 126 | } 127 | } 128 | var movable: Bool = true { 129 | didSet { 130 | panGestureRecognizer.isEnabled = movable 131 | } 132 | } 133 | var scalable: Bool = true { 134 | didSet { 135 | rotateImageView.isUserInteractionEnabled = scalable 136 | updateUI() 137 | } 138 | } 139 | 140 | private func updateUI() { 141 | if isSelected { 142 | borderLayer.isHidden = false 143 | rotateImageView.isHidden = !scalable 144 | } else { 145 | borderLayer.isHidden = true 146 | rotateImageView.isHidden = true 147 | } 148 | checkStickerLayer() 149 | } 150 | 151 | fileprivate func checkStickerLayer() { 152 | CATransaction.begin() 153 | CATransaction.setDisableActions(true) 154 | stickerLayer.isHidden = false 155 | CATransaction.commit() 156 | } 157 | 158 | override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { 159 | if gestureRecognizer == panGestureRecognizer { 160 | if isSelected { 161 | return true 162 | } else { 163 | return false 164 | } 165 | } 166 | return super.gestureRecognizerShouldBegin(gestureRecognizer) 167 | } 168 | 169 | private var rotateImageView: UIImageView! 170 | private var borderLayer: CALayer! 171 | var sticker: Sticker 172 | var timeOffset: CMTime 173 | private var panGestureRecognizer: UIPanGestureRecognizer! 174 | 175 | init(sticker: Sticker, timeOffset: CMTime = CMTime.zero) { 176 | self.sticker = sticker 177 | self.timeOffset = timeOffset 178 | var stickerJSON: [ String: Any ] = [:] 179 | let animationLayer = CALayer.animation(withPath: sticker.url) 180 | sticker.compSize = animationLayer.compSize() 181 | let stickerLayer = StickerLayer.init(animationLayer: animationLayer) 182 | 183 | super.init(stickerLayer: stickerLayer) 184 | 185 | padding = 15 186 | 187 | let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleMoveAction(_:))) 188 | panGestureRecognizer.delegate = self 189 | addGestureRecognizer(panGestureRecognizer) 190 | self.panGestureRecognizer = panGestureRecognizer 191 | 192 | let borderLayer = CALayer() 193 | borderLayer.borderWidth = 2 194 | borderLayer.borderColor = UIColor.xd_03a9f4.cgColor 195 | borderLayer.zPosition = 1 196 | borderLayer.cornerRadius = 4 197 | borderLayer.masksToBounds = true 198 | layer.addSublayer(borderLayer) 199 | self.borderLayer = borderLayer 200 | 201 | let dragImageView = UIImageView() 202 | dragImageView.contentMode = .center 203 | dragImageView.image = #imageLiteral(resourceName: "sticker_drag") 204 | dragImageView.isUserInteractionEnabled = true 205 | dragImageView.layer.zPosition = 2 206 | addSubview(dragImageView) 207 | self.rotateImageView = dragImageView 208 | dragImageView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePanAction(_:)))) 209 | 210 | stickerLayer.isHidden = true 211 | updateLayerRange() 212 | updateUI() 213 | } 214 | func layoutForPreview() { 215 | self.borderLayer.removeFromSuperlayer() 216 | 217 | let borderLayer = CAShapeLayer() 218 | borderLayer.lineWidth = 4 219 | borderLayer.lineDashPattern = [2, 2] 220 | borderLayer.fillColor = UIColor.clear.cgColor 221 | borderLayer.strokeColor = UIColor.init(hex6: 0x03a9f4, alpha: 0.63).cgColor 222 | borderLayer.zPosition = 1 223 | borderLayer.cornerRadius = 4 224 | borderLayer.masksToBounds = true 225 | layer.addSublayer(borderLayer) 226 | self.borderLayer = borderLayer 227 | } 228 | private func exchange(layer1: CALayer, layer2: CALayer) { 229 | layer2.bounds = layer1.bounds 230 | layer2.position = layer1.position 231 | layer2.isHidden = layer1.isHidden 232 | layer2.setAffineTransform(layer1.affineTransform()) 233 | layer1.superlayer?.addSublayer(layer2) 234 | layer1.removeFromSuperlayer() 235 | } 236 | private var isDragging: Bool = false 237 | private func updateLayerRange() { 238 | guard let stickerLayer = stickerLayer as? StickerLayer else { return } 239 | stickerLayer.animationLayer.beginTime = timeOffset.seconds + sticker.range.start.seconds / Double(sticker.speed) 240 | stickerLayer.animationLayer.duration = sticker.range.duration.seconds 241 | stickerLayer.animationLayer.speed = sticker.speed 242 | } 243 | required init?(coder aDecoder: NSCoder) { 244 | fatalError("init(coder:) has not been implemented") 245 | } 246 | } 247 | 248 | class StickerLayer: AVSynchronizedLayer { 249 | var animationLayer: CALayer 250 | init(animationLayer: CALayer) { 251 | self.animationLayer = animationLayer 252 | super.init() 253 | addSublayer(animationLayer) 254 | } 255 | override var bounds: CGRect { 256 | didSet { 257 | CATransaction.begin() 258 | CATransaction.setDisableActions(true) 259 | let scale = bounds.width / animationLayer.bounds.width 260 | animationLayer.setAffineTransform(CGAffineTransform.init(scaleX: scale, y: scale)) 261 | animationLayer.position = CGPoint(x: bounds.midX, y: bounds.midY) 262 | CATransaction.commit() 263 | } 264 | } 265 | required init?(coder aDecoder: NSCoder) { 266 | fatalError("init(coder:) has not been implemented") 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/Sticker/View/StickerWrapView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StickerWrapView.swift 3 | // XDtv 4 | // 5 | // Created by lvpengwei on 19/02/2017. 6 | // Copyright © 2017 xiaodao.tv. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class StickerWrapView: UIView { 13 | 14 | var padding: CGFloat = 0 15 | var stickerLayer: CALayer 16 | 17 | init(stickerLayer: CALayer) { 18 | self.stickerLayer = stickerLayer 19 | super.init(frame: .zero) 20 | } 21 | 22 | required init?(coder aDecoder: NSCoder) { 23 | fatalError("init(coder:) has not been implemented") 24 | } 25 | 26 | override var bounds: CGRect { 27 | didSet { 28 | CATransaction.begin() 29 | CATransaction.setDisableActions(true) 30 | stickerLayer.bounds = bounds.insetBy(dx: padding, dy: padding) 31 | CATransaction.commit() 32 | } 33 | } 34 | 35 | override var center: CGPoint { 36 | didSet { 37 | CATransaction.begin() 38 | CATransaction.setDisableActions(true) 39 | stickerLayer.position = center 40 | CATransaction.commit() 41 | } 42 | } 43 | 44 | override var transform: CGAffineTransform { 45 | didSet { 46 | CATransaction.begin() 47 | CATransaction.setDisableActions(true) 48 | stickerLayer.setAffineTransform(transform) 49 | CATransaction.commit() 50 | } 51 | } 52 | 53 | override func addSubview(_ view: UIView) { 54 | super.addSubview(view) 55 | if let view = view as? StickerWrapView { 56 | stickerLayer.addSublayer(view.stickerLayer) 57 | } 58 | } 59 | 60 | override func insertSubview(_ view: UIView, at index: Int) { 61 | super.insertSubview(view, at: index) 62 | if let view = view as? StickerWrapView { 63 | stickerLayer.insertSublayer(view.stickerLayer, at: UInt32(index)) 64 | } 65 | } 66 | 67 | override func removeFromSuperview() { 68 | super.removeFromSuperview() 69 | stickerLayer.removeFromSuperlayer() 70 | } 71 | 72 | override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { 73 | if isHidden { 74 | return nil 75 | } 76 | var view = super.hitTest(point, with: event) 77 | if view == nil { 78 | for subview in subviews { 79 | if let subview = subview as? StickerWrapView, !subview.isHidden { 80 | if subview.frame.contains(point) { 81 | view = subview 82 | break 83 | } 84 | } 85 | } 86 | } 87 | return view 88 | } 89 | 90 | override func layoutSubviews() { 91 | super.layoutSubviews() 92 | CATransaction.begin() 93 | CATransaction.setDisableActions(true) 94 | stickerLayer.bounds = bounds.insetBy(dx: padding, dy: padding) 95 | stickerLayer.position = center 96 | stickerLayer.setAffineTransform(transform) 97 | CATransaction.commit() 98 | } 99 | 100 | } 101 | 102 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/UIView+Positioning.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Positioning.swift 3 | // 4 | // Created by Shai Mishali on 1/19/15. 5 | // Copyright (c) 2015 Shai Mishali. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIView { 11 | // MARK: - Basic Properties 12 | 13 | /// X Axis value of UIView. 14 | var x: CGFloat { 15 | set { self.frame = CGRect(x: _pixelIntegral(newValue), y: self.y, width: self.width, height: self.height) } 16 | get { return self.frame.origin.x } 17 | } 18 | 19 | /// Y Axis value of UIView. 20 | var y: CGFloat { 21 | set { self.frame = CGRect(x: self.x, y: _pixelIntegral(newValue), width: self.width, height: self.height) } 22 | get { return self.frame.origin.y } 23 | } 24 | 25 | /// Width of view. 26 | var width: CGFloat { 27 | set { self.frame = CGRect(x: self.x, y: self.y, width: _pixelIntegral(newValue), height: self.height) } 28 | get { return self.frame.size.width } 29 | } 30 | 31 | /// Height of view. 32 | var height: CGFloat { 33 | set { self.frame = CGRect(x: self.x, y: self.y, width: self.width, height: _pixelIntegral(newValue)) } 34 | get { return self.frame.size.height } 35 | } 36 | 37 | // MARK: - Origin and Size 38 | 39 | /// View's Origin point. 40 | var origin: CGPoint { 41 | set { self.frame = CGRect(x: _pixelIntegral(newValue.x), y: _pixelIntegral(newValue.y), width: self.width, height: self.height) } 42 | get { return self.frame.origin } 43 | } 44 | 45 | /// View's size. 46 | var size: CGSize{ 47 | set { self.frame = CGRect(x: self.x, y: self.y, width: _pixelIntegral(newValue.width), height: _pixelIntegral(newValue.height)) } 48 | get { return self.frame.size } 49 | } 50 | 51 | // MARK: - Extra Properties 52 | 53 | /// View's right side (x + width). 54 | var right: CGFloat{ 55 | set { self.x = newValue - self.width } 56 | get { return self.x + self.width } 57 | } 58 | 59 | /// View's bottom (y + height). 60 | var bottom: CGFloat{ 61 | set { self.y = newValue - self.height } 62 | get { return self.y + self.height } 63 | } 64 | 65 | /// View's top (y). 66 | var top: CGFloat { 67 | set { self.y = newValue } 68 | get { return self.y } 69 | } 70 | 71 | /// View's left side (x). 72 | var left: CGFloat { 73 | set { self.x = newValue } 74 | get { return self.x } 75 | } 76 | 77 | /// View's center X value (center.x). 78 | var centerX: CGFloat { 79 | set { self.center = CGPoint(x: newValue, y: self.centerY) } 80 | get { return self.center.x } 81 | } 82 | 83 | /// View's center Y value (center.y). 84 | var centerY: CGFloat { 85 | set { self.center = CGPoint(x: self.centerX, y: newValue) } 86 | get { return self.center.y } 87 | } 88 | 89 | /// Last subview on X Axis. 90 | var lastSubviewOnX:UIView?{ 91 | get { 92 | var outView:UIView = self.subviews[0] as UIView 93 | 94 | for v in self.subviews as [UIView] { 95 | if(v.x > outView.x){ outView = v } 96 | } 97 | 98 | return outView 99 | } 100 | } 101 | 102 | /// Last subview on Y Axis. 103 | var lastSubviewOnY:UIView?{ 104 | get { 105 | var outView:UIView = self.subviews[0] as UIView 106 | 107 | for v in self.subviews as [UIView] { 108 | if(v.y > outView.y){ outView = v } 109 | } 110 | 111 | return outView 112 | } 113 | } 114 | 115 | // MARK: - Bounds Methods 116 | 117 | /// X value of bounds (bounds.origin.x). 118 | var boundsX:CGFloat{ 119 | set{ self.bounds = CGRect(x: _pixelIntegral(newValue), y: self.boundsY, width: self.boundsWidth, height: self.boundsHeight) } 120 | get{ return self.bounds.origin.x } 121 | } 122 | 123 | /// Y value of bounds (bounds.origin.y). 124 | var boundsY:CGFloat{ 125 | set { self.frame = CGRect(x: self.boundsX, y: _pixelIntegral(newValue), width: self.boundsWidth, height: self.boundsHeight) } 126 | get { return self.bounds.origin.y } 127 | } 128 | 129 | /// Width of bounds (bounds.size.width). 130 | var boundsWidth: CGFloat{ 131 | set { self.frame = CGRect(x: self.boundsX, y: self.boundsY, width: _pixelIntegral(newValue), height: self.boundsHeight) } 132 | get { return self.bounds.size.width } 133 | } 134 | 135 | /// Height of bounds (bounds.size.height). 136 | var boundsHeight: CGFloat{ 137 | set { self.frame = CGRect(x: self.boundsX, y: self.boundsY, width: self.boundsWidth, height: _pixelIntegral(newValue)) } 138 | get { return self.bounds.size.height } 139 | } 140 | 141 | // MARK: - Useful Methods 142 | 143 | /// Center view to it's parent view. 144 | func centerToParent(){ 145 | if(self.superview != nil){ 146 | switch(UIApplication.shared.statusBarOrientation){ 147 | case .landscapeLeft: 148 | fallthrough 149 | case .landscapeRight: 150 | self.origin = CGPoint(x: (self.superview!.height / 2) - (self.width / 2), 151 | y: (self.superview!.width / 2) - (self.height / 2)) 152 | case .portrait: 153 | fallthrough 154 | case .portraitUpsideDown: 155 | self.origin = CGPoint(x: (self.superview!.width / 2) - (self.width / 2), 156 | y: (self.superview!.height / 2) - (self.height / 2)) 157 | case .unknown: 158 | return 159 | } 160 | } 161 | } 162 | 163 | // MARK: - Private Methods 164 | private func _pixelIntegral(_ pointValue:CGFloat) -> CGFloat{ 165 | let scale = UIScreen.main.scale 166 | return (round(pointValue * scale) / scale) 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/Util.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Util.swift 3 | // LottieInVideo 4 | // 5 | // Created by lvpengwei on 2018/12/15. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import AVFoundation 11 | import RxSwift 12 | import UIColor_Hex_Swift 13 | 14 | class Util { 15 | class var screenWidth: CGFloat { 16 | get { 17 | return UIScreen.main.bounds.width 18 | } 19 | } 20 | class var screenHeight: CGFloat { 21 | get { 22 | return UIScreen.main.bounds.height 23 | } 24 | } 25 | static let formatter: DateFormatter = { 26 | let formatter = DateFormatter() 27 | formatter.timeZone = TimeZone(identifier: "UTC")! 28 | formatter.dateFormat = "mm:ss" 29 | return formatter 30 | }() 31 | 32 | static func timeStringMMSS(duration: TimeInterval) -> String { 33 | return formatter.string(from: Date(timeIntervalSince1970: max(0, duration))) 34 | } 35 | } 36 | 37 | extension UIFont { 38 | 39 | class func xdFont(ofSize: CGFloat) -> UIFont { 40 | if let font = UIFont(name: "PingFangSC-Regular", size: ofSize) { 41 | return font 42 | } 43 | return UIFont.systemFont(ofSize: ofSize, weight: UIFont.Weight.regular) 44 | } 45 | 46 | class func lightXDFont(ofSize: CGFloat) -> UIFont { 47 | if let font = UIFont(name: "PingFangSC-Light", size: ofSize) { 48 | return font 49 | } 50 | return UIFont.systemFont(ofSize: ofSize, weight: UIFont.Weight.light) 51 | } 52 | 53 | class func boldXDFont(ofSize: CGFloat) -> UIFont { 54 | if let font = UIFont(name: "PingFangSC-Semibold", size: ofSize) { 55 | return font 56 | } 57 | return UIFont.systemFont(ofSize: ofSize, weight: UIFont.Weight.semibold) 58 | } 59 | 60 | } 61 | 62 | extension UIColor { 63 | 64 | class var xd_262626: UIColor { 65 | get { 66 | return UIColor.init(hex6: 0x262626) 67 | } 68 | } 69 | 70 | class var xd_00b1f7: UIColor { 71 | get { 72 | return UIColor.init(hex6: 0x00b1f7) 73 | } 74 | } 75 | 76 | class var xd_bcc1cc: UIColor { 77 | get { 78 | return UIColor.init(hex6: 0xbcc1cc) 79 | } 80 | } 81 | 82 | class var xd_e76464: UIColor { 83 | get { 84 | return UIColor.init(hex6: 0xe76464) 85 | } 86 | } 87 | 88 | class var xd_333333: UIColor { 89 | get { 90 | return UIColor.init(hex6: 0x333333) 91 | } 92 | } 93 | 94 | class var xd_efeff4: UIColor { 95 | get { 96 | return UIColor.init(hex6: 0xefeff4) 97 | } 98 | } 99 | 100 | class var xd_666666: UIColor { 101 | get { 102 | return UIColor.init(hex6: 0x666666) 103 | } 104 | } 105 | 106 | class var xd_fafafa: UIColor { 107 | get { 108 | return UIColor.init(hex6: 0xfafafa) 109 | } 110 | } 111 | 112 | class var xd_e9e9e9: UIColor { 113 | get { 114 | return UIColor.init(hex6: 0xe9e9e9) 115 | } 116 | } 117 | 118 | class var xd_ff981e: UIColor { 119 | get { 120 | return UIColor.init(hex6: 0xff981e) 121 | } 122 | } 123 | 124 | class var xd_555555: UIColor { 125 | get { 126 | return UIColor.init(hex6: 0x555555) 127 | } 128 | } 129 | 130 | class var xd_161616: UIColor { 131 | get { 132 | return UIColor.init(hex6: 0x161616) 133 | } 134 | } 135 | 136 | class var xd_8c8c8c: UIColor { 137 | get { 138 | return UIColor.init(hex6: 0x8c8c8c) 139 | } 140 | } 141 | 142 | class var xd_111111: UIColor { 143 | get { 144 | return UIColor.init(hex6: 0x111111) 145 | } 146 | } 147 | 148 | class var xd_19171a: UIColor { 149 | get { 150 | return UIColor.init(hex6: 0x19171a) 151 | } 152 | } 153 | 154 | class var xd_03a9f4: UIColor { 155 | get { 156 | return UIColor.init(hex6: 0x03a9f4) 157 | } 158 | } 159 | 160 | class var xd_999999: UIColor { 161 | get { 162 | return UIColor.init(hex6: 0x999999) 163 | } 164 | } 165 | 166 | class var xd_ff8080: UIColor { 167 | get { 168 | return UIColor.init(hex6: 0xff8080) 169 | } 170 | } 171 | 172 | class var xd_ff5050: UIColor { 173 | get { 174 | return UIColor.init(hex6: 0xff5050) 175 | } 176 | } 177 | 178 | class var xd_e5e6e8: UIColor { 179 | get { 180 | return UIColor.init(hex6: 0xe5e6e8) 181 | } 182 | } 183 | 184 | class var xd_878787: UIColor { 185 | get { 186 | return UIColor.init(hex6: 0x878787) 187 | } 188 | } 189 | 190 | class var xd_eaebed: UIColor { 191 | get { 192 | return UIColor.init(hex6: 0xeaebed) 193 | } 194 | } 195 | 196 | class var xd_eeeeee: UIColor { 197 | get { 198 | return UIColor.init(hex6: 0xeeeeee) 199 | } 200 | } 201 | 202 | class var xd_cccccc: UIColor { 203 | get { 204 | return UIColor.init(hex6: 0xcccccc) 205 | } 206 | } 207 | 208 | class var xd_383838: UIColor { 209 | get { 210 | return UIColor.init(hex6: 0x383838) 211 | } 212 | } 213 | 214 | // 编辑器 button 禁用状态的颜色 215 | class var xd_ve_btn_disabled: UIColor { 216 | return xd_333333 217 | } 218 | 219 | func image() -> UIImage? { 220 | let rect = CGRect(x: 0, y: 0, width: 1, height: 1) 221 | UIGraphicsBeginImageContext(rect.size) 222 | if let context = UIGraphicsGetCurrentContext() { 223 | context.setFillColor(cgColor) 224 | context.fill(rect) 225 | let image = UIGraphicsGetImageFromCurrentImageContext() 226 | UIGraphicsEndImageContext() 227 | return image 228 | } 229 | return nil 230 | } 231 | 232 | class var iosAzure: UIColor { 233 | return UIColor(red: 3.0 / 255.0, green: 169.0 / 255.0, blue: 244.0 / 255.0, alpha: 1.0) 234 | } 235 | class var iosGrapefruit: UIColor { 236 | return UIColor(red: 255.0 / 255.0, green: 80.0 / 255.0, blue: 80.0 / 255.0, alpha: 1.0) 237 | } 238 | class var iosPaleGrey: UIColor { 239 | return UIColor(red: 234.0 / 255.0, green: 235.0 / 255.0, blue: 237.0 / 255.0, alpha: 1.0) 240 | } 241 | class var iosWarmGrey: UIColor { 242 | return UIColor(white: 153.0 / 255.0, alpha: 1.0) 243 | } 244 | class var iosBlackThree: UIColor { 245 | return UIColor(white: 22.0 / 255.0, alpha: 1.0) 246 | } 247 | class var iosBlack: UIColor { 248 | return UIColor(white: 38.0 / 255.0, alpha: 1.0) 249 | } 250 | class var iosPinkishGrey: UIColor { 251 | return UIColor(white: 204.0 / 255.0, alpha: 1.0) 252 | } 253 | class var iosBrownishGrey: UIColor { 254 | return UIColor(white: 102.0 / 255.0, alpha: 1.0) 255 | } 256 | } 257 | 258 | extension CGRect { 259 | func equals(_ right: CGRect) -> Bool { 260 | return origin.equals(right.origin) && size.equals(right.size) 261 | } 262 | } 263 | 264 | extension CGPoint { 265 | func equals(_ right: CGPoint) -> Bool { 266 | return x.equals(right.x) && y.equals(right.y) 267 | } 268 | } 269 | 270 | extension CGSize { 271 | func equals(_ right: CGSize) -> Bool { 272 | return width.equals(right.width) && height.equals(right.width) 273 | } 274 | } 275 | 276 | extension CGFloat { 277 | func equals(_ right: CGFloat) -> Bool { 278 | return abs(self - right) < 0.01 279 | } 280 | } 281 | 282 | extension Float { 283 | func format(f: String) -> String { 284 | return String(format: "%\(f)f", self) 285 | } 286 | func equals(_ right: Float) -> Bool { 287 | return abs(self - right) < 0.01 288 | } 289 | } 290 | 291 | extension Double { 292 | func format(f: String) -> String { 293 | return String(format: "%\(f)f", self) 294 | } 295 | func equals(_ right: Double) -> Bool { 296 | return abs(self - right) < 0.01 297 | } 298 | } 299 | 300 | // MARK: RxSwift - ignoreNil 301 | public protocol OptionalType { 302 | associatedtype Wrapped 303 | 304 | var optional: Wrapped? { get } 305 | } 306 | 307 | extension Optional: OptionalType { 308 | public var optional: Wrapped? { return self } 309 | } 310 | 311 | // Unfortunately the extra type annotations are required, otherwise the compiler gives an incomprehensible error. 312 | extension Observable where Element: OptionalType { 313 | func ignoreNil() -> Observable { 314 | return flatMap { value in 315 | value.optional.map { Observable.just($0) } ?? Observable.empty() 316 | } 317 | } 318 | } 319 | 320 | extension AVPlayer { 321 | func xd_play() { 322 | guard currentItem != nil else { return } 323 | if rate != 0 { 324 | pause() 325 | } else if currentTime() == currentItem?.duration { 326 | fl_seekSmoothly(to: CMTime.zero) 327 | play() 328 | } else { 329 | play() 330 | } 331 | } 332 | } 333 | 334 | extension AVPlayerItem { 335 | func disPlaySize() -> CGSize { 336 | if let videoComposition = videoComposition { 337 | return videoComposition.renderSize 338 | } 339 | guard let track = asset.tracks(withMediaType: AVMediaType.video).first else { 340 | return .zero 341 | } 342 | let size = track.naturalSize.applying(track.preferredTransform) 343 | return CGSize(width: abs(size.width), height: abs(size.height)) 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /LottieInVideo/Classes/VideoPreview.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoPreview.swift 3 | // LottieInVideo 4 | // 5 | // Created by lvpengwei on 2018/12/16. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import RxSwift 11 | import RxCocoa 12 | import SnapKit 13 | import SCRecorder 14 | import AVFoundation 15 | import AVPlayerSeeker 16 | 17 | class VideoPreview: UIView { 18 | private var videoView: UIView! { 19 | return scFilterImageView 20 | } 21 | private weak var scFilterImageView: SCFilterImageView! 22 | let player = SCPlayer() 23 | private let playButton = UIButton() 24 | private let slider = ResizableSlider.editorSlider() 25 | private let leftTimeLabel = UILabel() 26 | private let rightTimeLabel = UILabel() 27 | private let stickerWrapLayer = CALayer() 28 | private var stickerWrapView: StickerWrapView! 29 | private let controlView = UIView() 30 | private var currentItem: AVPlayerItem? { 31 | return player.currentItem 32 | } 33 | @objc dynamic var hideStickerWrapView: Bool = false 34 | override init(frame: CGRect) { 35 | super.init(frame: frame) 36 | commonInit() 37 | } 38 | required init?(coder aDecoder: NSCoder) { 39 | super.init(coder: aDecoder) 40 | commonInit() 41 | } 42 | private func commonInit() { 43 | let scFilterImageView = SCFilterImageView() 44 | scFilterImageView.contentMode = .scaleAspectFit 45 | addSubview(scFilterImageView) 46 | self.scFilterImageView = scFilterImageView 47 | 48 | player.scImageView = scFilterImageView 49 | player.delegate = self 50 | player.beginSendingPlayMessages() 51 | 52 | stickerWrapLayer.masksToBounds = true 53 | layer.addSublayer(stickerWrapLayer) 54 | 55 | stickerWrapView = StickerWrapView(stickerLayer: stickerWrapLayer) 56 | stickerWrapView.clipsToBounds = true 57 | addSubview(stickerWrapView) 58 | 59 | controlView.isHidden = true 60 | controlView.backgroundColor = UIColor.xd_161616 61 | addSubview(controlView) 62 | 63 | playButton.isUserInteractionEnabled = false 64 | playButton.setImage(#imageLiteral(resourceName: "icon_play"), for: .normal) 65 | playButton.setImage(#imageLiteral(resourceName: "icon_pause"), for: .selected) 66 | playButton.contentEdgeInsets = UIEdgeInsets(top: 6, left: 6, bottom: 6, right: 6) 67 | controlView.addSubview(playButton) 68 | 69 | slider.maximumValue = 1 70 | slider.minimumTrackTintColor = UIColor.init(hex6: 0xffffff, alpha: 0.64) 71 | slider.maximumTrackTintColor = UIColor.init(hex6: 0xffffff, alpha: 0.16) 72 | slider.setThumbImage(#imageLiteral(resourceName: "asset_slider_thumb"), for: .normal) 73 | slider.addTarget(self, action: #selector(handleSliderValueChanged), for: .valueChanged) 74 | slider.addTarget(self, action: #selector(handleSliderTouchDown), for: .touchDown) 75 | slider.addTarget(self, action: #selector(handleSliderTouchUp), for: [.touchUpInside, .touchUpOutside, .touchCancel]) 76 | controlView.addSubview(slider) 77 | 78 | leftTimeLabel.font = UIFont.boldXDFont(ofSize: 11) 79 | leftTimeLabel.textAlignment = .left 80 | leftTimeLabel.textColor = .white 81 | leftTimeLabel.text = "00:00" 82 | controlView.addSubview(leftTimeLabel) 83 | 84 | rightTimeLabel.font = UIFont.boldXDFont(ofSize: 11) 85 | rightTimeLabel.textAlignment = .left 86 | rightTimeLabel.textColor = .white 87 | controlView.addSubview(rightTimeLabel) 88 | 89 | controlView.bounds = CGRect(x: 0, y: 0, width: Util.screenWidth, height: 32) 90 | 91 | playButton.snp.makeConstraints { make in 92 | make.leading.equalToSuperview().offset(9) 93 | make.centerY.equalToSuperview() 94 | } 95 | leftTimeLabel.snp.makeConstraints { make in 96 | make.leading.equalTo(playButton.snp.trailing).offset(9) 97 | make.width.equalTo(32) 98 | make.centerY.equalToSuperview() 99 | } 100 | slider.snp.makeConstraints { make in 101 | make.leading.equalTo(leftTimeLabel.snp.trailing).offset(8) 102 | make.centerY.equalToSuperview() 103 | } 104 | rightTimeLabel.snp.makeConstraints { make in 105 | make.leading.equalTo(slider.snp.trailing).offset(8) 106 | make.width.equalTo(32) 107 | make.centerY.equalToSuperview() 108 | make.trailing.equalToSuperview().offset(-15) 109 | } 110 | 111 | stickerWrapView.isHidden = true 112 | let statusObservable = player.rx.observe(AVPlayer.Status.self, "status").takeUntil(rx.deallocated).ignoreNil() 113 | let rateObservable = player.rx.observe(Float.self, "rate").takeUntil(rx.deallocated).ignoreNil() 114 | let hideStickerWrapViewObservable = rx.observeWeakly(Bool.self, "hideStickerWrapView").takeUntil(rx.deallocated).ignoreNil() 115 | _ = Observable.combineLatest(statusObservable, rateObservable, hideStickerWrapViewObservable) { !($0 == .readyToPlay && $1 == 0 && !$2) }.bind(to: stickerWrapView.rx.isHidden) 116 | _ = rateObservable.subscribe(onNext: { [weak self] (_) in 117 | guard let s = self else { return } 118 | if s.player.rate != 0 { 119 | // 播放 120 | s.playButton.isSelected = true 121 | } else { 122 | s.playButton.isSelected = false 123 | } 124 | }) 125 | _ = hideStickerWrapViewObservable.subscribe(onNext: { [weak self] in 126 | self?.stickerWrapLayer.isHidden = $0 127 | }) 128 | 129 | let tap = UITapGestureRecognizer(target: self, action: #selector(play as () -> Void)) 130 | addGestureRecognizer(tap) 131 | } 132 | @objc private func handleSliderValueChanged(s: UISlider) { 133 | if let duration = player.currentItem?.duration { 134 | let time = CMTime(seconds: Double(s.value) * duration.seconds, preferredTimescale: duration.timescale) 135 | player.fl_seekSmoothly(to: time) 136 | } 137 | } 138 | @objc private func handleSliderTouchDown() { 139 | player.rate = 0 140 | } 141 | @objc private func handleSliderTouchUp() { 142 | player.rate = 0 143 | } 144 | @objc func play() { 145 | player.xd_play() 146 | } 147 | func play(withAsset asset: AVAsset, autoPlay: Bool = true) { 148 | play(withItem: AVPlayerItem(asset: asset), autoPlay: autoPlay) 149 | } 150 | func play(withItem item: AVPlayerItem, from time: CMTime = CMTime.zero, autoPlay: Bool = false) { 151 | stickerWrapLayer.opacity = 0 152 | DispatchQueue.main.async { 153 | self.player.replaceCurrentItem(with: item) 154 | self.player.fl_seekSmoothly(to: time) 155 | if autoPlay { 156 | self.player.play() 157 | } else { 158 | self.player.pause() 159 | } 160 | self.setNeedsLayout() 161 | self.stickerWrapLayer.opacity = 1 162 | } 163 | } 164 | func addSticker(sticker: Sticker) { 165 | let stickerView = StickerView(sticker: sticker) 166 | if stickerView.center == .zero { 167 | stickerView.center = CGPoint(x: stickerWrapView.bounds.midX, y: stickerWrapView.bounds.midY) 168 | } 169 | stickerWrapView.addSubview(stickerView) 170 | if let syncLayer = stickerView.stickerLayer as? AVSynchronizedLayer { 171 | syncLayer.playerItem = player.currentItem 172 | } 173 | } 174 | func removeSticker(sticker: Sticker) { 175 | let subviews = stickerWrapView.subviews 176 | for view in subviews { 177 | guard let stickerView = view as? StickerView else { continue } 178 | guard stickerView.sticker === sticker else { continue } 179 | stickerView.removeFromSuperview() 180 | } 181 | } 182 | deinit { 183 | player.endSendingPlayMessages() 184 | } 185 | override var isHidden: Bool { 186 | set { 187 | super.isHidden = newValue 188 | if newValue && player.rate != 0 { 189 | player.rate = 0 190 | } 191 | } 192 | get { 193 | return super.isHidden 194 | } 195 | } 196 | private var disPlaySize: CGSize? { 197 | get { 198 | return currentItem?.disPlaySize() 199 | } 200 | } 201 | override func layoutSubviews() { 202 | super.layoutSubviews() 203 | layoutViews() 204 | } 205 | var controlViewAlwaysStickyBottom: Bool = false { 206 | didSet { 207 | if controlViewAlwaysStickyBottom { 208 | controlView.backgroundColor = UIColor.init(hex6: 0x000000, alpha: 0.48) 209 | } else { 210 | controlView.backgroundColor = UIColor.xd_161616 211 | } 212 | } 213 | } 214 | fileprivate var renderAspectRatio: Float = 0 215 | fileprivate func layoutViews() { 216 | if var size = disPlaySize { 217 | if size.width == 0 || size.height == 0 { 218 | return 219 | } 220 | size = CGSize(width: abs(size.width), height: abs(size.height)) 221 | var aspectRatio = CGFloat(renderAspectRatio) 222 | if aspectRatio == 0 { 223 | aspectRatio = size.width / size.height 224 | } 225 | var actualWidth = bounds.width 226 | var actualHeight = bounds.height 227 | if controlViewAlwaysStickyBottom { 228 | videoView.center = CGPoint(x: bounds.midX, y: bounds.midY) 229 | } else { 230 | if controlView.isHidden { 231 | actualHeight = bounds.height 232 | videoView.center = CGPoint(x: bounds.midX, y: bounds.midY) 233 | } else { 234 | actualHeight = bounds.height - 32 235 | videoView.center = CGPoint(x: bounds.midX, y: bounds.midY - 16) 236 | } 237 | } 238 | var newWidth: CGFloat 239 | var newHeight: CGFloat 240 | 241 | let actualRatio = actualWidth / actualHeight 242 | if actualRatio > aspectRatio { 243 | actualWidth = actualHeight * aspectRatio 244 | } else if actualRatio < aspectRatio { 245 | actualHeight = actualWidth / aspectRatio 246 | if !controlViewAlwaysStickyBottom { 247 | if !controlView.isHidden && (bounds.height - actualHeight) >= 32 { 248 | videoView.center = CGPoint(x: bounds.midX, y: bounds.midY) 249 | } 250 | } 251 | } 252 | newWidth = actualWidth 253 | newHeight = actualHeight 254 | 255 | videoView.bounds = CGRect(x: 0, y: 0, width: newWidth, height: newHeight) 256 | videoView.setNeedsLayout() 257 | 258 | // control view 259 | controlView.bounds = CGRect(x: 0, y: 0, width: bounds.width, height: 32) 260 | if controlViewAlwaysStickyBottom { 261 | controlView.center = CGPoint(x: bounds.midX, y: bottom - 16) 262 | } else { 263 | controlView.center = CGPoint(x: bounds.midX, y: videoView.centerY + newHeight * 0.5 + 16) 264 | } 265 | // sticker wrap view 266 | stickerWrapView.bounds = CGRect(x: 0, y: 0, width: newWidth, height: newHeight) 267 | stickerWrapView.center = videoView.center 268 | } 269 | } 270 | 271 | override func willMove(toWindow newWindow: UIWindow?) { 272 | if newWindow == nil && player.rate != 0 { 273 | player.pause() 274 | } 275 | } 276 | } 277 | 278 | extension VideoPreview: SCPlayerDelegate { 279 | func updateLeftTimeLabel() { 280 | guard let item = player.currentItem else { return } 281 | let currentTime = player.currentTime() 282 | let duration = item.duration 283 | slider.setValue(Float(currentTime.seconds / duration.seconds), animated: true) 284 | leftTimeLabel.text = "\(Util.timeStringMMSS(duration: currentTime.seconds))" 285 | } 286 | func updateRightTimeLabel() { 287 | guard let item = player.currentItem else { return } 288 | let duration = item.asset.duration 289 | rightTimeLabel.text = "\(Util.timeStringMMSS(duration: duration.seconds))" 290 | } 291 | func player(_ player: SCPlayer, didPlay currentTime: CMTime, loopsCount: Int) { 292 | updateLeftTimeLabel() 293 | } 294 | func player(_ player: SCPlayer, didChange item: AVPlayerItem?) { 295 | controlView.isHidden = item == nil 296 | changeStickerLayerItem() 297 | if let item = item { 298 | if item.asset.statusOfValue(forKey: "duration", error: nil) == .loaded { 299 | updateRightTimeLabel() 300 | } else { 301 | rightTimeLabel.text = "--:--" 302 | item.asset.loadValuesAsynchronously(forKeys: ["duration"]) { 303 | DispatchQueue.main.async { 304 | self.updateRightTimeLabel() 305 | } 306 | } 307 | } 308 | } 309 | setNeedsLayout() 310 | } 311 | func changeStickerLayerItem() { 312 | guard let sublayers = stickerWrapLayer.sublayers else { return } 313 | for sublayer in sublayers { 314 | if let syncLayer = sublayer as? AVSynchronizedLayer { 315 | syncLayer.playerItem = currentItem 316 | } 317 | } 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /LottieInVideo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSPhotoLibraryAddUsageDescription 24 | 「$(PRODUCT_NAME)」需要你的同意,才能保存视频到你的相册 25 | NSPhotoLibraryUsageDescription 26 | 读取视频和相片 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /LottieInVideo/Resource/1532072337.63853.MP4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvpengwei/LottieInVideo/2c470a3bdda73b33f733cddd726f95a8c4eaffd6/LottieInVideo/Resource/1532072337.63853.MP4 -------------------------------------------------------------------------------- /LottieInVideo/Resource/PinJump.json: -------------------------------------------------------------------------------- 1 | {"assets":[],"fonts":{"list":[{"fName":"momo_xinjian","fPath":"","fClass":"","fFamily":"momo_xinjian","fWeight":"","fStyle":"Regular","fOrigin":"t","ascent":67.1996336430311}]},"layers":[{"ddd":0,"ind":0,"ty":5,"nm":"台湾 ","ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[80]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":10,"s":[80],"e":[81]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":65,"s":[81],"e":[0]},{"t":74}]},"r":{"k":0},"p":{"k":[647.829,221.8,0]},"a":{"k":[0,0,0]},"s":{"k":[100,100,100]}},"ao":0,"t":{"d":{"k":[{"s":{"s":258,"f":"momo_xinjian","t":"台湾","j":0,"tr":-352,"lh":309.6,"fc":[0.15,0.15,0.15]},"t":0}]},"p":{},"m":{"g":1,"a":{"k":[0,0]}},"a":[]},"ip":0,"op":75,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":5,"nm":"垦丁的海 啊海 听海哭的声音","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[141.429,768.486,0]},"a":{"k":[0,0,0]},"s":{"k":[80,80,100]}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35,-33.35],[-35,10.6],[-33,10.6],[-33,-33.35]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-35,-47],[-35,22],[662,22],[662,-47]],"c":true}]},{"t":40}]},"o":{"k":100},"x":{"k":0},"nm":"蒙版 1"}],"t":{"d":{"k":[{"s":{"s":50,"f":"momo_xinjian","t":"垦丁的海 啊海 听海哭的声音","j":0,"tr":1,"lh":60,"fc":[0.15,0.15,0.15]},"t":0}]},"p":{},"m":{"g":1,"a":{"k":[0,0]}},"a":[]},"ip":0,"op":75,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"“bird1”轮廓 10","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[800.171,113.657,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-18.399,1.814],[4.954,-17.65],[0,0],[0,0],[0,0],[0,0],[7.538,-1.077],[-11.769,1.159],[0,0],[0,0],[-3.64,2.761],[0,0],[0,0],[-7.028,-1.525]],"o":[[-4.209,19.462],[0,0],[0,0],[0,0],[0,0],[-7.537,1.076],[2.384,-10.393],[0,0],[0,0],[2.728,-3.666],[0,0],[0,0],[3.766,4.398],[7.271,-12.879]],"v":[[42,-25.846],[16.154,12.923],[22.615,12.923],[22.615,19.385],[-19.385,19.385],[-19.385,22.616],[-42,25.846],[-25.846,12.923],[-25.846,6.462],[-32.308,6.462],[-29.077,3.231],[-29.077,0],[-19.385,0],[-6.462,6.462]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[91,265.154],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":-7,"op":-2,"st":-7,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"“bird2”轮廓 9","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[809.429,144.514,0]},"a":{"k":[282,282,0]},"s":{"k":[92,92,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-5.408,-1.352],[2.301,-16.822],[0,0],[0,0],[24.332,2.943],[5.408,-9.464],[0,0],[-8.938,8.656],[0,0],[0,0],[-5.883,-3.196],[0,0],[-6.689,8.356]],"o":[[-3.71,14.259],[0,0],[0,0],[-27.344,5.177],[-5.408,9.465],[0,0],[-0.648,-18.234],[0,0],[0,0],[4.429,4.758],[0,0],[10.399,-4.567],[5.408,1.353]],"v":[[38.95,-28.396],[26.779,0.001],[34.893,0.001],[34.893,8.113],[-13.786,4.057],[-30.012,32.452],[-38.124,32.452],[-30.012,-12.17],[-30.012,-16.226],[-17.842,-16.226],[-5.673,-8.113],[-5.673,-12.17],[22.723,-32.452]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.99,0.99,0.98,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[85.672,249.548],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":-2,"op":3,"st":-2,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"“bird3”轮廓 9","ks":{"o":{"k":100},"r":{"k":-1},"p":{"k":[682.914,144.514,0]},"a":{"k":[282,282,0]},"s":{"k":[90,90,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.396,-1.349],[-8.081,-2.435],[0,0],[10.282,-6.57],[0,0],[16.246,-2.406],[0,0],[-2.856,11.317],[0,0],[0,0],[0,0],[8.081,2.435],[0,0],[-12.142,-1.349],[0,0],[0,0],[0,0]],"o":[[0,0],[-5.396,1.349],[4.611,4.609],[0,0],[-16.192,-0.18],[0,0],[-9.993,7.861],[0,0],[8.839,-4.858],[0,0],[0,0],[0,0],[-4.611,-4.608],[0,0],[12.142,1.349],[0,0],[0,0],[0,0],[0,0]],"v":[[42.5,-28.334],[42.5,-16.191],[26.31,-12.144],[34.405,-8.096],[34.405,4.048],[-14.167,8.096],[-14.167,12.143],[-42.5,28.334],[-42.5,12.143],[-26.31,-8.096],[-22.262,-8.096],[-22.262,-12.144],[-26.31,-12.144],[-34.405,-16.191],[-34.405,-24.286],[2.024,-20.239],[2.024,-24.286],[10.119,-24.286],[10.119,-28.334]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[202.5,252.619],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":3,"op":8,"st":3,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"“bird4”轮廓 9","ks":{"o":{"k":100},"r":{"k":-20},"p":{"k":[547.143,98.229,0]},"a":{"k":[282,282,0]},"s":{"k":[94,94,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-22.653,4.64],[0,0],[7.832,-6.526],[0,0],[0,0],[-1.306,-5.221],[0,0],[0,0],[6.859,5.485],[0,0],[0,0],[0,0],[6.149,9.6],[0,0],[-9.163,-2.245]],"o":[[0,0],[-7.832,6.526],[0,0],[0,0],[1.306,5.221],[0,0],[0,0],[-10.254,-2.44],[0,0],[0,0],[0,0],[-8.498,-5.304],[0,0],[4.952,6.159],[5.453,-21.362]],"v":[[50.912,-33.289],[50.912,-21.539],[27.414,-1.958],[23.498,13.707],[15.665,17.624],[19.582,33.289],[-11.749,33.289],[-11.749,29.372],[-31.33,17.624],[-31.33,13.707],[-39.163,13.707],[-39.163,9.79],[-50.912,1.958],[-31.33,1.958],[-11.749,13.707]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[336.911,290.289],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":8,"op":13,"st":8,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"“bird5”轮廓 9","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[556.4,132.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-2.687,10.967],[0,0],[0,0],[-17.329,-15.55],[-2.82,-9.358],[6.249,-1.562],[-1.563,-7.812],[12.498,3.125],[0,0],[10.544,2.952],[12.854,-5.228],[0,0]],"o":[[0,0],[0,0],[15.812,6.099],[5.337,5.34],[-6.249,1.562],[1.562,7.812],[-12.499,-3.125],[0,0],[-7.201,-5.419],[-6.796,11.518],[0,0],[7.373,-5.927]],"v":[[-35.481,-20.35],[-12.044,-20.35],[-7.356,-10.975],[44.207,-10.975],[48.894,-1.6],[30.144,3.087],[34.832,26.525],[-2.668,17.15],[-2.668,12.463],[-21.418,3.087],[-49.544,21.838],[-49.544,3.087]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[330.106,255.413],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":13,"op":18,"st":13,"bm":0,"sr":1},{"ddd":0,"ind":7,"ty":4,"nm":"“bird6”轮廓 9","ks":{"o":{"k":100},"r":{"k":2},"p":{"k":[476.171,129.086,0]},"a":{"k":[282,282,0]},"s":{"k":[81,81,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-4.111,-15.527],[0,0],[0,0],[22.036,-8.326],[0,0],[17.335,-4.717],[-9.421,10.488],[-3.666,1.833],[1.833,3.666],[0,0],[-17.999,0.529]],"o":[[0,0],[0,0],[-12.89,-5.223],[0,0],[-16.95,8.029],[2.692,-16.033],[3.666,-1.833],[-1.833,-3.666],[0,0],[9.378,8.705],[6.668,11.703]],"v":[[60.5,2.75],[49.5,2.75],[49.5,13.75],[-16.5,2.75],[-16.5,8.25],[-60.5,30.25],[-38.5,-13.75],[-27.5,-19.25],[-33,-30.25],[-11,-30.25],[44,-24.75]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[404.5,265.75],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":18,"op":23,"st":18,"bm":0,"sr":1},{"ddd":0,"ind":8,"ty":4,"nm":"“bird7”轮廓 7","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[429.886,132.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-8.984,-2.707],[0,0],[0,0],[0,0],[8.074,-4.289],[0,0],[0,0],[0,0],[0,0],[0,0],[13.905,-1.485],[-22.491,0.544],[-14.837,-0.458],[-26.478,-0.709]],"o":[[0,0],[0,0],[0,0],[-10.997,2.581],[0,0],[0,0],[0,0],[0,0],[0,0],[-11.332,-3.296],[3.258,-18.893],[6.732,7.916],[8.883,-16.33],[5.127,5.124]],"v":[[56.25,-15.396],[56.25,-6.396],[33.75,-6.396],[33.75,-1.896],[15.75,7.104],[20.25,20.604],[-6.75,20.604],[-11.25,11.604],[-20.25,11.604],[-20.25,7.104],[-56.25,16.104],[-24.75,-10.896],[2.25,-1.896],[47.25,-19.896]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[458.75,256.188],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":23,"op":28,"st":23,"bm":0,"sr":1},{"ddd":0,"ind":9,"ty":4,"nm":"“bird1”轮廓 9","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[800.171,113.657,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-18.399,1.814],[4.954,-17.65],[0,0],[0,0],[0,0],[0,0],[7.538,-1.077],[-11.769,1.159],[0,0],[0,0],[-3.64,2.761],[0,0],[0,0],[-7.028,-1.525]],"o":[[-4.209,19.462],[0,0],[0,0],[0,0],[0,0],[-7.537,1.076],[2.384,-10.393],[0,0],[0,0],[2.728,-3.666],[0,0],[0,0],[3.766,4.398],[7.271,-12.879]],"v":[[42,-25.846],[16.154,12.923],[22.615,12.923],[22.615,19.385],[-19.385,19.385],[-19.385,22.616],[-42,25.846],[-25.846,12.923],[-25.846,6.462],[-32.308,6.462],[-29.077,3.231],[-29.077,0],[-19.385,0],[-6.462,6.462]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[91,265.154],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":28,"op":33,"st":28,"bm":0,"sr":1},{"ddd":0,"ind":10,"ty":4,"nm":"“bird2”轮廓 8","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[809.429,144.514,0]},"a":{"k":[282,282,0]},"s":{"k":[92,92,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-5.408,-1.352],[2.301,-16.822],[0,0],[0,0],[24.332,2.943],[5.408,-9.464],[0,0],[-8.938,8.656],[0,0],[0,0],[-5.883,-3.196],[0,0],[-6.689,8.356]],"o":[[-3.71,14.259],[0,0],[0,0],[-27.344,5.177],[-5.408,9.465],[0,0],[-0.648,-18.234],[0,0],[0,0],[4.429,4.758],[0,0],[10.399,-4.567],[5.408,1.353]],"v":[[38.95,-28.396],[26.779,0.001],[34.893,0.001],[34.893,8.113],[-13.786,4.057],[-30.012,32.452],[-38.124,32.452],[-30.012,-12.17],[-30.012,-16.226],[-17.842,-16.226],[-5.673,-8.113],[-5.673,-12.17],[22.723,-32.452]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.99,0.99,0.98,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[85.672,249.548],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":33,"op":38,"st":33,"bm":0,"sr":1},{"ddd":0,"ind":11,"ty":4,"nm":"“bird3”轮廓 8","ks":{"o":{"k":100},"r":{"k":-1},"p":{"k":[682.914,144.514,0]},"a":{"k":[282,282,0]},"s":{"k":[90,90,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.396,-1.349],[-8.081,-2.435],[0,0],[10.282,-6.57],[0,0],[16.246,-2.406],[0,0],[-2.856,11.317],[0,0],[0,0],[0,0],[8.081,2.435],[0,0],[-12.142,-1.349],[0,0],[0,0],[0,0]],"o":[[0,0],[-5.396,1.349],[4.611,4.609],[0,0],[-16.192,-0.18],[0,0],[-9.993,7.861],[0,0],[8.839,-4.858],[0,0],[0,0],[0,0],[-4.611,-4.608],[0,0],[12.142,1.349],[0,0],[0,0],[0,0],[0,0]],"v":[[42.5,-28.334],[42.5,-16.191],[26.31,-12.144],[34.405,-8.096],[34.405,4.048],[-14.167,8.096],[-14.167,12.143],[-42.5,28.334],[-42.5,12.143],[-26.31,-8.096],[-22.262,-8.096],[-22.262,-12.144],[-26.31,-12.144],[-34.405,-16.191],[-34.405,-24.286],[2.024,-20.239],[2.024,-24.286],[10.119,-24.286],[10.119,-28.334]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[202.5,252.619],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":38,"op":43,"st":38,"bm":0,"sr":1},{"ddd":0,"ind":12,"ty":4,"nm":"“bird4”轮廓 8","ks":{"o":{"k":100},"r":{"k":-20},"p":{"k":[547.143,98.229,0]},"a":{"k":[282,282,0]},"s":{"k":[94,94,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-22.653,4.64],[0,0],[7.832,-6.526],[0,0],[0,0],[-1.306,-5.221],[0,0],[0,0],[6.859,5.485],[0,0],[0,0],[0,0],[6.149,9.6],[0,0],[-9.163,-2.245]],"o":[[0,0],[-7.832,6.526],[0,0],[0,0],[1.306,5.221],[0,0],[0,0],[-10.254,-2.44],[0,0],[0,0],[0,0],[-8.498,-5.304],[0,0],[4.952,6.159],[5.453,-21.362]],"v":[[50.912,-33.289],[50.912,-21.539],[27.414,-1.958],[23.498,13.707],[15.665,17.624],[19.582,33.289],[-11.749,33.289],[-11.749,29.372],[-31.33,17.624],[-31.33,13.707],[-39.163,13.707],[-39.163,9.79],[-50.912,1.958],[-31.33,1.958],[-11.749,13.707]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[336.911,290.289],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":43,"op":48,"st":43,"bm":0,"sr":1},{"ddd":0,"ind":13,"ty":4,"nm":"“bird5”轮廓 8","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[556.4,132.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-2.687,10.967],[0,0],[0,0],[-17.329,-15.55],[-2.82,-9.358],[6.249,-1.562],[-1.563,-7.812],[12.498,3.125],[0,0],[10.544,2.952],[12.854,-5.228],[0,0]],"o":[[0,0],[0,0],[15.812,6.099],[5.337,5.34],[-6.249,1.562],[1.562,7.812],[-12.499,-3.125],[0,0],[-7.201,-5.419],[-6.796,11.518],[0,0],[7.373,-5.927]],"v":[[-35.481,-20.35],[-12.044,-20.35],[-7.356,-10.975],[44.207,-10.975],[48.894,-1.6],[30.144,3.087],[34.832,26.525],[-2.668,17.15],[-2.668,12.463],[-21.418,3.087],[-49.544,21.838],[-49.544,3.087]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[330.106,255.413],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":48,"op":53,"st":48,"bm":0,"sr":1},{"ddd":0,"ind":14,"ty":4,"nm":"“bird6”轮廓 8","ks":{"o":{"k":100},"r":{"k":2},"p":{"k":[476.171,129.086,0]},"a":{"k":[282,282,0]},"s":{"k":[81,81,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-4.111,-15.527],[0,0],[0,0],[22.036,-8.326],[0,0],[17.335,-4.717],[-9.421,10.488],[-3.666,1.833],[1.833,3.666],[0,0],[-17.999,0.529]],"o":[[0,0],[0,0],[-12.89,-5.223],[0,0],[-16.95,8.029],[2.692,-16.033],[3.666,-1.833],[-1.833,-3.666],[0,0],[9.378,8.705],[6.668,11.703]],"v":[[60.5,2.75],[49.5,2.75],[49.5,13.75],[-16.5,2.75],[-16.5,8.25],[-60.5,30.25],[-38.5,-13.75],[-27.5,-19.25],[-33,-30.25],[-11,-30.25],[44,-24.75]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[404.5,265.75],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":53,"op":58,"st":53,"bm":0,"sr":1},{"ddd":0,"ind":15,"ty":4,"nm":"“bird7”轮廓 6","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[429.886,132.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-8.984,-2.707],[0,0],[0,0],[0,0],[8.074,-4.289],[0,0],[0,0],[0,0],[0,0],[0,0],[13.905,-1.485],[-22.491,0.544],[-14.837,-0.458],[-26.478,-0.709]],"o":[[0,0],[0,0],[0,0],[-10.997,2.581],[0,0],[0,0],[0,0],[0,0],[0,0],[-11.332,-3.296],[3.258,-18.893],[6.732,7.916],[8.883,-16.33],[5.127,5.124]],"v":[[56.25,-15.396],[56.25,-6.396],[33.75,-6.396],[33.75,-1.896],[15.75,7.104],[20.25,20.604],[-6.75,20.604],[-11.25,11.604],[-20.25,11.604],[-20.25,7.104],[-56.25,16.104],[-24.75,-10.896],[2.25,-1.896],[47.25,-19.896]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[458.75,256.188],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":58,"op":63,"st":58,"bm":0,"sr":1},{"ddd":0,"ind":16,"ty":4,"nm":"“bird1”轮廓 8","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[800.171,113.657,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-18.399,1.814],[4.954,-17.65],[0,0],[0,0],[0,0],[0,0],[7.538,-1.077],[-11.769,1.159],[0,0],[0,0],[-3.64,2.761],[0,0],[0,0],[-7.028,-1.525]],"o":[[-4.209,19.462],[0,0],[0,0],[0,0],[0,0],[-7.537,1.076],[2.384,-10.393],[0,0],[0,0],[2.728,-3.666],[0,0],[0,0],[3.766,4.398],[7.271,-12.879]],"v":[[42,-25.846],[16.154,12.923],[22.615,12.923],[22.615,19.385],[-19.385,19.385],[-19.385,22.616],[-42,25.846],[-25.846,12.923],[-25.846,6.462],[-32.308,6.462],[-29.077,3.231],[-29.077,0],[-19.385,0],[-6.462,6.462]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[91,265.154],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":63,"op":68,"st":63,"bm":0,"sr":1},{"ddd":0,"ind":17,"ty":4,"nm":"“bird2”轮廓 7","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[809.429,144.514,0]},"a":{"k":[282,282,0]},"s":{"k":[92,92,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-5.408,-1.352],[2.301,-16.822],[0,0],[0,0],[24.332,2.943],[5.408,-9.464],[0,0],[-8.938,8.656],[0,0],[0,0],[-5.883,-3.196],[0,0],[-6.689,8.356]],"o":[[-3.71,14.259],[0,0],[0,0],[-27.344,5.177],[-5.408,9.465],[0,0],[-0.648,-18.234],[0,0],[0,0],[4.429,4.758],[0,0],[10.399,-4.567],[5.408,1.353]],"v":[[38.95,-28.396],[26.779,0.001],[34.893,0.001],[34.893,8.113],[-13.786,4.057],[-30.012,32.452],[-38.124,32.452],[-30.012,-12.17],[-30.012,-16.226],[-17.842,-16.226],[-5.673,-8.113],[-5.673,-12.17],[22.723,-32.452]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.99,0.99,0.98,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[85.672,249.548],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":68,"op":73,"st":68,"bm":0,"sr":1},{"ddd":0,"ind":18,"ty":4,"nm":"“bird3”轮廓 7","ks":{"o":{"k":100},"r":{"k":-1},"p":{"k":[682.914,144.514,0]},"a":{"k":[282,282,0]},"s":{"k":[90,90,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.396,-1.349],[-8.081,-2.435],[0,0],[10.282,-6.57],[0,0],[16.246,-2.406],[0,0],[-2.856,11.317],[0,0],[0,0],[0,0],[8.081,2.435],[0,0],[-12.142,-1.349],[0,0],[0,0],[0,0]],"o":[[0,0],[-5.396,1.349],[4.611,4.609],[0,0],[-16.192,-0.18],[0,0],[-9.993,7.861],[0,0],[8.839,-4.858],[0,0],[0,0],[0,0],[-4.611,-4.608],[0,0],[12.142,1.349],[0,0],[0,0],[0,0],[0,0]],"v":[[42.5,-28.334],[42.5,-16.191],[26.31,-12.144],[34.405,-8.096],[34.405,4.048],[-14.167,8.096],[-14.167,12.143],[-42.5,28.334],[-42.5,12.143],[-26.31,-8.096],[-22.262,-8.096],[-22.262,-12.144],[-26.31,-12.144],[-34.405,-16.191],[-34.405,-24.286],[2.024,-20.239],[2.024,-24.286],[10.119,-24.286],[10.119,-28.334]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[202.5,252.619],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":73,"op":78,"st":73,"bm":0,"sr":1},{"ddd":0,"ind":19,"ty":4,"nm":"“bird4”轮廓 7","ks":{"o":{"k":100},"r":{"k":-20},"p":{"k":[547.143,98.229,0]},"a":{"k":[282,282,0]},"s":{"k":[94,94,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-22.653,4.64],[0,0],[7.832,-6.526],[0,0],[0,0],[-1.306,-5.221],[0,0],[0,0],[6.859,5.485],[0,0],[0,0],[0,0],[6.149,9.6],[0,0],[-9.163,-2.245]],"o":[[0,0],[-7.832,6.526],[0,0],[0,0],[1.306,5.221],[0,0],[0,0],[-10.254,-2.44],[0,0],[0,0],[0,0],[-8.498,-5.304],[0,0],[4.952,6.159],[5.453,-21.362]],"v":[[50.912,-33.289],[50.912,-21.539],[27.414,-1.958],[23.498,13.707],[15.665,17.624],[19.582,33.289],[-11.749,33.289],[-11.749,29.372],[-31.33,17.624],[-31.33,13.707],[-39.163,13.707],[-39.163,9.79],[-50.912,1.958],[-31.33,1.958],[-11.749,13.707]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[336.911,290.289],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":78,"op":83,"st":78,"bm":0,"sr":1},{"ddd":0,"ind":20,"ty":4,"nm":"“bird5”轮廓 7","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[556.4,132.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-2.687,10.967],[0,0],[0,0],[-17.329,-15.55],[-2.82,-9.358],[6.249,-1.562],[-1.563,-7.812],[12.498,3.125],[0,0],[10.544,2.952],[12.854,-5.228],[0,0]],"o":[[0,0],[0,0],[15.812,6.099],[5.337,5.34],[-6.249,1.562],[1.562,7.812],[-12.499,-3.125],[0,0],[-7.201,-5.419],[-6.796,11.518],[0,0],[7.373,-5.927]],"v":[[-35.481,-20.35],[-12.044,-20.35],[-7.356,-10.975],[44.207,-10.975],[48.894,-1.6],[30.144,3.087],[34.832,26.525],[-2.668,17.15],[-2.668,12.463],[-21.418,3.087],[-49.544,21.838],[-49.544,3.087]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[330.106,255.413],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":83,"op":88,"st":83,"bm":0,"sr":1},{"ddd":0,"ind":21,"ty":4,"nm":"“bird6”轮廓 7","ks":{"o":{"k":100},"r":{"k":2},"p":{"k":[476.171,129.086,0]},"a":{"k":[282,282,0]},"s":{"k":[81,81,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-4.111,-15.527],[0,0],[0,0],[22.036,-8.326],[0,0],[17.335,-4.717],[-9.421,10.488],[-3.666,1.833],[1.833,3.666],[0,0],[-17.999,0.529]],"o":[[0,0],[0,0],[-12.89,-5.223],[0,0],[-16.95,8.029],[2.692,-16.033],[3.666,-1.833],[-1.833,-3.666],[0,0],[9.378,8.705],[6.668,11.703]],"v":[[60.5,2.75],[49.5,2.75],[49.5,13.75],[-16.5,2.75],[-16.5,8.25],[-60.5,30.25],[-38.5,-13.75],[-27.5,-19.25],[-33,-30.25],[-11,-30.25],[44,-24.75]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[404.5,265.75],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":88,"op":93,"st":88,"bm":0,"sr":1},{"ddd":0,"ind":22,"ty":4,"nm":"“bird1”轮廓 4","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[966.171,307.657,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-18.399,1.814],[4.954,-17.65],[0,0],[0,0],[0,0],[0,0],[7.538,-1.077],[-11.769,1.159],[0,0],[0,0],[-3.64,2.761],[0,0],[0,0],[-7.028,-1.525]],"o":[[-4.209,19.462],[0,0],[0,0],[0,0],[0,0],[-7.537,1.076],[2.384,-10.393],[0,0],[0,0],[2.728,-3.666],[0,0],[0,0],[3.766,4.398],[7.271,-12.879]],"v":[[42,-25.846],[16.154,12.923],[22.615,12.923],[22.615,19.385],[-19.385,19.385],[-19.385,22.616],[-42,25.846],[-25.846,12.923],[-25.846,6.462],[-32.308,6.462],[-29.077,3.231],[-29.077,0],[-19.385,0],[-6.462,6.462]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[91,265.154],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":5,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":23,"ty":4,"nm":"“bird2”轮廓 4","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[975.429,338.514,0]},"a":{"k":[282,282,0]},"s":{"k":[92,92,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-5.408,-1.352],[2.301,-16.822],[0,0],[0,0],[24.332,2.943],[5.408,-9.464],[0,0],[-8.938,8.656],[0,0],[0,0],[-5.883,-3.196],[0,0],[-6.689,8.356]],"o":[[-3.71,14.259],[0,0],[0,0],[-27.344,5.177],[-5.408,9.465],[0,0],[-0.648,-18.234],[0,0],[0,0],[4.429,4.758],[0,0],[10.399,-4.567],[5.408,1.353]],"v":[[38.95,-28.396],[26.779,0.001],[34.893,0.001],[34.893,8.113],[-13.786,4.057],[-30.012,32.452],[-38.124,32.452],[-30.012,-12.17],[-30.012,-16.226],[-17.842,-16.226],[-5.673,-8.113],[-5.673,-12.17],[22.723,-32.452]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.99,0.99,0.98,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[85.672,249.548],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":5,"op":10,"st":5,"bm":0,"sr":1},{"ddd":0,"ind":24,"ty":4,"nm":"“bird3”轮廓 4","ks":{"o":{"k":100},"r":{"k":-1},"p":{"k":[848.914,338.514,0]},"a":{"k":[282,282,0]},"s":{"k":[90,90,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.396,-1.349],[-8.081,-2.435],[0,0],[10.282,-6.57],[0,0],[16.246,-2.406],[0,0],[-2.856,11.317],[0,0],[0,0],[0,0],[8.081,2.435],[0,0],[-12.142,-1.349],[0,0],[0,0],[0,0]],"o":[[0,0],[-5.396,1.349],[4.611,4.609],[0,0],[-16.192,-0.18],[0,0],[-9.993,7.861],[0,0],[8.839,-4.858],[0,0],[0,0],[0,0],[-4.611,-4.608],[0,0],[12.142,1.349],[0,0],[0,0],[0,0],[0,0]],"v":[[42.5,-28.334],[42.5,-16.191],[26.31,-12.144],[34.405,-8.096],[34.405,4.048],[-14.167,8.096],[-14.167,12.143],[-42.5,28.334],[-42.5,12.143],[-26.31,-8.096],[-22.262,-8.096],[-22.262,-12.144],[-26.31,-12.144],[-34.405,-16.191],[-34.405,-24.286],[2.024,-20.239],[2.024,-24.286],[10.119,-24.286],[10.119,-28.334]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[202.5,252.619],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":10,"op":15,"st":10,"bm":0,"sr":1},{"ddd":0,"ind":25,"ty":4,"nm":"“bird4”轮廓 4","ks":{"o":{"k":100},"r":{"k":-20},"p":{"k":[713.143,292.229,0]},"a":{"k":[282,282,0]},"s":{"k":[94,94,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-22.653,4.64],[0,0],[7.832,-6.526],[0,0],[0,0],[-1.306,-5.221],[0,0],[0,0],[6.859,5.485],[0,0],[0,0],[0,0],[6.149,9.6],[0,0],[-9.163,-2.245]],"o":[[0,0],[-7.832,6.526],[0,0],[0,0],[1.306,5.221],[0,0],[0,0],[-10.254,-2.44],[0,0],[0,0],[0,0],[-8.498,-5.304],[0,0],[4.952,6.159],[5.453,-21.362]],"v":[[50.912,-33.289],[50.912,-21.539],[27.414,-1.958],[23.498,13.707],[15.665,17.624],[19.582,33.289],[-11.749,33.289],[-11.749,29.372],[-31.33,17.624],[-31.33,13.707],[-39.163,13.707],[-39.163,9.79],[-50.912,1.958],[-31.33,1.958],[-11.749,13.707]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[336.911,290.289],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":15,"op":20,"st":15,"bm":0,"sr":1},{"ddd":0,"ind":26,"ty":4,"nm":"“bird5”轮廓 4","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[722.4,326.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-2.687,10.967],[0,0],[0,0],[-17.329,-15.55],[-2.82,-9.358],[6.249,-1.562],[-1.563,-7.812],[12.498,3.125],[0,0],[10.544,2.952],[12.854,-5.228],[0,0]],"o":[[0,0],[0,0],[15.812,6.099],[5.337,5.34],[-6.249,1.562],[1.562,7.812],[-12.499,-3.125],[0,0],[-7.201,-5.419],[-6.796,11.518],[0,0],[7.373,-5.927]],"v":[[-35.481,-20.35],[-12.044,-20.35],[-7.356,-10.975],[44.207,-10.975],[48.894,-1.6],[30.144,3.087],[34.832,26.525],[-2.668,17.15],[-2.668,12.463],[-21.418,3.087],[-49.544,21.838],[-49.544,3.087]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[330.106,255.413],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":20,"op":25,"st":20,"bm":0,"sr":1},{"ddd":0,"ind":27,"ty":4,"nm":"“bird6”轮廓 4","ks":{"o":{"k":100},"r":{"k":2},"p":{"k":[642.171,323.086,0]},"a":{"k":[282,282,0]},"s":{"k":[81,81,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-4.111,-15.527],[0,0],[0,0],[22.036,-8.326],[0,0],[17.335,-4.717],[-9.421,10.488],[-3.666,1.833],[1.833,3.666],[0,0],[-17.999,0.529]],"o":[[0,0],[0,0],[-12.89,-5.223],[0,0],[-16.95,8.029],[2.692,-16.033],[3.666,-1.833],[-1.833,-3.666],[0,0],[9.378,8.705],[6.668,11.703]],"v":[[60.5,2.75],[49.5,2.75],[49.5,13.75],[-16.5,2.75],[-16.5,8.25],[-60.5,30.25],[-38.5,-13.75],[-27.5,-19.25],[-33,-30.25],[-11,-30.25],[44,-24.75]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[404.5,265.75],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":25,"op":30,"st":25,"bm":0,"sr":1},{"ddd":0,"ind":28,"ty":4,"nm":"“bird7”轮廓 4","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[595.886,326.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-8.984,-2.707],[0,0],[0,0],[0,0],[8.074,-4.289],[0,0],[0,0],[0,0],[0,0],[0,0],[13.905,-1.485],[-22.491,0.544],[-14.837,-0.458],[-26.478,-0.709]],"o":[[0,0],[0,0],[0,0],[-10.997,2.581],[0,0],[0,0],[0,0],[0,0],[0,0],[-11.332,-3.296],[3.258,-18.893],[6.732,7.916],[8.883,-16.33],[5.127,5.124]],"v":[[56.25,-15.396],[56.25,-6.396],[33.75,-6.396],[33.75,-1.896],[15.75,7.104],[20.25,20.604],[-6.75,20.604],[-11.25,11.604],[-20.25,11.604],[-20.25,7.104],[-56.25,16.104],[-24.75,-10.896],[2.25,-1.896],[47.25,-19.896]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[458.75,256.188],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":30,"op":35,"st":30,"bm":0,"sr":1},{"ddd":0,"ind":29,"ty":4,"nm":"“bird1”轮廓 5","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[966.171,307.657,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-18.399,1.814],[4.954,-17.65],[0,0],[0,0],[0,0],[0,0],[7.538,-1.077],[-11.769,1.159],[0,0],[0,0],[-3.64,2.761],[0,0],[0,0],[-7.028,-1.525]],"o":[[-4.209,19.462],[0,0],[0,0],[0,0],[0,0],[-7.537,1.076],[2.384,-10.393],[0,0],[0,0],[2.728,-3.666],[0,0],[0,0],[3.766,4.398],[7.271,-12.879]],"v":[[42,-25.846],[16.154,12.923],[22.615,12.923],[22.615,19.385],[-19.385,19.385],[-19.385,22.616],[-42,25.846],[-25.846,12.923],[-25.846,6.462],[-32.308,6.462],[-29.077,3.231],[-29.077,0],[-19.385,0],[-6.462,6.462]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[91,265.154],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":35,"op":40,"st":35,"bm":0,"sr":1},{"ddd":0,"ind":30,"ty":4,"nm":"“bird2”轮廓 5","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[975.429,338.514,0]},"a":{"k":[282,282,0]},"s":{"k":[92,92,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-5.408,-1.352],[2.301,-16.822],[0,0],[0,0],[24.332,2.943],[5.408,-9.464],[0,0],[-8.938,8.656],[0,0],[0,0],[-5.883,-3.196],[0,0],[-6.689,8.356]],"o":[[-3.71,14.259],[0,0],[0,0],[-27.344,5.177],[-5.408,9.465],[0,0],[-0.648,-18.234],[0,0],[0,0],[4.429,4.758],[0,0],[10.399,-4.567],[5.408,1.353]],"v":[[38.95,-28.396],[26.779,0.001],[34.893,0.001],[34.893,8.113],[-13.786,4.057],[-30.012,32.452],[-38.124,32.452],[-30.012,-12.17],[-30.012,-16.226],[-17.842,-16.226],[-5.673,-8.113],[-5.673,-12.17],[22.723,-32.452]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.99,0.99,0.98,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[85.672,249.548],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":40,"op":45,"st":40,"bm":0,"sr":1},{"ddd":0,"ind":31,"ty":4,"nm":"“bird3”轮廓 5","ks":{"o":{"k":100},"r":{"k":-1},"p":{"k":[848.914,338.514,0]},"a":{"k":[282,282,0]},"s":{"k":[90,90,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.396,-1.349],[-8.081,-2.435],[0,0],[10.282,-6.57],[0,0],[16.246,-2.406],[0,0],[-2.856,11.317],[0,0],[0,0],[0,0],[8.081,2.435],[0,0],[-12.142,-1.349],[0,0],[0,0],[0,0]],"o":[[0,0],[-5.396,1.349],[4.611,4.609],[0,0],[-16.192,-0.18],[0,0],[-9.993,7.861],[0,0],[8.839,-4.858],[0,0],[0,0],[0,0],[-4.611,-4.608],[0,0],[12.142,1.349],[0,0],[0,0],[0,0],[0,0]],"v":[[42.5,-28.334],[42.5,-16.191],[26.31,-12.144],[34.405,-8.096],[34.405,4.048],[-14.167,8.096],[-14.167,12.143],[-42.5,28.334],[-42.5,12.143],[-26.31,-8.096],[-22.262,-8.096],[-22.262,-12.144],[-26.31,-12.144],[-34.405,-16.191],[-34.405,-24.286],[2.024,-20.239],[2.024,-24.286],[10.119,-24.286],[10.119,-28.334]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[202.5,252.619],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":45,"op":50,"st":45,"bm":0,"sr":1},{"ddd":0,"ind":32,"ty":4,"nm":"“bird4”轮廓 5","ks":{"o":{"k":100},"r":{"k":-20},"p":{"k":[713.143,292.229,0]},"a":{"k":[282,282,0]},"s":{"k":[94,94,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-22.653,4.64],[0,0],[7.832,-6.526],[0,0],[0,0],[-1.306,-5.221],[0,0],[0,0],[6.859,5.485],[0,0],[0,0],[0,0],[6.149,9.6],[0,0],[-9.163,-2.245]],"o":[[0,0],[-7.832,6.526],[0,0],[0,0],[1.306,5.221],[0,0],[0,0],[-10.254,-2.44],[0,0],[0,0],[0,0],[-8.498,-5.304],[0,0],[4.952,6.159],[5.453,-21.362]],"v":[[50.912,-33.289],[50.912,-21.539],[27.414,-1.958],[23.498,13.707],[15.665,17.624],[19.582,33.289],[-11.749,33.289],[-11.749,29.372],[-31.33,17.624],[-31.33,13.707],[-39.163,13.707],[-39.163,9.79],[-50.912,1.958],[-31.33,1.958],[-11.749,13.707]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[336.911,290.289],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":50,"op":55,"st":50,"bm":0,"sr":1},{"ddd":0,"ind":33,"ty":4,"nm":"“bird5”轮廓 5","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[722.4,326.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-2.687,10.967],[0,0],[0,0],[-17.329,-15.55],[-2.82,-9.358],[6.249,-1.562],[-1.563,-7.812],[12.498,3.125],[0,0],[10.544,2.952],[12.854,-5.228],[0,0]],"o":[[0,0],[0,0],[15.812,6.099],[5.337,5.34],[-6.249,1.562],[1.562,7.812],[-12.499,-3.125],[0,0],[-7.201,-5.419],[-6.796,11.518],[0,0],[7.373,-5.927]],"v":[[-35.481,-20.35],[-12.044,-20.35],[-7.356,-10.975],[44.207,-10.975],[48.894,-1.6],[30.144,3.087],[34.832,26.525],[-2.668,17.15],[-2.668,12.463],[-21.418,3.087],[-49.544,21.838],[-49.544,3.087]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[330.106,255.413],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":55,"op":60,"st":55,"bm":0,"sr":1},{"ddd":0,"ind":34,"ty":4,"nm":"“bird6”轮廓 5","ks":{"o":{"k":100},"r":{"k":2},"p":{"k":[642.171,323.086,0]},"a":{"k":[282,282,0]},"s":{"k":[81,81,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-4.111,-15.527],[0,0],[0,0],[22.036,-8.326],[0,0],[17.335,-4.717],[-9.421,10.488],[-3.666,1.833],[1.833,3.666],[0,0],[-17.999,0.529]],"o":[[0,0],[0,0],[-12.89,-5.223],[0,0],[-16.95,8.029],[2.692,-16.033],[3.666,-1.833],[-1.833,-3.666],[0,0],[9.378,8.705],[6.668,11.703]],"v":[[60.5,2.75],[49.5,2.75],[49.5,13.75],[-16.5,2.75],[-16.5,8.25],[-60.5,30.25],[-38.5,-13.75],[-27.5,-19.25],[-33,-30.25],[-11,-30.25],[44,-24.75]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[404.5,265.75],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":60,"op":65,"st":60,"bm":0,"sr":1},{"ddd":0,"ind":35,"ty":4,"nm":"“bird7”轮廓 5","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[595.886,326.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-8.984,-2.707],[0,0],[0,0],[0,0],[8.074,-4.289],[0,0],[0,0],[0,0],[0,0],[0,0],[13.905,-1.485],[-22.491,0.544],[-14.837,-0.458],[-26.478,-0.709]],"o":[[0,0],[0,0],[0,0],[-10.997,2.581],[0,0],[0,0],[0,0],[0,0],[0,0],[-11.332,-3.296],[3.258,-18.893],[6.732,7.916],[8.883,-16.33],[5.127,5.124]],"v":[[56.25,-15.396],[56.25,-6.396],[33.75,-6.396],[33.75,-1.896],[15.75,7.104],[20.25,20.604],[-6.75,20.604],[-11.25,11.604],[-20.25,11.604],[-20.25,7.104],[-56.25,16.104],[-24.75,-10.896],[2.25,-1.896],[47.25,-19.896]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[458.75,256.188],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":65,"op":70,"st":65,"bm":0,"sr":1},{"ddd":0,"ind":36,"ty":4,"nm":"“bird1”轮廓 7","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[966.171,307.657,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-18.399,1.814],[4.954,-17.65],[0,0],[0,0],[0,0],[0,0],[7.538,-1.077],[-11.769,1.159],[0,0],[0,0],[-3.64,2.761],[0,0],[0,0],[-7.028,-1.525]],"o":[[-4.209,19.462],[0,0],[0,0],[0,0],[0,0],[-7.537,1.076],[2.384,-10.393],[0,0],[0,0],[2.728,-3.666],[0,0],[0,0],[3.766,4.398],[7.271,-12.879]],"v":[[42,-25.846],[16.154,12.923],[22.615,12.923],[22.615,19.385],[-19.385,19.385],[-19.385,22.616],[-42,25.846],[-25.846,12.923],[-25.846,6.462],[-32.308,6.462],[-29.077,3.231],[-29.077,0],[-19.385,0],[-6.462,6.462]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[91,265.154],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":70,"op":75,"st":70,"bm":0,"sr":1},{"ddd":0,"ind":37,"ty":4,"nm":"“bird2”轮廓 6","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[975.429,338.514,0]},"a":{"k":[282,282,0]},"s":{"k":[92,92,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-5.408,-1.352],[2.301,-16.822],[0,0],[0,0],[24.332,2.943],[5.408,-9.464],[0,0],[-8.938,8.656],[0,0],[0,0],[-5.883,-3.196],[0,0],[-6.689,8.356]],"o":[[-3.71,14.259],[0,0],[0,0],[-27.344,5.177],[-5.408,9.465],[0,0],[-0.648,-18.234],[0,0],[0,0],[4.429,4.758],[0,0],[10.399,-4.567],[5.408,1.353]],"v":[[38.95,-28.396],[26.779,0.001],[34.893,0.001],[34.893,8.113],[-13.786,4.057],[-30.012,32.452],[-38.124,32.452],[-30.012,-12.17],[-30.012,-16.226],[-17.842,-16.226],[-5.673,-8.113],[-5.673,-12.17],[22.723,-32.452]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.99,0.99,0.98,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[85.672,249.548],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":75,"op":80,"st":75,"bm":0,"sr":1},{"ddd":0,"ind":38,"ty":4,"nm":"“bird3”轮廓 6","ks":{"o":{"k":100},"r":{"k":-1},"p":{"k":[848.914,338.514,0]},"a":{"k":[282,282,0]},"s":{"k":[90,90,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.396,-1.349],[-8.081,-2.435],[0,0],[10.282,-6.57],[0,0],[16.246,-2.406],[0,0],[-2.856,11.317],[0,0],[0,0],[0,0],[8.081,2.435],[0,0],[-12.142,-1.349],[0,0],[0,0],[0,0]],"o":[[0,0],[-5.396,1.349],[4.611,4.609],[0,0],[-16.192,-0.18],[0,0],[-9.993,7.861],[0,0],[8.839,-4.858],[0,0],[0,0],[0,0],[-4.611,-4.608],[0,0],[12.142,1.349],[0,0],[0,0],[0,0],[0,0]],"v":[[42.5,-28.334],[42.5,-16.191],[26.31,-12.144],[34.405,-8.096],[34.405,4.048],[-14.167,8.096],[-14.167,12.143],[-42.5,28.334],[-42.5,12.143],[-26.31,-8.096],[-22.262,-8.096],[-22.262,-12.144],[-26.31,-12.144],[-34.405,-16.191],[-34.405,-24.286],[2.024,-20.239],[2.024,-24.286],[10.119,-24.286],[10.119,-28.334]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[202.5,252.619],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":80,"op":85,"st":80,"bm":0,"sr":1},{"ddd":0,"ind":39,"ty":4,"nm":"“bird4”轮廓 6","ks":{"o":{"k":100},"r":{"k":-20},"p":{"k":[713.143,292.229,0]},"a":{"k":[282,282,0]},"s":{"k":[94,94,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-22.653,4.64],[0,0],[7.832,-6.526],[0,0],[0,0],[-1.306,-5.221],[0,0],[0,0],[6.859,5.485],[0,0],[0,0],[0,0],[6.149,9.6],[0,0],[-9.163,-2.245]],"o":[[0,0],[-7.832,6.526],[0,0],[0,0],[1.306,5.221],[0,0],[0,0],[-10.254,-2.44],[0,0],[0,0],[0,0],[-8.498,-5.304],[0,0],[4.952,6.159],[5.453,-21.362]],"v":[[50.912,-33.289],[50.912,-21.539],[27.414,-1.958],[23.498,13.707],[15.665,17.624],[19.582,33.289],[-11.749,33.289],[-11.749,29.372],[-31.33,17.624],[-31.33,13.707],[-39.163,13.707],[-39.163,9.79],[-50.912,1.958],[-31.33,1.958],[-11.749,13.707]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[336.911,290.289],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":85,"op":90,"st":85,"bm":0,"sr":1},{"ddd":0,"ind":40,"ty":4,"nm":"“bird5”轮廓 6","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[722.4,326.171,0]},"a":{"k":[282,282,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-2.687,10.967],[0,0],[0,0],[-17.329,-15.55],[-2.82,-9.358],[6.249,-1.562],[-1.563,-7.812],[12.498,3.125],[0,0],[10.544,2.952],[12.854,-5.228],[0,0]],"o":[[0,0],[0,0],[15.812,6.099],[5.337,5.34],[-6.249,1.562],[1.562,7.812],[-12.499,-3.125],[0,0],[-7.201,-5.419],[-6.796,11.518],[0,0],[7.373,-5.927]],"v":[[-35.481,-20.35],[-12.044,-20.35],[-7.356,-10.975],[44.207,-10.975],[48.894,-1.6],[30.144,3.087],[34.832,26.525],[-2.668,17.15],[-2.668,12.463],[-21.418,3.087],[-49.544,21.838],[-49.544,3.087]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[330.106,255.413],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":90,"op":95,"st":90,"bm":0,"sr":1},{"ddd":0,"ind":41,"ty":4,"nm":"“bird6”轮廓 6","ks":{"o":{"k":100},"r":{"k":2},"p":{"k":[642.171,323.086,0]},"a":{"k":[282,282,0]},"s":{"k":[81,81,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[-4.111,-15.527],[0,0],[0,0],[22.036,-8.326],[0,0],[17.335,-4.717],[-9.421,10.488],[-3.666,1.833],[1.833,3.666],[0,0],[-17.999,0.529]],"o":[[0,0],[0,0],[-12.89,-5.223],[0,0],[-16.95,8.029],[2.692,-16.033],[3.666,-1.833],[-1.833,-3.666],[0,0],[9.378,8.705],[6.668,11.703]],"v":[[60.5,2.75],[49.5,2.75],[49.5,13.75],[-16.5,2.75],[-16.5,8.25],[-60.5,30.25],[-38.5,-13.75],[-27.5,-19.25],[-33,-30.25],[-11,-30.25],[44,-24.75]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[404.5,265.75],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":2,"mn":"ADBE Vector Group"}],"ip":95,"op":100,"st":95,"bm":0,"sr":1},{"ddd":0,"ind":42,"ty":4,"nm":"“宝丽来”轮廓","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[417,469,0]},"a":{"k":[960,540,0]},"s":{"k":[80,80,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[380.469,64.844],[-380.469,64.844],[-380.469,-64.844],[380.469,-64.844]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":8},"lc":1,"lj":1,"ml":10,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[1,1,1,1]},"o":{"k":100},"nm":"填充 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[926.969,904.719],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 1","np":3,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[380.469,384.375],[-380.469,384.375],[-380.469,-384.375],[380.469,-384.375]],"c":true}},"nm":"路径 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":16},"lc":1,"lj":1,"ml":10,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[926.969,585.187],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"组 2","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":75,"st":0,"bm":0,"sr":1}],"v":"4.5.4","ddd":0,"ip":0,"op":75,"fr":25,"w":1112,"h":842} -------------------------------------------------------------------------------- /LottieInVideo/Resource/WelcomeToIsland.json: -------------------------------------------------------------------------------- 1 | {"assets":[],"fonts":{"list":[{"fName":"FZPXJW","fPath":"","fClass":"","fFamily":"FZPXJW","fWeight":"normal","fStyle":"Regular","fOrigin":"t","ascent":59.3484861776233}]},"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"空图层——控制大小","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[250,250,0]},"a":{"k":[0,0,0]},"s":{"k":[{"i":{"x":[0.217,0.217,0.667],"y":[1,1,0.667]},"o":{"x":[0.165,0.165,0.333],"y":[0,0,0.333]},"n":["0p217_1_0p165_0","0p217_1_0p165_0","0p667_0p667_0p333_0p333"],"t":4,"s":[88,88,100],"e":[108,108,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":56,"s":[108,108,100],"e":[108,108,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":62,"s":[108,108,100],"e":[88,88,100]},{"t":122}]}},"ao":0,"shapes":[],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"cube 4","parent":0,"ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[20],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75,"s":[20],"e":[0]},{"t":110}]},"r":{"k":[{"i":{"x":[0.048],"y":[1]},"o":{"x":[0.228],"y":[0]},"n":["0p048_1_0p228_0"],"t":0,"s":[0],"e":[45]},{"i":{"x":[0.048],"y":[0.048]},"o":{"x":[0.167],"y":[0.167]},"n":["0p048_0p048_0p167_0p167"],"t":35,"s":[45],"e":[45]},{"i":{"x":[0.772],"y":[1]},"o":{"x":[0.952],"y":[0]},"n":["0p772_1_0p952_0"],"t":75,"s":[45],"e":[0]},{"t":110}]},"p":{"k":[140.25,0,0]},"a":{"k":[1,-6,0]},"s":{"k":[{"i":{"x":[0.048,0.048,0.667],"y":[1,1,0.667]},"o":{"x":[0.228,0.228,0.333],"y":[0,0,0.333]},"n":["0p048_1_0p228_0","0p048_1_0p228_0","0p667_0p667_0p333_0p333"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.048,0.048,0.667],"y":[0.048,0.048,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p048_0p048_0p167_0p167","0p048_0p048_0p167_0p167","0p667_0p667_0p167_0p167"],"t":35,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.772,0.772,0.667],"y":[1,1,0.667]},"o":{"x":[0.952,0.952,0.333],"y":[0,0,0.333]},"n":["0p772_1_0p952_0","0p772_1_0p952_0","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,0,100]},{"t":110}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"k":[100,100]},"p":{"k":[0,0]},"r":{"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"k":[1,0,0,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0,0,0,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[1,-6],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Rectangle 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"cube 3","parent":0,"ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[20],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75,"s":[20],"e":[0]},{"t":110}]},"r":{"k":[{"i":{"x":[0.048],"y":[1]},"o":{"x":[0.228],"y":[0]},"n":["0p048_1_0p228_0"],"t":0,"s":[0],"e":[45]},{"i":{"x":[0.048],"y":[0.048]},"o":{"x":[0.167],"y":[0.167]},"n":["0p048_0p048_0p167_0p167"],"t":35,"s":[45],"e":[45]},{"i":{"x":[0.772],"y":[1]},"o":{"x":[0.952],"y":[0]},"n":["0p772_1_0p952_0"],"t":75,"s":[45],"e":[0]},{"t":110}]},"p":{"k":[-140.25,0,0]},"a":{"k":[1,-6,0]},"s":{"k":[{"i":{"x":[0.048,0.048,0.667],"y":[1,1,0.667]},"o":{"x":[0.228,0.228,0.333],"y":[0,0,0.333]},"n":["0p048_1_0p228_0","0p048_1_0p228_0","0p667_0p667_0p333_0p333"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.048,0.048,0.667],"y":[0.048,0.048,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p048_0p048_0p167_0p167","0p048_0p048_0p167_0p167","0p667_0p667_0p167_0p167"],"t":35,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.772,0.772,0.667],"y":[1,1,0.667]},"o":{"x":[0.952,0.952,0.333],"y":[0,0,0.333]},"n":["0p772_1_0p952_0","0p772_1_0p952_0","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,0,100]},{"t":110}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"k":[100,100]},"p":{"k":[0,0]},"r":{"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"k":[1,0,0,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0,0,0,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[1,-6],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Rectangle 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"cube ","parent":0,"ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[20],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75,"s":[20],"e":[0]},{"t":110}]},"r":{"k":[{"i":{"x":[0.048],"y":[1]},"o":{"x":[0.228],"y":[0]},"n":["0p048_1_0p228_0"],"t":0,"s":[0],"e":[45]},{"i":{"x":[0.048],"y":[0.048]},"o":{"x":[0.167],"y":[0.167]},"n":["0p048_0p048_0p167_0p167"],"t":35,"s":[45],"e":[45]},{"i":{"x":[0.772],"y":[1]},"o":{"x":[0.952],"y":[0]},"n":["0p772_1_0p952_0"],"t":75,"s":[45],"e":[0]},{"t":110}]},"p":{"k":[0,0,0]},"a":{"k":[1,-6,0]},"s":{"k":[{"i":{"x":[0.048,0.048,0.667],"y":[1,1,0.667]},"o":{"x":[0.228,0.228,0.333],"y":[0,0,0.333]},"n":["0p048_1_0p228_0","0p048_1_0p228_0","0p667_0p667_0p333_0p333"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.048,0.048,0.667],"y":[0.048,0.048,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p048_0p048_0p167_0p167","0p048_0p048_0p167_0p167","0p667_0p667_0p167_0p167"],"t":35,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.772,0.772,0.667],"y":[1,1,0.667]},"o":{"x":[0.952,0.952,0.333],"y":[0,0,0.333]},"n":["0p772_1_0p952_0","0p772_1_0p952_0","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,0,100]},{"t":110}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"k":[100,100]},"p":{"k":[0,0]},"r":{"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"k":[1,0,0,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0,0,0,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[1,-6],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Rectangle 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"cube 2","parent":0,"ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":2,"s":[0],"e":[10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[10],"e":[10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75,"s":[10],"e":[0]},{"t":110}]},"r":{"k":[{"i":{"x":[0.03],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p03_1_0p333_0"],"t":2,"s":[0],"e":[45]},{"i":{"x":[0.03],"y":[0.03]},"o":{"x":[0.167],"y":[0.167]},"n":["0p03_0p03_0p167_0p167"],"t":37,"s":[45],"e":[45]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.97],"y":[0]},"n":["0p667_1_0p97_0"],"t":75,"s":[45],"e":[0]},{"t":110}]},"p":{"k":[0,0,0]},"a":{"k":[1,-6,0]},"s":{"k":[{"i":{"x":[0,0,0.667],"y":[1,1,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0_1_0p333_0","0_1_0p333_0","0p667_0p667_0p333_0p333"],"t":2,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.667],"y":[0,0,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p667_0p667_0p167_0p167"],"t":37,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,0.667]},"o":{"x":[1,1,0.333],"y":[0,0,0.333]},"n":["0p667_1_1_0","0p667_1_1_0","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,0,100]},{"t":110}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"k":[171,171]},"p":{"k":[0,0]},"r":{"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"k":[1,0,0,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0,0,0,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[1,-6],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Rectangle 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 10","parent":14,"td":1,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[13.958,-192.913,0]},"a":{"k":[0,0,0]},"s":{"k":[251.226,70.754,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"k":[623.627,227.211]},"p":{"k":[0,0]},"r":{"k":0},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect"},{"ty":"st","c":{"k":[1,1,1,1]},"o":{"k":100},"w":{"k":0},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"fl","c":{"k":[0,0,0,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[5.402,143.646],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Rectangle 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":5,"nm":"NEVER STOP DREAMING(右)","parent":0,"tt":1,"ks":{"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":19,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":105,"s":[100],"e":[0]},{"t":117}]},"r":{"k":0},"p":{"k":[{"i":{"x":0,"y":1},"o":{"x":0.391,"y":0},"n":"0_1_0p391_0","t":6,"s":[2,50,0],"e":[2,10,0],"to":[0,-6.66666650772095,0],"ti":[0,6.66666650772095,0]},{"i":{"x":0.325,"y":0.325},"o":{"x":1,"y":1},"n":"0p325_0p325_1_1","t":51,"s":[2,10,0],"e":[2,10,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.601,"y":1},"o":{"x":1,"y":0.059},"n":"0p601_1_1_0p059","t":80,"s":[2,10,0],"e":[2,50,0],"to":[0,6.66666650772095,0],"ti":[0,-6.66666650772095,0]},{"t":117}]},"a":{"k":[0,0,0]},"s":{"k":[100,100,100]}},"ao":0,"t":{"d":{"k":[{"s":{"s":31,"f":"FZPXJW","t":"欢迎来到小岛","j":2,"tr":208,"lh":37.2,"fc":[0,0,0]},"t":0}]},"p":{},"m":{"g":1,"a":{"k":[0,0]}},"a":[]},"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 6","parent":0,"ks":{"o":{"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.205],"y":[0]},"n":["0_1_0p205_0"],"t":17,"s":[0],"e":[100]},{"i":{"x":[0],"y":[0]},"o":{"x":[0.333],"y":[0.333]},"n":["0_0_0p333_0p333"],"t":48,"s":[100],"e":[100]},{"i":{"x":[0.795],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p795_1_1_0"],"t":75,"s":[100],"e":[0]},{"t":106}]},"r":{"k":0},"p":{"k":[{"i":{"x":0,"y":1},"o":{"x":0.205,"y":0},"n":"0_1_0p205_0","t":17,"s":[0,-32,0],"e":[0,0,0],"to":[0,5.33333349227905,0],"ti":[0,-5.33333349227905,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"n":"0_0_0p333_0p333","t":48,"s":[0,0,0],"e":[0,0,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.795,"y":1},"o":{"x":1,"y":0},"n":"0p795_1_1_0","t":75,"s":[0,0,0],"e":[0,-32,0],"to":[0,-5.33333349227905,0],"ti":[0,5.33333349227905,0]},{"t":106}]},"a":{"k":[0,0,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-12,117],[1,130],[14,116.75]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 5","parent":0,"ks":{"o":{"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.205],"y":[0]},"n":["0_1_0p205_0"],"t":17,"s":[0],"e":[100]},{"i":{"x":[0],"y":[0]},"o":{"x":[0.333],"y":[0.333]},"n":["0_0_0p333_0p333"],"t":48,"s":[100],"e":[100]},{"i":{"x":[0.795],"y":[1]},"o":{"x":[1],"y":[0]},"n":["0p795_1_1_0"],"t":75,"s":[100],"e":[0]},{"t":106}]},"r":{"k":0},"p":{"k":[{"i":{"x":0,"y":1},"o":{"x":0.205,"y":0},"n":"0_1_0p205_0","t":17,"s":[0.75,-92.25,0],"e":[0.75,-124.25,0],"to":[0,-5.33333349227905,0],"ti":[0,5.33333349227905,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"n":"0_0_0p333_0p333","t":48,"s":[0.75,-124.25,0],"e":[0.75,-124.25,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.795,"y":1},"o":{"x":1,"y":0},"n":"0p795_1_1_0","t":75,"s":[0.75,-124.25,0],"e":[0.75,-92.25,0],"to":[0,5.33333349227905,0],"ti":[0,-5.33333349227905,0]},{"t":106}]},"a":{"k":[0.75,-124.25,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-10.75,-118.5],[0.75,-130],[12.25,-119.25]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":9,"ty":4,"nm":"line4","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[2,-34,0]},"a":{"k":[2,-34,0]},"s":{"k":[{"i":{"x":[0,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[0.165,0.333,0.333],"y":[0,0.333,0.333]},"n":["0_1_0p165_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":5,"s":[0,100,100],"e":[100,100,100]},{"i":{"x":[0,0.667,0.667],"y":[0,0.667,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0.333,0.333]},"n":["0_0_0p333_0p333","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":48,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.835,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[1,0.333,0.333],"y":[0,0.333,0.333]},"n":["0p835_1_1_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,100,100]},{"t":118}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-64,-34],[68,-34]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":10,"ty":4,"nm":"line3","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[2,33.5,0]},"a":{"k":[2,33.5,0]},"s":{"k":[{"i":{"x":[0,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[0.165,0.333,0.333],"y":[0,0.333,0.333]},"n":["0_1_0p165_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":5,"s":[0,100,100],"e":[100,100,100]},{"i":{"x":[0,0.667,0.667],"y":[0,0.667,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0.333,0.333]},"n":["0_0_0p333_0p333","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":48,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.835,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[1,0.333,0.333],"y":[0,0.333,0.333]},"n":["0p835_1_1_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,100,100]},{"t":118}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-64,33.5],[68,33.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":11,"ty":4,"nm":"line5","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[0,28.5,0]},"a":{"k":[0,28.5,0]},"s":{"k":[{"i":{"x":[0,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[0.301,0.333,0.333],"y":[0,0.333,0.333]},"n":["0_1_0p301_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":3,"s":[0,100,100],"e":[100,100,100]},{"i":{"x":[0,0.667,0.667],"y":[0,0.667,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0p667_0p667_0p167_0p167","0p667_0p667_0p167_0p167"],"t":48,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.699,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[1,0.333,0.333],"y":[0,0.333,0.333]},"n":["0p699_1_1_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,100,100]},{"t":120}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-129.5,28.5],[129.5,28.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":12,"ty":4,"nm":"line6","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[0.25,-29.5,0]},"a":{"k":[0.25,-29.5,0]},"s":{"k":[{"i":{"x":[0,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[0.301,0.333,0.333],"y":[0,0.333,0.333]},"n":["0_1_0p301_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":3,"s":[0,100,100],"e":[100,100,100]},{"i":{"x":[0,0.667,0.667],"y":[0,0.667,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0p667_0p667_0p167_0p167","0p667_0p667_0p167_0p167"],"t":48,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.699,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[1,0.333,0.333],"y":[0,0.333,0.333]},"n":["0p699_1_1_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":75,"s":[100,100,100],"e":[0,100,100]},{"t":120}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-129.5,-29.5],[130,-29.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":13,"ty":4,"nm":"line","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[1.1,-23.4,0]},"a":{"k":[15,-10,0]},"s":{"k":[{"i":{"x":[0,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[0.255,0.333,0.333],"y":[0,0.333,0.333]},"n":["0_1_0p255_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":0,"s":[0,154,100],"e":[154,154,100]},{"i":{"x":[0,0.667,0.667],"y":[0,1,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0,0.333]},"n":["0_0_0p333_0p333","0p667_1_0p333_0","0p667_0p667_0p333_0p333"],"t":48,"s":[154,154,100],"e":[154,154,100]},{"i":{"x":[0.745,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[1,0.333,0.333],"y":[0,0.333,0.333]},"n":["0p745_1_1_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":75,"s":[154,154,100],"e":[0,154,100]},{"t":123}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-130,-10],[160,-10]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":14,"ty":4,"nm":"line 2","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[1.1,24.6,0]},"a":{"k":[15,-10,0]},"s":{"k":[{"i":{"x":[0,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[0.255,0.333,0.333],"y":[0,0.333,0.333]},"n":["0_1_0p255_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":0,"s":[0,154,100],"e":[154,154,100]},{"i":{"x":[0,0.667,0.667],"y":[0,1,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0,0.333]},"n":["0_0_0p333_0p333","0p667_1_0p333_0","0p667_0p667_0p333_0p333"],"t":48,"s":[154,154,100],"e":[154,154,100]},{"i":{"x":[0.745,0.667,0.667],"y":[1,0.667,0.667]},"o":{"x":[1,0.333,0.333],"y":[0,0.333,0.333]},"n":["0p745_1_1_0","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":75,"s":[154,154,100],"e":[0,154,100]},{"t":123}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-130,-10],[160,-10]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"k":[0,0,0,1]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":0,"op":136,"st":0,"bm":0,"sr":1}],"v":"4.5.4","ddd":0,"ip":0,"op":136,"fr":30,"w":500,"h":500} -------------------------------------------------------------------------------- /LottieInVideo/Resource/xingxing.json: -------------------------------------------------------------------------------- 1 | {"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"0331-贴纸星星右 Outlines","ks":{"o":{"k":[{"i":{"x":[0.086],"y":[1]},"o":{"x":[0.812],"y":[-0.002]},"n":["0p086_1_0p812_-0p002"],"t":7,"s":[0],"e":[100]},{"i":{"x":[0.682],"y":[0.682]},"o":{"x":[0.157],"y":[0.157]},"n":["0p682_0p682_0p157_0p157"],"t":14,"s":[100],"e":[100]},{"i":{"x":[0.786],"y":[0.999]},"o":{"x":[0.433],"y":[0.075]},"n":["0p786_0p999_0p433_0p075"],"t":48,"s":[100],"e":[0]},{"i":{"x":[0.086],"y":[1]},"o":{"x":[0.812],"y":[-0.002]},"n":["0p086_1_0p812_-0p002"],"t":55,"s":[0],"e":[100]},{"t":62}]},"r":{"k":0},"p":{"k":[556,800,0]},"a":{"k":[540,540,0]},"s":{"k":[{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":9,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":19,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[1,1,0.167],"y":[1,1,0.167]},"n":["0p833_0p833_1_1","0p833_0p833_1_1","0p833_0p833_0p167_0p167"],"t":27,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":33,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":40,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":43,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":47,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":57,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":64,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":67,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[1,1,0.167],"y":[1,1,0.167]},"n":["0p833_0p833_1_1","0p833_0p833_1_1","0p833_0p833_0p167_0p167"],"t":75,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0,0,0.167]},"n":["0_1p001_1_0","0_1p001_1_0","0p833_0p833_0p167_0p167"],"t":81,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":88,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":91,"s":[100,100,100],"e":[0,0,100]},{"t":95}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[40.726,-24.399],[-16.978,-75.878],[-40.944,24.326],[17.16,74.864]],"o":[[41.667,23.169],[14.879,-76.312],[-41.377,-23.242],[-15.095,75.299]],"v":[[-90.013,0.688],[2.191,157.077],[90.013,-1.773],[-2.154,-157.076]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.96,0.87,0.08,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[540.012,548.797],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[1.122,0],[1.05,0.29],[0.217,6.589],[62.375,0.796],[0,6.661],[-2.208,2.607],[-3.403,0.072],[1.847,134.16],[0,0],[-2.317,2.389],[-3.33,0],[-1.086,-0.289],[0,-6.154],[0,0],[-63.713,-0.724],[0,-6.661],[6.551,-0.218],[0.397,-131.772],[6.082,-0.723]],"o":[[-1.123,0],[-6.625,0],[-4.054,-131.699],[-6.661,-0.144],[-0.435,-3.403],[2.172,-2.606],[63.714,-2.607],[0,0],[-0.108,-3.33],[2.317,-2.389],[0.58,0.941],[6.119,0.724],[0,0],[1.882,134.161],[6.698,0.145],[0,6.516],[-62.302,2.606],[0,6.082],[-1.086,0.362]],"v":[[3.747,275.199],[-0.525,274.548],[-10.227,263.036],[-130.704,22.734],[-142.721,10.498],[-139.898,1.52],[-131.102,-2.389],[-16.997,-254.637],[-17.54,-262.457],[-14.137,-271.435],[-5.34,-275.2],[0.814,-274.838],[10.335,-262.964],[10.046,-255],[131.101,-6.082],[143.156,6.154],[131.428,19.042],[17.685,262.674],[7.005,274.692]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0,0.66,0.76,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[539.831,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Group 2","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":72,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"0331-贴纸星星左 Outlines","ks":{"o":{"k":[{"i":{"x":[0.086],"y":[1]},"o":{"x":[0.812],"y":[-0.002]},"n":["0p086_1_0p812_-0p002"],"t":1,"s":[0],"e":[100]},{"i":{"x":[0.796],"y":[0.796]},"o":{"x":[0.163],"y":[0.163]},"n":["0p796_0p796_0p163_0p163"],"t":8,"s":[100],"e":[100]},{"i":{"x":[0.704],"y":[1]},"o":{"x":[0.37],"y":[0.004]},"n":["0p704_1_0p37_0p004"],"t":48,"s":[100],"e":[0]},{"i":{"x":[0.086],"y":[1]},"o":{"x":[0.812],"y":[-0.002]},"n":["0p086_1_0p812_-0p002"],"t":49,"s":[0],"e":[100]},{"t":56}]},"r":{"k":0},"p":{"k":[152,868,0]},"a":{"k":[540,540,0]},"s":{"k":[{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":2,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":9,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":12,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[1,1,0.167],"y":[1,1,0.167]},"n":["0p833_0p833_1_1","0p833_0p833_1_1","0p833_0p833_0p167_0p167"],"t":20,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1,1,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1_1_0p001","0_1_1_0p001","0p833_0p833_0p167_0p167"],"t":27,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":31,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":35,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":43,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":45,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":50,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":57,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":60,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[1,1,0.167],"y":[1,1,0.167]},"n":["0p833_0p833_1_1","0p833_0p833_1_1","0p833_0p833_0p167_0p167"],"t":68,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1,1,0.833]},"o":{"x":[1,1,0.167],"y":[0,0,0.167]},"n":["0_1_1_0","0_1_1_0","0p833_0p833_0p167_0p167"],"t":75,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":79,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":83,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":91,"s":[0,0,100],"e":[0,0,100]},{"t":93}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[27.729,-18.897],[-13.322,-50.319],[-27.875,18.824],[13.394,49.74]],"o":[[28.381,18.101],[11.874,-50.682],[-28.274,-18.101],[-12.018,50.102]],"v":[[-63.388,0.579],[1.52,107.372],[63.388,-1.158],[-1.485,-107.372]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.96,0.87,0.08,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[539.982,546.713],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[1.158,0],[1.123,0.361],[0.218,6.588],[46.156,0.579],[0,6.66],[-6.553,0.217],[1.376,101],[0,0.217],[-2.317,2.39],[-2.389,0.507],[-2.969,-0.797],[0,-5.937],[0,0],[-47.17,-0.507],[0,-6.661],[5.756,-0.218],[0.289,-99.118],[5.9,-0.941]],"o":[[-1.159,0],[-6.588,0],[-3.041,-99.046],[-6.66,-0.144],[0,-6.517],[47.097,-1.882],[-0.036,-0.145],[-0.109,-3.331],[1.701,-1.81],[1.376,-0.507],[5.683,1.086],[0,0],[1.303,103.462],[6.697,0.145],[-0.94,5.72],[-46.084,1.882],[0,5.936],[-1.122,0.362]],"v":[[2.698,213.369],[-1.503,212.718],[-10.843,201.278],[-100.042,20.562],[-112.06,8.327],[-100.331,-4.417],[-16.018,-194.181],[-16.417,-200.118],[-12.978,-209.024],[-6.643,-212.5],[0.67,-212.571],[10.625,-200.553],[10.516,-197.005],[100.005,-7.24],[112.06,4.996],[100.331,17.739],[16.236,200.916],[6.027,212.862]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0,0.66,0.76,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[540,539.835],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Group 2","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":72,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"0331-贴纸星星中 Outlines","ks":{"o":{"k":[{"i":{"x":[0.086],"y":[1]},"o":{"x":[0.812],"y":[-0.002]},"n":["0p086_1_0p812_-0p002"],"t":4,"s":[0],"e":[100]},{"i":{"x":[0.726],"y":[0.726]},"o":{"x":[0.159],"y":[0.159]},"n":["0p726_0p726_0p159_0p159"],"t":11,"s":[100],"e":[100]},{"i":{"x":[0.759],"y":[1]},"o":{"x":[0.416],"y":[0.034]},"n":["0p759_1_0p416_0p034"],"t":48,"s":[100],"e":[0]},{"i":{"x":[0.086],"y":[1]},"o":{"x":[0.812],"y":[-0.002]},"n":["0p086_1_0p812_-0p002"],"t":52,"s":[0],"e":[100]},{"t":59}]},"r":{"k":0},"p":{"k":[352,384,0]},"a":{"k":[540,540,0]},"s":{"k":[{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":7,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":14,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":17,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[1,1,0.167],"y":[1,1,0.167]},"n":["0p833_0p833_1_1","0p833_0p833_1_1","0p833_0p833_0p167_0p167"],"t":25,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":30,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":37,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":40,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":44,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0.001,0.001,0.167]},"n":["0_1p001_1_0p001","0_1p001_1_0p001","0p833_0p833_0p167_0p167"],"t":55,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":62,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":65,"s":[100,100,100],"e":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[1,1,0.167],"y":[1,1,0.167]},"n":["0p833_0p833_1_1","0p833_0p833_1_1","0p833_0p833_0p167_0p167"],"t":73,"s":[0,0,100],"e":[0,0,100]},{"i":{"x":[0,0,0.833],"y":[1.001,1.001,0.833]},"o":{"x":[1,1,0.167],"y":[0,0,0.167]},"n":["0_1p001_1_0","0_1p001_1_0","0p833_0p833_0p167_0p167"],"t":78,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0,0,0.833],"y":[0,0,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0_0_0p167_0p167","0_0_0p167_0p167","0p833_0p833_0p167_0p167"],"t":85,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p833_1_0p167_0","0p833_1_0p167_0","0p833_0p833_0p167_0p167"],"t":88,"s":[100,100,100],"e":[0,0,100]},{"t":92}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[63.822,-32.219],[-22.336,-121.201],[-63.641,32.943],[22.589,119.97]],"o":[[64.474,31.133],[18.969,-121.78],[-64.727,-30.336],[-19.223,120.549]],"v":[[-135.97,0],[3.404,245.298],[135.971,-3.838],[-3.438,-245.298]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0.96,0.87,0.08,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[540.066,553.795],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"},{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[1.412,-0.145],[0.796,0.217],[0.218,6.588],[89.453,1.158],[0,6.66],[-2.172,2.607],[-3.403,0.072],[2.679,192.806],[0.145,1.665],[0.072,2.099],[-2.28,2.389],[-3.295,0],[-0.76,-0.29],[0,-6.734],[0.109,-2.027],[-0.036,-1.738],[-92.964,-1.086],[0,-6.661],[6.552,-0.217],[0.543,-186.218],[6.299,-0.579]],"o":[[-1.521,0],[-6.589,0],[-5.719,-186.073],[-6.697,-0.145],[-0.434,-3.403],[2.208,-2.606],[92.927,-3.837],[-0.036,-1.665],[-0.181,-2.027],[-0.108,-3.331],[2.317,-2.317],[4.488,-0.434],[6.734,0],[0,2.099],[-0.109,1.665],[2.679,192.878],[6.697,0.145],[0,6.516],[-89.416,3.766],[0,6.299],[-1.339,0.362]],"v":[[4.471,379.023],[0.416,378.299],[-9.539,366.715],[-182.181,27.078],[-194.236,14.842],[-191.448,5.719],[-182.615,1.737],[-18.952,-354.841],[-19.278,-359.838],[-19.676,-365.992],[-16.237,-374.896],[-7.476,-378.589],[-0.671,-378.445],[9.539,-366.425],[9.321,-360.344],[9.141,-355.276],[182.615,-3.476],[194.67,8.76],[182.941,21.938],[19.784,366.353],[8.633,378.444]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"k":[0,0.66,0.76,1]},"o":{"k":100},"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"k":[539.831,539.894],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"变换"}],"nm":"Group 2","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":72,"st":0,"bm":0,"sr":1}],"v":"4.5.4","ddd":0,"ip":0,"op":72,"fr":24,"w":748,"h":1080} -------------------------------------------------------------------------------- /LottieInVideo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // LottieInVideo 4 | // 5 | // Created by lvpengwei on 2018/12/15. 6 | // Copyright © 2018 lvpengwei. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | import SCRecorder 12 | import AVFoundation 13 | import Lottie 14 | 15 | class ViewController: UIViewController { 16 | @IBOutlet weak var videoPreview: VideoPreview! 17 | @IBOutlet weak var progressLabel: UILabel! 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | setupVideo() 21 | } 22 | private func setupVideo() { 23 | guard let path = Bundle.main.path(forResource: "1532072337.63853", ofType: "MP4") else { return } 24 | let asset = AVAsset(url: URL(fileURLWithPath: path)) 25 | videoPreview.play(withAsset: asset, autoPlay: false) 26 | } 27 | @IBAction func addStickerAction(_ sender: Any) { 28 | setupSticker() 29 | } 30 | @IBAction func exportAction(_ sender: Any) { 31 | exportVideo() 32 | } 33 | private var sticker: Sticker? 34 | private func setupSticker() { 35 | if let sticker = self.sticker { 36 | videoPreview.removeSticker(sticker: sticker) 37 | } 38 | guard let stickerPath = Bundle.main.path(forResource: "drinks", ofType: "json") else { return } 39 | let start = videoPreview.player.fl_currentTime() 40 | let duration = min(CMTime(seconds: 3, preferredTimescale: 600), videoPreview.player.itemDuration - start) 41 | let sticker = Sticker() 42 | sticker.url = stickerPath 43 | sticker.range = CMTimeRange(start: start, duration: duration) 44 | videoPreview.addSticker(sticker: sticker) 45 | self.sticker = sticker 46 | } 47 | private var exportSession: SCAssetExportSession? 48 | private func exportVideo() { 49 | guard let path = Bundle.main.path(forResource: "1532072337.63853", ofType: "MP4") else { return } 50 | let asset = AVAsset(url: URL(fileURLWithPath: path)) 51 | let composition = AVMutableComposition() 52 | let videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: 1)! 53 | try? videoTrack.insertTimeRange(CMTimeRange(start: .zero, duration: asset.duration), of: asset.tracks(withMediaType: .video)[0], at: .zero) 54 | exportSession = SCAssetExportSession(asset: composition) 55 | exportSession?.videoConfiguration.composition = createVideoComposition(composition) 56 | exportSession?.delegate = self 57 | let outputURL = URL(fileURLWithPath: NSTemporaryDirectory() + "/\(Date().timeIntervalSince1970).mp4") 58 | exportSession?.outputUrl = outputURL 59 | exportSession?.outputFileType = AVFileType.mp4.rawValue 60 | 61 | progressLabel.isHidden = false 62 | exportSession?.exportAsynchronously(completionHandler: { [weak self] in 63 | guard let s = self else { return } 64 | s.progressLabel.isHidden = true 65 | if let err = s.exportSession?.error { 66 | print(err.localizedDescription) 67 | } else { 68 | print("complete") 69 | s.saveVideoToAlbum(outputURL, nil) 70 | } 71 | }) 72 | } 73 | private func requestAuthorization(completion: @escaping ()->Void) { 74 | if PHPhotoLibrary.authorizationStatus() == .notDetermined { 75 | PHPhotoLibrary.requestAuthorization { (status) in 76 | DispatchQueue.main.async { 77 | completion() 78 | } 79 | } 80 | } else if PHPhotoLibrary.authorizationStatus() == .authorized { 81 | completion() 82 | } 83 | } 84 | private func saveVideoToAlbum(_ outputURL: URL, _ completion: ((Error?) -> Void)?) { 85 | requestAuthorization { 86 | PHPhotoLibrary.shared().performChanges({ 87 | let request = PHAssetCreationRequest.forAsset() 88 | request.addResource(with: .video, fileURL: outputURL, options: nil) 89 | }) { (result, error) in 90 | DispatchQueue.main.async { 91 | if let error = error { 92 | print(error.localizedDescription) 93 | } else { 94 | print("保存成功") 95 | } 96 | completion?(error) 97 | } 98 | } 99 | } 100 | } 101 | private func createVideoComposition(_ asset: AVAsset) -> AVVideoComposition { 102 | let renderSize = CGSize(width: 1920, height: 1080) 103 | let videoTrack = asset.tracks(withMediaType: .video)[0] 104 | let videoComposition = AVMutableVideoComposition() 105 | videoComposition.renderSize = renderSize 106 | videoComposition.frameDuration = CMTimeMake(value: 20, timescale: 600) 107 | videoComposition.customVideoCompositorClass = CustomVideoCompositor.classForCoder() as? AVVideoCompositing.Type 108 | 109 | let layerInstruction = CustomLayerInstruction(assetTrack: videoTrack) 110 | layerInstruction.setOpacityRamp(fromStartOpacity: 1.0, toEndOpacity: 1.0, timeRange: CMTimeRangeMake(start: .zero, duration: asset.duration)) 111 | if let layer = createStickerLayer(in: renderSize) { 112 | layerInstruction.overlayStore.setItem(layer, timeRange: CMTimeRangeMake(start: .zero, duration: asset.duration)) 113 | } 114 | let instruction = AVMutableVideoCompositionInstruction() 115 | instruction.timeRange = CMTimeRange(start: CMTime.zero, duration: asset.duration) 116 | instruction.layerInstructions = [layerInstruction] 117 | videoComposition.instructions = [instruction] 118 | return videoComposition 119 | } 120 | private func createStickerLayer(in size: CGSize) -> StickerContainerLayer? { 121 | guard let sticker = sticker else { return nil } 122 | let layer = StickerContainerLayer() 123 | layer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) 124 | let animationLayer = CALayer.animation(withPath: sticker.url) 125 | let bounds = sticker.bounds(containerBounds: layer.bounds) 126 | let scale = bounds.width / animationLayer.bounds.width 127 | var transform = CGAffineTransform.init(scaleX: scale, y: scale) 128 | transform = sticker.transform.concatenating(transform) 129 | animationLayer.setAffineTransform(transform) 130 | animationLayer.position = sticker.center(containerBounds: layer.bounds) 131 | animationLayer.beginTime = sticker.range.start.seconds 132 | animationLayer.duration = sticker.range.duration.seconds 133 | animationLayer.speed = sticker.speed 134 | layer.addSublayer(animationLayer) 135 | return layer 136 | } 137 | } 138 | 139 | extension ViewController: SCAssetExportSessionDelegate { 140 | func assetExportSessionDidProgress(_ assetExportSession: SCAssetExportSession) { 141 | print("progress: \(assetExportSession.progress)") 142 | DispatchQueue.main.async { 143 | self.progressLabel.text = "\(assetExportSession.progress.format(f: ".2"))" 144 | } 145 | } 146 | } 147 | 148 | class StickerContainerLayer: CALayer { } 149 | extension StickerContainerLayer: ImageProvider { 150 | public func image(at time: CMTime, renderSize: CGSize, presentationTimeRange: CMTimeRange) -> CIImage? { 151 | guard let sublayers = sublayers else { return nil } 152 | for sublayer in sublayers { 153 | let beginTime = CMTime(seconds: sublayer.beginTime, preferredTimescale: 600) 154 | let duration = CMTime(seconds: sublayer.duration, preferredTimescale: 600) 155 | let timeRange = CMTimeRange(start: beginTime, duration: duration) 156 | if (timeRange.containsTime(time)) { 157 | sublayer.isHidden = false 158 | let progress = (time - beginTime).seconds / duration.seconds 159 | sublayer.display(with: CGFloat(progress)) 160 | } else { 161 | sublayer.isHidden = true 162 | } 163 | } 164 | let size = bounds.size 165 | let w = Int(size.width) 166 | let h = Int(size.height) 167 | guard let context = CGContext(data: nil, width: w, height: h, bitsPerComponent: 8, bytesPerRow: 4 * w, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else { return nil } 168 | render(in: context) 169 | guard let snapshot = context.makeImage() else { return nil } 170 | var result = CIImage(cgImage: snapshot) 171 | result = result.transformed(by: CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: result.extent.origin.y * 2 + result.extent.height)) 172 | return result 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '9.0' 3 | 4 | inhibit_all_warnings! 5 | 6 | def ui 7 | pod 'UIColor_Hex_Swift', '~> 4.2.0' 8 | pod 'SnapKit', '~> 4.2.0' 9 | end 10 | 11 | def video 12 | pod 'lottie-ios', :git => 'https://github.com/lvpengwei/lottie-ios.git', :commit => 'daf49528ae6ad235a4edfae68964c22256183422' 13 | pod 'AVPlayerSeeker', :git => 'https://github.com/lvpengwei/AVPlayerSeeker.git', :commit => '31381b0249d0d9a3dbae3a2c893fb132561547e7' 14 | pod 'SCRecorder', :git => 'https://github.com/lvpengwei/SCRecorder.git', :commit => 'f507fcc38228e14d1c2d970f559548742cbf13a6' 15 | end 16 | 17 | def fundmental 18 | pod 'RxCocoa', '~> 4.4.0' 19 | end 20 | 21 | target 'LottieInVideo' do 22 | use_frameworks! 23 | 24 | ui 25 | video 26 | fundmental 27 | end 28 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AVPlayerSeeker (1.1) 3 | - lottie-ios (3.1.0) 4 | - RxAtomic (4.4.0) 5 | - RxCocoa (4.4.0): 6 | - RxSwift (~> 4.0) 7 | - RxSwift (4.4.0): 8 | - RxAtomic (~> 4.4) 9 | - SCRecorder (2.7.0) 10 | - SnapKit (4.2.0) 11 | - UIColor_Hex_Swift (4.2.0) 12 | 13 | DEPENDENCIES: 14 | - AVPlayerSeeker (from `https://github.com/lvpengwei/AVPlayerSeeker.git`, commit `31381b0249d0d9a3dbae3a2c893fb132561547e7`) 15 | - lottie-ios (from `https://github.com/lvpengwei/lottie-ios.git`, commit `daf49528ae6ad235a4edfae68964c22256183422`) 16 | - RxCocoa (~> 4.4.0) 17 | - SCRecorder (from `https://github.com/lvpengwei/SCRecorder.git`, commit `f507fcc38228e14d1c2d970f559548742cbf13a6`) 18 | - SnapKit (~> 4.2.0) 19 | - UIColor_Hex_Swift (~> 4.2.0) 20 | 21 | SPEC REPOS: 22 | https://github.com/cocoapods/specs.git: 23 | - RxAtomic 24 | - RxCocoa 25 | - RxSwift 26 | - SnapKit 27 | - UIColor_Hex_Swift 28 | 29 | EXTERNAL SOURCES: 30 | AVPlayerSeeker: 31 | :commit: 31381b0249d0d9a3dbae3a2c893fb132561547e7 32 | :git: https://github.com/lvpengwei/AVPlayerSeeker.git 33 | lottie-ios: 34 | :commit: daf49528ae6ad235a4edfae68964c22256183422 35 | :git: https://github.com/lvpengwei/lottie-ios.git 36 | SCRecorder: 37 | :commit: f507fcc38228e14d1c2d970f559548742cbf13a6 38 | :git: https://github.com/lvpengwei/SCRecorder.git 39 | 40 | CHECKOUT OPTIONS: 41 | AVPlayerSeeker: 42 | :commit: 31381b0249d0d9a3dbae3a2c893fb132561547e7 43 | :git: https://github.com/lvpengwei/AVPlayerSeeker.git 44 | lottie-ios: 45 | :commit: daf49528ae6ad235a4edfae68964c22256183422 46 | :git: https://github.com/lvpengwei/lottie-ios.git 47 | SCRecorder: 48 | :commit: f507fcc38228e14d1c2d970f559548742cbf13a6 49 | :git: https://github.com/lvpengwei/SCRecorder.git 50 | 51 | SPEC CHECKSUMS: 52 | AVPlayerSeeker: 97a9f1d66c8c46d5889936033b3e88de06d45c54 53 | lottie-ios: 106cd6f0067e38434143cf89fe40a29847f90017 54 | RxAtomic: eacf60db868c96bfd63320e28619fe29c179656f 55 | RxCocoa: df63ebf7b9a70d6b4eeea407ed5dd4efc8979749 56 | RxSwift: 5976ecd04fc2fefd648827c23de5e11157faa973 57 | SCRecorder: bbb521dbc222908876ec9cd9156bbc8a893bed44 58 | SnapKit: fe8a619752f3f27075cc9a90244d75c6c3f27e2a 59 | UIColor_Hex_Swift: bc07fc197421ee896b9ed6dcfa2054b7fbf75145 60 | 61 | PODFILE CHECKSUM: b02a6ccc9d45c0cf0dbede7ab9b1784aaf39d214 62 | 63 | COCOAPODS: 1.6.1 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LottieInVideo 2 | Render Lottie in video by AVFoundation 3 | 4 | ### PAG vs Lottie 5 | 渲染矢量动画到视频里面,[PAG](https://pag.io)更适合做这件事。 6 | Rendering vector animation in video, [PAG](https://pag.io) is best for this job than lottie. 7 | 8 | ### Lottie 3.1.0 9 | 分支 master 使用的 Lottie 版本 10 | 11 | ### Lottie 2.5.2 12 | 分支 lottie-2.5.2 13 | 在 Lottie 2.5.2 版本,Lottie 重构了生成动画的方案。新的方案使用了各种插值器(`Interpolate`)来生成每一帧的贝塞尔曲线/点等等,最后用`CoreGraphics`来画。所以我们可以对`layer`做截图,然后把生成的图片和视频图片进行叠加。 14 | 15 | ### Lottie 1.0.4 16 | 在 Lottie 1.0.4 版本,Lottie 是基于 `CAAnimation` 实现的动画,那时候合成到视频中需要借助 `AVVideoComposition` 的 `animationTool`。 17 | ``` 18 | let instruction = AVMutableVideoCompositionInstruction() 19 | instruction.timeRange = CMTimeRange(start: CMTime.zero, duration: asset.duration) 20 | instruction.layerInstructions = [layerInstruction] 21 | videoComposition.instructions = [instruction] 22 | if let animationLayer = createStickerLayer(in: renderSize) { 23 | let parentLayer = CALayer() 24 | let videoLayer = CALayer() 25 | let contentLayer = CALayer() 26 | parentLayer.frame = CGRect(x: 0, y: 0, width: renderSize.width, height: renderSize.height) 27 | videoLayer.frame = CGRect(x: 0, y: 0, width: renderSize.width, height: renderSize.height) 28 | contentLayer.frame = CGRect(x: 0, y: 0, width: renderSize.width, height: renderSize.height) 29 | contentLayer.addSublayer(animationLayer) 30 | contentLayer.isGeometryFlipped = true 31 | parentLayer.addSublayer(videoLayer) 32 | parentLayer.addSublayer(contentLayer) 33 | videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer) 34 | } 35 | 36 | private func createStickerLayer(in size: CGSize) -> CALayer? { 37 | guard let sticker = sticker else { return nil } 38 | let layer = CALayer() 39 | layer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height) 40 | do { 41 | let animationData = try Data(contentsOf: URL(fileURLWithPath: sticker.url)) 42 | if let animationJSON = try JSONSerialization.jsonObject(with: animationData, options: JSONSerialization.ReadingOptions(rawValue: UInt(0))) as? Dictionary { 43 | let animationLayer = LOTAnimationLayer.animation(fromJSON: animationJSON, customData: [], loop: false)! 44 | animationLayer.bounds = sticker.bounds(containerBounds: layer.bounds) 45 | animationLayer.position = sticker.center(containerBounds: layer.bounds) 46 | animationLayer.setAffineTransform(sticker.transform) 47 | animationLayer.beginTime = sticker.range.start.seconds 48 | animationLayer.duration = sticker.range.duration.seconds 49 | animationLayer.speed = sticker.speed 50 | layer.addSublayer(animationLayer) 51 | } 52 | } catch let e { 53 | print(e) 54 | } 55 | return layer 56 | } 57 | ``` 58 | --------------------------------------------------------------------------------