diff --git a/spine-ios/CHANGELOG.md b/spine-ios/CHANGELOG.md index 02bfc1284..d1bbf3d59 100644 --- a/spine-ios/CHANGELOG.md +++ b/spine-ios/CHANGELOG.md @@ -22,3 +22,4 @@ - Add option to disable drawing when out of viewport (#18) - Add docs for public Spine classes/methods (#19) - Fix various regressions (#20) +- Add `boundsProvider` parameter to `SkeletonDrawableWrapper.renderToImage(...)` to align image rendering bounds with `SpineView` (#3002) diff --git a/spine-ios/Example/Spine iOS Example/DressUp.swift b/spine-ios/Example/Spine iOS Example/DressUp.swift index 5d48d3f53..87425c341 100644 --- a/spine-ios/Example/Spine iOS Example/DressUp.swift +++ b/spine-ios/Example/Spine iOS Example/DressUp.swift @@ -58,7 +58,7 @@ struct DressUp: View { SpineView( from: .drawable(drawable), controller: model.controller, - boundsProvider: SkinAndAnimationBounds(skins: ["full-skins/girl"]) + boundsProvider: model.boundsProvider ) } else { Spacer() @@ -76,6 +76,7 @@ struct DressUp: View { final class DressUpModel: ObservableObject { let thumbnailSize = CGSize(width: 200, height: 200) + let boundsProvider: BoundsProvider = SkinAndAnimationBounds(skins: ["full-skins/girl"]) @Published var controller: SpineController @@ -118,6 +119,7 @@ final class DressUpModel: ObservableObject { try skin.name.flatMap { skinName in self.skinImages[skinName] = try drawable.renderToImage( size: self.thumbnailSize, + boundsProvider: self.boundsProvider, backgroundColor: .white, scaleFactor: UIScreen.main.scale ) diff --git a/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift b/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift index 9ddb991d4..66ef8a3c3 100644 --- a/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift +++ b/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift @@ -37,11 +37,18 @@ public extension SkeletonDrawableWrapper { /// /// Parameters: /// - size: The size of the `CGImage` that should be rendered. + /// - boundsProvider: The skeleton bounds provider used to compute fitting and positioning. /// - backgroundColor: the background color of the image /// - scaleFactor: The scale factor. Set this to `UIScreen.main.scale` if you want to show the image in a view - func renderToImage(size: CGSize, backgroundColor: UIColor, scaleFactor: CGFloat = 1) throws -> CGImage? { + func renderToImage( + size: CGSize, + boundsProvider: BoundsProvider = SetupPoseBounds(), + backgroundColor: UIColor, + scaleFactor: CGFloat = 1 + ) throws -> CGImage? { let spineView = SpineUIView( controller: SpineController(disposeDrawableOnDeInit: false), // Doesn't own the drawable + boundsProvider: boundsProvider, backgroundColor: backgroundColor ) spineView.frame = CGRect(origin: .zero, size: size) diff --git a/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift b/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift index 08085c61a..a2bc5f942 100644 --- a/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift +++ b/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift @@ -46,7 +46,7 @@ import UIKit /// To update the ``AnimationState`` and apply it to the ``Skeleton`` call the ``AnimationStateWrapper/update`` function, providing it /// a delta time in seconds to advance the animations. /// -/// To render the current pose of the ``Skeleton`` as a `CGImage`, use ``SkeletonDrawableWrapper/renderToImage(size:backgroundColor:scaleFactor:)``. +/// To render the current pose of the ``Skeleton`` as a `CGImage`, use ``SkeletonDrawableWrapper/renderToImage(size:boundsProvider:backgroundColor:scaleFactor:)``. /// /// When the skeleton drawable is no longer needed, call the ``SkeletonDrawableWrapper/dispose()`` method to release its resources. If /// the skeleton drawable was constructed from a shared ``Atlas`` and ``SkeletonData``, make sure to dispose the