Skip to content

Commit 9412e94

Browse files
committed
Fix the contentMode adjustment to use viewBox, this allows the correct behavior during animation
1 parent 5b3a3fa commit 9412e94

File tree

3 files changed

+56
-38
lines changed

3 files changed

+56
-38
lines changed

SDWebImageSVGCoder/Classes/SDSVGImage.m

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
#import "SDSVGImage.h"
9+
#import "SDWebImageSVGCoderDefine.h"
910

1011
@interface SDSVGImage ()
1112

@@ -55,11 +56,19 @@ - (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale options:(SDImag
5556
if (!svgImage) {
5657
return nil;
5758
}
59+
// Check specified image size
60+
SDWebImageContext *context = options[SDImageCoderWebImageContext];
61+
if (context[SDWebImageContextVectorImageSize]) {
62+
CGSize imageSize = [context[SDWebImageContextVectorImageSize] CGSizeValue];
63+
if (!CGSizeEqualToSize(imageSize, CGSizeZero)) {
64+
svgImage.size = imageSize;
65+
}
66+
}
5867
return [self initWithSVGImage:svgImage];
5968
}
6069

6170
- (instancetype)initWithAnimatedCoder:(id<SDAnimatedImageCoder>)animatedCoder scale:(CGFloat)scale {
62-
// Does not support progressive load for GIF images at all
71+
// Does not support progressive load for SVG images at all
6372
return nil;
6473
}
6574

SDWebImageSVGCoder/Classes/SDWebImageSVGCoderDefine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
@class SVGKImage;
1111

1212
/**
13-
Adjust `SVGKImage`'s size && internal layerTree position to match the specify `contentMode` of view size.
13+
Adjust `SVGKImage`'s viewPort && viewBox to match the specify `contentMode` of view size.
1414
@note Though this util method can be used outside this framework. For simple SVG image loading, it's recommaned to use `sd_adjustContentMode` property on `SVGKImageView+WebCache`.
1515
1616
@param svgImage `SVGKImage` instance, should not be nil.

SDWebImageSVGCoder/Classes/SDWebImageSVGCoderDefine.m

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ void SDAdjustSVGContentMode(SVGKImage * svgImage, UIViewContentMode contentMode,
3737
case UIViewContentModeScaleAspectFit: {
3838
CGFloat scale = smallestScaleUp < 1.0f ? smallestScaleUp : biggestScaleDown;
3939
CGSize targetSize = CGSizeApplyAffineTransform(imageSize, CGAffineTransformMakeScale(scale, scale));
40-
CGFloat x = ceil(viewSize.width - targetSize.width) / 2;
41-
CGFloat y = ceil(viewSize.height - targetSize.height) / 2;
40+
xPosition = (viewSize.width - targetSize.width) / 2;
41+
yPosition = (viewSize.height - targetSize.height) / 2;
4242
svgImage.size = targetSize;
43-
svgImage.DOMTree.viewport = SVGRectMake(x, y, targetSize.width, targetSize.height);
43+
svgImage.DOMTree.viewport = SVGRectMake(xPosition, yPosition, targetSize.width, targetSize.height);
4444
// masksToBounds to clip the sublayer which beyond the viewport to match `UIImageView` behavior
4545
svgImage.CALayerTree.masksToBounds = YES;
4646
}
@@ -55,71 +55,80 @@ void SDAdjustSVGContentMode(SVGKImage * svgImage, UIViewContentMode contentMode,
5555
scale = hScale;
5656
}
5757
CGSize targetSize = CGSizeApplyAffineTransform(imageSize, CGAffineTransformMakeScale(scale, scale));
58-
svgImage.size = targetSize;
5958
if (imageAspect < viewAspect) {
6059
// need center y as well
61-
xPosition = targetSize.width / 2;
62-
yPosition = viewSize.height / 2;
60+
xPosition = 0;
61+
yPosition = (targetSize.height - viewSize.height) / 2;
6362
} else {
6463
// need center x as well
65-
xPosition = viewSize.width / 2;
66-
yPosition = targetSize.height / 2;
64+
xPosition = (targetSize.width - viewSize.width) / 2;
65+
yPosition = 0;
6766
}
68-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
67+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
68+
svgImage.size = targetSize;
6969
}
7070
break;
7171
case UIViewContentModeTop: {
72-
xPosition = viewSize.width / 2;
73-
yPosition = imageSize.height / 2;
74-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
72+
xPosition = (imageSize.width - viewSize.width) / 2;
73+
yPosition = 0;
74+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
75+
svgImage.size = imageSize;
7576
}
7677
break;
7778
case UIViewContentModeTopLeft: {
78-
xPosition = imageSize.width / 2;
79-
yPosition = imageSize.height / 2;
80-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
79+
xPosition = 0;
80+
yPosition = 0;
81+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
82+
svgImage.size = imageSize;
8183
}
8284
break;
8385
case UIViewContentModeTopRight: {
84-
xPosition = -imageSize.width / 2 + viewSize.width;
85-
yPosition = imageSize.height / 2;
86-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
86+
xPosition = imageSize.width - viewSize.width;
87+
yPosition = 0;
88+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
89+
svgImage.size = imageSize;
8790
}
8891
break;
8992
case UIViewContentModeCenter: {
90-
xPosition = viewSize.width / 2;
91-
yPosition = viewSize.height / 2;
92-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
93+
xPosition = (imageSize.width - viewSize.width) / 2;
94+
yPosition = (imageSize.height - viewSize.height) / 2;
95+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
96+
svgImage.size = imageSize;
9397
}
9498
break;
9599
case UIViewContentModeLeft: {
96-
xPosition = imageSize.width / 2;
97-
yPosition = viewSize.height / 2;
98-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
100+
xPosition = 0;
101+
yPosition = (imageSize.height - viewSize.height) / 2;
102+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
103+
svgImage.size = imageSize;
99104
}
100105
break;
101106
case UIViewContentModeRight: {
102-
xPosition = -imageSize.width / 2 + viewSize.width;
103-
yPosition = viewSize.height / 2;
104-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
107+
xPosition = imageSize.width - viewSize.width;
108+
yPosition = (imageSize.height - viewSize.height) / 2;
109+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
110+
svgImage.size = imageSize;
105111
}
106112
break;
107113
case UIViewContentModeBottom: {
108-
xPosition = viewSize.width / 2;
109-
yPosition = -imageSize.height / 2 + viewSize.height;
110-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
114+
xPosition = (imageSize.width - viewSize.width) / 2;
115+
yPosition = imageSize.height - viewSize.height;
116+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
117+
svgImage.size = imageSize;
111118
}
112119
break;
113120
case UIViewContentModeBottomLeft: {
114-
xPosition = imageSize.width / 2;
115-
yPosition = -imageSize.height / 2 + viewSize.height;
116-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
121+
xPosition = 0;
122+
yPosition = imageSize.height - viewSize.height;
123+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
124+
svgImage.size = imageSize;
117125
}
118126
break;
119127
case UIViewContentModeBottomRight: {
120-
xPosition = -imageSize.width / 2 + viewSize.width;
121-
yPosition = -imageSize.height / 2 + viewSize.height;
122-
svgImage.CALayerTree.position = CGPointMake(xPosition, yPosition);
128+
xPosition = imageSize.width - viewSize.width;
129+
yPosition = imageSize.height - viewSize.height;
130+
svgImage.DOMTree.viewBox = SVGRectMake(xPosition, yPosition, imageSize.width, imageSize.height);
131+
svgImage.size = imageSize;
123132
}
124133
break;
125134
case UIViewContentModeRedraw: {

0 commit comments

Comments
 (0)