image scaleType add an enumeration ScaleToTile.

This commit is contained in:
吴尚昆 2022-03-18 19:07:09 +08:00 committed by osborn
parent 31f45d161f
commit 55ff312312
12 changed files with 33 additions and 142 deletions

View File

@ -53,7 +53,6 @@ import com.bumptech.glide.request.target.DrawableImageViewTarget;
import com.bumptech.glide.request.target.SizeReadyCallback; import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import com.facebook.yoga.YogaNode; import com.facebook.yoga.YogaNode;
import com.github.pengfeizhou.jscore.JSBoolean;
import com.github.pengfeizhou.jscore.JSNumber; import com.github.pengfeizhou.jscore.JSNumber;
import com.github.pengfeizhou.jscore.JSONBuilder; import com.github.pengfeizhou.jscore.JSONBuilder;
import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSObject;
@ -93,9 +92,9 @@ public class ImageNode extends ViewNode<ImageView> {
private int placeHolderColor = Color.TRANSPARENT; private int placeHolderColor = Color.TRANSPARENT;
private int errorColor = Color.TRANSPARENT; private int errorColor = Color.TRANSPARENT;
private JSObject stretchInset = null; private JSObject stretchInset = null;
private JSObject tileInset = null;
private float imageScale = DoricUtils.getScreenScale(); private float imageScale = DoricUtils.getScreenScale();
private Animatable2Compat.AnimationCallback animationCallback = null; private Animatable2Compat.AnimationCallback animationCallback = null;
private int scaleType = 0;
public ImageNode(DoricContext doricContext) { public ImageNode(DoricContext doricContext) {
super(doricContext); super(doricContext);
@ -163,24 +162,6 @@ public class ImageNode extends ViewNode<ImageView> {
this.stretchInset = stretchInsetValue.asObject(); this.stretchInset = stretchInsetValue.asObject();
} }
JSValue tileInsetValue = jsObject.getProperty("tileInset");
if (tileInsetValue.isBoolean()) {
if (tileInsetValue.asBoolean().value()) {
// If boolean value 'true' is passed, it equals { left: 0, top: 0, right: 0, bottom: 0 }
JSObject obj = new JSObject();
JSNumber zero = new JSNumber(0);
obj.setProperty("top", zero);
obj.setProperty("left", zero);
obj.setProperty("right", zero);
obj.setProperty("bottom", zero);
this.tileInset = obj;
} else {
this.tileInset = null;
}
} else if (tileInsetValue.isObject()) {
this.tileInset = tileInsetValue.asObject();
} else { }
JSValue imageScaleValue = jsObject.getProperty("imageScale"); JSValue imageScaleValue = jsObject.getProperty("imageScale");
if (imageScaleValue.isNumber()) { if (imageScaleValue.isNumber()) {
this.imageScale = imageScaleValue.asNumber().toFloat(); this.imageScale = imageScaleValue.asNumber().toFloat();
@ -378,7 +359,13 @@ public class ImageNode extends ViewNode<ImageView> {
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
resource = new BitmapDrawable(getContext().getResources(), bitmap); resource = new BitmapDrawable(getContext().getResources(), bitmap);
} }
if (stretchInset != null) {
if (scaleType == 3) { // image tile
BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),bitmap);
drawable.setTileModeXY(Shader.TileMode.REPEAT , Shader.TileMode.REPEAT);
drawable.setDither(true);
super.setResource(drawable);
} else if (stretchInset != null) {
float left = stretchInset.getProperty("left").asNumber().toFloat() * scale; float left = stretchInset.getProperty("left").asNumber().toFloat() * scale;
float top = stretchInset.getProperty("top").asNumber().toFloat() * scale; float top = stretchInset.getProperty("top").asNumber().toFloat() * scale;
float right = stretchInset.getProperty("right").asNumber().toFloat() * scale; float right = stretchInset.getProperty("right").asNumber().toFloat() * scale;
@ -399,26 +386,6 @@ public class ImageNode extends ViewNode<ImageView> {
null null
); );
super.setResource(ninePatchDrawable); super.setResource(ninePatchDrawable);
} else if (tileInset != null) {
float left = tileInset.getProperty("left").asNumber().toFloat() * scale;
float top = tileInset.getProperty("top").asNumber().toFloat() * scale;
float right = tileInset.getProperty("right").asNumber().toFloat() * scale;
float bottom = tileInset.getProperty("bottom").asNumber().toFloat() * scale;
Rect rect = new Rect(
(int) left,
(int) top,
(int) (bitmap.getWidth() - right),
(int) (bitmap.getHeight() - bottom)
);
Matrix matrix = new Matrix();
matrix.setScale(1, 1);
bitmap = Bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height(), matrix, true);
BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),bitmap);
drawable.setTileModeXY(Shader.TileMode.REPEAT , Shader.TileMode.REPEAT);
drawable.setDither(true);
super.setResource(drawable);
} else { } else {
super.setResource(resource); super.setResource(resource);
} }
@ -478,7 +445,7 @@ public class ImageNode extends ViewNode<ImageView> {
if (!prop.isNumber()) { if (!prop.isNumber()) {
return; return;
} }
int scaleType = prop.asNumber().toInt(); scaleType = prop.asNumber().toInt();
switch (scaleType) { switch (scaleType) {
case 1: case 1:
view.setScaleType(ImageView.ScaleType.FIT_CENTER); view.setScaleType(ImageView.ScaleType.FIT_CENTER);

View File

@ -225,9 +225,8 @@ class ImageDemo extends Panel {
width: 84 * 3, width: 84 * 3,
imageScale: 1, imageScale: 1,
backgroundColor: Color.BLACK, backgroundColor: Color.BLACK,
scaleType: ScaleType.ScaleToFill, scaleType: ScaleType.ScaleToTile,
layoutConfig: layoutConfig().just(), layoutConfig: layoutConfig().just(),
tileInset: true,
}), }),
label("tileInset 2"), label("tileInset 2"),
@ -243,17 +242,8 @@ class ImageDemo extends Panel {
height: 288, height: 288,
width: 154, width: 154,
imageScale: 2, imageScale: 2,
scaleType: ScaleType.ScaleToFill, scaleType: ScaleType.ScaleToTile,
layoutConfig: layoutConfig().just(), layoutConfig: layoutConfig().just(),
tileInset:
Environment.platform === "Android"
? true
: {
left: 0,
top: 70,
right: 0,
bottom: 0,
},
}), }),
], ],
{ {

View File

@ -84,9 +84,9 @@ @interface DoricImageNode ()
@property(nonatomic, strong) NSString *errorImageBase64; @property(nonatomic, strong) NSString *errorImageBase64;
@property(nonatomic, strong) UIVisualEffectView *blurEffectView; @property(nonatomic, strong) UIVisualEffectView *blurEffectView;
@property(nonatomic, strong) NSDictionary *stretchInsetDic; @property(nonatomic, strong) NSDictionary *stretchInsetDic;
@property(nonatomic, strong) NSDictionary *tileInsetDic;
@property(nonatomic, assign) CGFloat imageScale; @property(nonatomic, assign) CGFloat imageScale;
@property(nonatomic, strong) NSDictionary *props; @property(nonatomic, strong) NSDictionary *props;
@property(nonatomic, assign) NSInteger scaleType;
@end @end
@ -382,7 +382,8 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id
#endif #endif
async = YES; async = YES;
} else if ([@"scaleType" isEqualToString:name]) { } else if ([@"scaleType" isEqualToString:name]) {
switch ([prop integerValue]) { self.scaleType = [prop integerValue];
switch (self.scaleType) {
case 1: { case 1: {
self.view.contentMode = UIViewContentModeScaleAspectFit; self.view.contentMode = UIViewContentModeScaleAspectFit;
break; break;
@ -391,6 +392,10 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id
self.view.contentMode = UIViewContentModeScaleAspectFill; self.view.contentMode = UIViewContentModeScaleAspectFill;
break; break;
} }
case 3: { // image tile
self.view.contentMode = UIViewContentModeScaleToFill;
break;
}
default: { default: {
self.view.contentMode = UIViewContentModeScaleToFill; self.view.contentMode = UIViewContentModeScaleToFill;
break; break;
@ -563,19 +568,6 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id
} }
} else if ([@"stretchInset" isEqualToString:name]) { } else if ([@"stretchInset" isEqualToString:name]) {
self.stretchInsetDic = (NSDictionary *) prop; self.stretchInsetDic = (NSDictionary *) prop;
} else if ([@"tileInset" isEqualToString:name]) {
if ([prop isKindOfClass:[NSNumber class]]) {
NSInteger value = [prop intValue];
if (value == 1) {
self.tileInsetDic = @{@"left": @0, @"top": @0, @"right": @0, @"bottom": @0};
} else {
self.tileInsetDic = nil;
}
} else if ([prop isKindOfClass:[NSDictionary class]]) {
self.tileInsetDic = (NSDictionary *) prop;
} else {
DoricLog(@"set tileInset error for View Type :%@, prop is %@", self.class, name);
}
} else if ([@"imageScale" isEqualToString:name]) { } else if ([@"imageScale" isEqualToString:name]) {
//Do not need set //Do not need set
} else if ([@"onAnimationEnd" isEqualToString:name]) { } else if ([@"onAnimationEnd" isEqualToString:name]) {
@ -683,7 +675,10 @@ - (void)afterBlended:(NSDictionary *)props {
if (CGSizeEqualToSize(self.view.image.size, CGSizeZero)) { if (CGSizeEqualToSize(self.view.image.size, CGSizeZero)) {
return; return;
} }
if (self.stretchInsetDic != nil) { if (self.scaleType == 3) { // image tile
UIImage *result = [self.view.image resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeTile];
self.view.image = result;
} else if (self.stretchInsetDic != nil) {
CGFloat left = [self.stretchInsetDic[@"left"] floatValue]; CGFloat left = [self.stretchInsetDic[@"left"] floatValue];
CGFloat top = [self.stretchInsetDic[@"top"] floatValue]; CGFloat top = [self.stretchInsetDic[@"top"] floatValue];
CGFloat right = [self.stretchInsetDic[@"right"] floatValue]; CGFloat right = [self.stretchInsetDic[@"right"] floatValue];
@ -691,14 +686,6 @@ - (void)afterBlended:(NSDictionary *)props {
CGFloat scale = self.imageScale; CGFloat scale = self.imageScale;
UIImage *result = [self.view.image resizableImageWithCapInsets:UIEdgeInsetsMake(top / scale, left / scale, bottom / scale, right / scale) resizingMode:UIImageResizingModeStretch]; UIImage *result = [self.view.image resizableImageWithCapInsets:UIEdgeInsetsMake(top / scale, left / scale, bottom / scale, right / scale) resizingMode:UIImageResizingModeStretch];
self.view.image = result; self.view.image = result;
} else if (self.tileInsetDic != nil) {
CGFloat left = [self.tileInsetDic[@"left"] floatValue];
CGFloat top = [self.tileInsetDic[@"top"] floatValue];
CGFloat right = [self.tileInsetDic[@"right"] floatValue];
CGFloat bottom = [self.tileInsetDic[@"bottom"] floatValue];
CGFloat scale = self.imageScale;
UIImage *result = [self.view.image resizableImageWithCapInsets:UIEdgeInsetsMake(top / scale, left / scale, bottom / scale, right / scale) resizingMode:UIImageResizingModeTile];
self.view.image = result;
} }
} }

View File

@ -2288,6 +2288,7 @@ exports.ScaleType = void 0;
ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill"; ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill";
ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit"; ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit";
ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill"; ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill";
ScaleType[ScaleType["ScaleToTile"] = 3] = "ScaleToTile";
})(exports.ScaleType || (exports.ScaleType = {})); })(exports.ScaleType || (exports.ScaleType = {}));
var Image = /** @class */ (function (_super) { var Image = /** @class */ (function (_super) {
__extends$e(Image, _super); __extends$e(Image, _super);
@ -2389,10 +2390,6 @@ var Image = /** @class */ (function (_super) {
Property, Property,
__metadata$b("design:type", Object) __metadata$b("design:type", Object)
], Image.prototype, "stretchInset", void 0); ], Image.prototype, "stretchInset", void 0);
__decorate$b([
Property,
__metadata$b("design:type", Object)
], Image.prototype, "tileInset", void 0);
__decorate$b([ __decorate$b([
Property, Property,
__metadata$b("design:type", Function) __metadata$b("design:type", Function)

View File

@ -1706,6 +1706,7 @@ exports.ScaleType = void 0;
ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill"; ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill";
ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit"; ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit";
ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill"; ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill";
ScaleType[ScaleType["ScaleToTile"] = 3] = "ScaleToTile";
})(exports.ScaleType || (exports.ScaleType = {})); })(exports.ScaleType || (exports.ScaleType = {}));
class Image extends View { class Image extends View {
isAnimating(context) { isAnimating(context) {
@ -1804,10 +1805,6 @@ __decorate$b([
Property, Property,
__metadata$b("design:type", Object) __metadata$b("design:type", Object)
], Image.prototype, "stretchInset", void 0); ], Image.prototype, "stretchInset", void 0);
__decorate$b([
Property,
__metadata$b("design:type", Object)
], Image.prototype, "tileInset", void 0);
__decorate$b([ __decorate$b([
Property, Property,
__metadata$b("design:type", Function) __metadata$b("design:type", Function)

View File

@ -3234,6 +3234,7 @@ exports.ScaleType = void 0;
ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill"; ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill";
ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit"; ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit";
ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill"; ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill";
ScaleType[ScaleType["ScaleToTile"] = 3] = "ScaleToTile";
})(exports.ScaleType || (exports.ScaleType = {})); })(exports.ScaleType || (exports.ScaleType = {}));
class Image extends View { class Image extends View {
isAnimating(context) { isAnimating(context) {
@ -3332,10 +3333,6 @@ __decorate$b([
Property, Property,
__metadata$b("design:type", Object) __metadata$b("design:type", Object)
], Image.prototype, "stretchInset", void 0); ], Image.prototype, "stretchInset", void 0);
__decorate$b([
Property,
__metadata$b("design:type", Object)
], Image.prototype, "tileInset", void 0);
__decorate$b([ __decorate$b([
Property, Property,
__metadata$b("design:type", Function) __metadata$b("design:type", Function)

16
doric-js/index.d.ts vendored
View File

@ -625,7 +625,8 @@ declare module 'doric/lib/src/widget/image' {
export enum ScaleType { export enum ScaleType {
ScaleToFill = 0, ScaleToFill = 0,
ScaleAspectFit = 1, ScaleAspectFit = 1,
ScaleAspectFill = 2 ScaleAspectFill = 2,
ScaleToTile = 3
} }
export class Image extends View { export class Image extends View {
/** /**
@ -702,19 +703,6 @@ declare module 'doric/lib/src/widget/image' {
right: number; right: number;
bottom: number; bottom: number;
}; };
/**
* image tile
*
* If boolean value 'true' is passed, it equals { left: 0, top: 0, right: 0, bottom: 0 }
* Android: only support all area tile, so you'd better pass boolean value.
* iOS: support custom area tile, so you can pass object value and boolean value.
*/
tileInset?: {
left: number;
top: number;
right: number;
bottom: number;
} | boolean;
/** /**
* Called if loaded image is animated and played end. * Called if loaded image is animated and played end.
*/ */

View File

@ -5,7 +5,8 @@ import { Resource } from "../util/resource";
export declare enum ScaleType { export declare enum ScaleType {
ScaleToFill = 0, ScaleToFill = 0,
ScaleAspectFit = 1, ScaleAspectFit = 1,
ScaleAspectFill = 2 ScaleAspectFill = 2,
ScaleToTile = 3
} }
export declare class Image extends View { export declare class Image extends View {
/** /**
@ -82,19 +83,6 @@ export declare class Image extends View {
right: number; right: number;
bottom: number; bottom: number;
}; };
/**
* image tile
*
* If boolean value 'true' is passed, it equals { left: 0, top: 0, right: 0, bottom: 0 }
* Android: only support all area tile, so you'd better pass boolean value.
* iOS: support custom area tile, so you can pass object value and boolean value.
*/
tileInset?: {
left: number;
top: number;
right: number;
bottom: number;
} | boolean;
/** /**
* Called if loaded image is animated and played end. * Called if loaded image is animated and played end.
*/ */

View File

@ -31,6 +31,7 @@ export var ScaleType;
ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill"; ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill";
ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit"; ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit";
ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill"; ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill";
ScaleType[ScaleType["ScaleToTile"] = 3] = "ScaleToTile";
})(ScaleType || (ScaleType = {})); })(ScaleType || (ScaleType = {}));
export class Image extends View { export class Image extends View {
isAnimating(context) { isAnimating(context) {
@ -129,10 +130,6 @@ __decorate([
Property, Property,
__metadata("design:type", Object) __metadata("design:type", Object)
], Image.prototype, "stretchInset", void 0); ], Image.prototype, "stretchInset", void 0);
__decorate([
Property,
__metadata("design:type", Object)
], Image.prototype, "tileInset", void 0);
__decorate([ __decorate([
Property, Property,
__metadata("design:type", Function) __metadata("design:type", Function)

View File

@ -23,6 +23,7 @@ export enum ScaleType {
ScaleToFill = 0, ScaleToFill = 0,
ScaleAspectFit, ScaleAspectFit,
ScaleAspectFill, ScaleAspectFill,
ScaleToTile, // image tile mode
} }
export class Image extends View { export class Image extends View {
@ -120,21 +121,6 @@ export class Image extends View {
bottom: number bottom: number
} }
/**
* image tile
*
* If boolean value 'true' is passed, it equals { left: 0, top: 0, right: 0, bottom: 0 }
* Android: only support all area tile, so you'd better pass boolean value.
* iOS: support custom area tile, so you can pass object value and boolean value.
*/
@Property
tileInset?: {
left: number,
top: number,
right: number,
bottom: number
} | boolean
/** /**
* Called if loaded image is animated and played end. * Called if loaded image is animated and played end.
*/ */

View File

@ -3308,6 +3308,7 @@ exports.ScaleType = void 0;
ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill"; ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill";
ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit"; ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit";
ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill"; ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill";
ScaleType[ScaleType["ScaleToTile"] = 3] = "ScaleToTile";
})(exports.ScaleType || (exports.ScaleType = {})); })(exports.ScaleType || (exports.ScaleType = {}));
class Image extends View { class Image extends View {
isAnimating(context) { isAnimating(context) {
@ -3406,10 +3407,6 @@ __decorate$b([
Property, Property,
__metadata$b("design:type", Object) __metadata$b("design:type", Object)
], Image.prototype, "stretchInset", void 0); ], Image.prototype, "stretchInset", void 0);
__decorate$b([
Property,
__metadata$b("design:type", Object)
], Image.prototype, "tileInset", void 0);
__decorate$b([ __decorate$b([
Property, Property,
__metadata$b("design:type", Function) __metadata$b("design:type", Function)

File diff suppressed because one or more lines are too long