diff --git a/doric-demo/assets/123.png b/doric-demo/assets/123.png new file mode 100644 index 00000000..f062f464 Binary files /dev/null and b/doric-demo/assets/123.png differ diff --git a/doric-demo/bundle/assets/123.png b/doric-demo/bundle/assets/123.png new file mode 100644 index 00000000..f062f464 Binary files /dev/null and b/doric-demo/bundle/assets/123.png differ diff --git a/doric-demo/src/ImageDemo.ts b/doric-demo/src/ImageDemo.ts index 8b38f500..642aa3d6 100644 --- a/doric-demo/src/ImageDemo.ts +++ b/doric-demo/src/ImageDemo.ts @@ -12,258 +12,289 @@ class ImageDemo extends Panel { build(rootView: Group): void { let imageView: Image scroller( - vlayout( - [ - text({ - text: "Image Demo", - layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), - textSize: 30, - textColor: Color.WHITE, - backgroundColor: colors[5], - textAlignment: gravity().center(), - height: 50, - }), + vlayout( + [ + text({ + text: "Image Demo", + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST), + textSize: 30, + textColor: Color.WHITE, + backgroundColor: colors[5], + textAlignment: gravity().center(), + height: 50, + }), - label('Button'), - image({ - image: Environment.platform === 'Android' - ? new AndroidAssetsResource("assets/The_Parthenon_in_Athens.jpeg") - : new MainBundleResource("assets/The_Parthenon_in_Athens.jpeg"), - }), - image({ - image: new AssetsResource("The_Parthenon_in_Athens.jpeg"), - }), - image({ - image: new RemoteResource("https://p.upyun.com/demo/webp/webp/jpg-0.webp"), - }), - image({ - image: new Base64Resource(img_base64[0]), - scaleType: ScaleType.ScaleToFill, - layoutConfig: { - widthSpec: LayoutSpec.FIT, - heightSpec: LayoutSpec.FIT, - }, - }), - image({ - imageBase64: button, - scaleType: ScaleType.ScaleToFill, - layoutConfig: { - widthSpec: LayoutSpec.JUST, - heightSpec: LayoutSpec.JUST, - }, - width: 200, - height: 150 / 2.75, - stretchInset: { - left: 100, - top: 0, - right: 100, - bottom: 0 - }, - imageScale: 2.75, - }), - image({ - imageBase64: button, - scaleType: ScaleType.ScaleToFill, - layoutConfig: { - widthSpec: LayoutSpec.JUST, - heightSpec: LayoutSpec.JUST, - }, - width: 200, - height: 75, - stretchInset: { - left: 100, - top: 0, - right: 100, - bottom: 0 - }, - imageScale: 2, + label("Button"), + image({ + image: + Environment.platform === "Android" + ? new AndroidAssetsResource( + "assets/The_Parthenon_in_Athens.jpeg" + ) + : new MainBundleResource( + "assets/The_Parthenon_in_Athens.jpeg" + ), + }), + image({ + image: new AssetsResource("The_Parthenon_in_Athens.jpeg"), + }), + image({ + image: new RemoteResource( + "https://p.upyun.com/demo/webp/webp/jpg-0.webp" + ), + }), + image({ + image: new Base64Resource(img_base64[0]), + scaleType: ScaleType.ScaleToFill, + layoutConfig: { + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.FIT, + }, + }), + image({ + imageBase64: button, + scaleType: ScaleType.ScaleToFill, + layoutConfig: { + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, + }, + width: 200, + height: 150 / 2.75, + stretchInset: { + left: 100, + top: 0, + right: 100, + bottom: 0, + }, + imageScale: 2.75, + }), + image({ + imageBase64: button, + scaleType: ScaleType.ScaleToFill, + layoutConfig: { + widthSpec: LayoutSpec.JUST, + heightSpec: LayoutSpec.JUST, + }, + width: 200, + height: 75, + stretchInset: { + left: 100, + top: 0, + right: 100, + bottom: 0, + }, + imageScale: 2, + }), + label("Gif "), + image({ + imageUrl: + "https://www.w3.org/People/mimasa/test/imgformat/img/w3c_home_animation.gif", + scaleType: ScaleType.ScaleToFill, + imageScale: 3, + }), + label("APNG"), + image({ + imageUrl: + "https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png", + }), + label("Animated WebP"), + image({ + imageUrl: + "https://p.upyun.com/demo/webp/webp/animated-gif-0.webp", + }), + label("WebP"), + (imageView = image({ + imageUrl: "https://p.upyun.com/demo/webp/webp/jpg-0.webp", + layoutConfig: layoutConfig().just(), + width: 200, + height: 200, + loadCallback: (ret) => { + if (ret) { + imageView.width = ret.width; + imageView.height = ret.height; + } + }, + })), + label("ScaleToFill"), + image({ + imageUrl, + width: 300, + height: 300, + isBlur: true, + border: { + width: 2, + color: Color.GRAY, + }, + scaleType: ScaleType.ScaleToFill, + layoutConfig: layoutConfig().just(), + loadCallback: (ret) => {}, + }), + label("ScaleAspectFit"), + image({ + imageUrl, + width: 300, + height: 300, + border: { + width: 2, + color: Color.GRAY, + }, + scaleType: ScaleType.ScaleAspectFit, + layoutConfig: layoutConfig().just(), + }), + label("ScaleAspectFill"), + image({ + imageUrl, + width: 300, + height: 300, + border: { + width: 2, + color: Color.GRAY, + }, + scaleType: ScaleType.ScaleAspectFill, + layoutConfig: layoutConfig().just(), + }), + label("ImageBase64"), + image({ + imageBase64: img_base64[0], + width: 300, + height: 300, + border: { + width: 2, + color: Color.GRAY, + }, + scaleType: ScaleType.ScaleAspectFill, + layoutConfig: layoutConfig().just(), + }), + label("StretchInset 1"), + image({ + imageBase64: img_base64[1], + height: 60, + width: 134, + scaleType: ScaleType.ScaleAspectFill, + layoutConfig: layoutConfig().just(), + }), + image({ + imageBase64: img_base64[1], + height: 60, + width: 294, + scaleType: ScaleType.ScaleToFill, + layoutConfig: layoutConfig().just(), + stretchInset: { + left: 0.85, + top: 0, + right: 0.149, + bottom: 0, + }, + }), - }), - label('Gif '), - image({ - imageUrl: "https://www.w3.org/People/mimasa/test/imgformat/img/w3c_home_animation.gif", - scaleType: ScaleType.ScaleToFill, - imageScale: 3, - }), - label('APNG'), - image({ - imageUrl: "https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png", - }), - label('Animated WebP'), - image({ - imageUrl: "https://p.upyun.com/demo/webp/webp/animated-gif-0.webp", + label("StretchInset 2"), + image({ + image: new AssetsResource("coupon_bg2.png"), + height: 48, + width: 78, + scaleType: ScaleType.ScaleAspectFill, + layoutConfig: layoutConfig().just(), + }), + image({ + image: new AssetsResource("coupon_bg2.png"), + height: 48, + width: 78 * 3, + scaleType: ScaleType.ScaleToFill, + imageScale: 1, + layoutConfig: layoutConfig().just(), + stretchInset: { + left: 0, + top: 0, + right: 76, + bottom: 0, + }, + }), - }), - label('WebP'), - imageView = image({ - imageUrl: "https://p.upyun.com/demo/webp/webp/jpg-0.webp", - layoutConfig: layoutConfig().just(), - width: 200, - height: 200, - loadCallback: (ret) => { - if (ret) { - imageView.width = ret.width - imageView.height = ret.height - } - } - }), - label('ScaleToFill'), - image({ - imageUrl, - width: 300, - height: 300, - isBlur: true, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleToFill, - layoutConfig: layoutConfig().just(), - loadCallback: (ret) => { - } - }), - label('ScaleAspectFit'), - image({ - imageUrl, - width: 300, - height: 300, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleAspectFit, - layoutConfig: layoutConfig().just(), - }), - label('ScaleAspectFill'), - image({ - imageUrl, - width: 300, - height: 300, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - label('ImageBase64'), - image({ - imageBase64: img_base64[0], - width: 300, - height: 300, - border: { - width: 2, - color: Color.GRAY, - }, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - label('StretchInset1'), - image({ - imageBase64: img_base64[1], - height: 60, - width: 134, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - image({ - imageBase64: img_base64[1], - height: 60, - width: 294, - scaleType: ScaleType.ScaleToFill, - layoutConfig: layoutConfig().just(), - stretchInset: { - left: 0.85, - top: 0, - right: 0.149, - bottom: 0 - } - }), + label("tileInset 1"), + image({ + image: new AssetsResource("dididi.png"), + height: 78, + width: 84, + backgroundColor: Color.BLACK, + scaleType: ScaleType.ScaleAspectFill, + layoutConfig: layoutConfig().just(), + }), + image({ + image: new AssetsResource("dididi.png"), + height: 78, + width: 84 * 3, + imageScale: 1, + backgroundColor: Color.BLACK, + scaleType: ScaleType.ScaleToFill, + layoutConfig: layoutConfig().just(), + tileInset: true, + }), - label('StretchInset 2'), - image({ - image: new AssetsResource("coupon_bg2.png"), - height: 48, - width: 78, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - image({ - image: new AssetsResource("coupon_bg2.png"), - height: 48, - width: 78*3, - scaleType: ScaleType.ScaleToFill, - imageScale:1, - layoutConfig: layoutConfig().just(), - stretchInset: { - left: 0, - top: 0, - right: 76, - bottom: 0 - } - }), - - label('tileInset'), - image({ - image: new AssetsResource("dididi.png"), - height: 78, - width: 84, - backgroundColor: Color.BLACK, - scaleType: ScaleType.ScaleAspectFill, - layoutConfig: layoutConfig().just(), - }), - image({ - image: new AssetsResource("dididi.png"), - height: 78 * 1, - width: 84 * 3, - imageScale:1, - backgroundColor: Color.BLACK, - scaleType: ScaleType.ScaleToFill, - layoutConfig: layoutConfig().just(), - tileInset: { - left: 0, - top: 0, - right: 0, - bottom: 0 - } - }), - ], - { - layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), - gravity: gravity().center(), - space: 10, - }), + label("tileInset 2"), + image({ + image: new AssetsResource("123.png"), + height: 288 / 2, + width: 154 / 2, + scaleType: ScaleType.ScaleAspectFill, + layoutConfig: layoutConfig().just(), + }), + image({ + image: new AssetsResource("123.png"), + height: 288, + width: 154, + imageScale: 2, + scaleType: ScaleType.ScaleToFill, + layoutConfig: layoutConfig().just(), + tileInset: + Environment.platform === "Android" + ? true + : { + left: 0, + top: 70, + right: 0, + bottom: 0, + }, + }), + ], { - layoutConfig: layoutConfig().most(), + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), + gravity: gravity().center(), + space: 10, } - ).also(it => { + ), + { + layoutConfig: layoutConfig().most(), + } + ) + .also((it) => { coordinator(context).verticalScrolling({ - scrollable: it, - scrollRange: { - start: 0, - end: 100, - }, - target: "NavBar", - changing: { - name: "backgroundColor", - start: Color.WHITE, - end: Color.RED, - } - }) + scrollable: it, + scrollRange: { + start: 0, + end: 100, + }, + target: "NavBar", + changing: { + name: "backgroundColor", + start: Color.WHITE, + end: Color.RED, + }, + }); coordinator(context).verticalScrolling({ - scrollable: it, - scrollRange: { - start: 0, - end: 100, - }, - target: imageView, - changing: { - name: "width", - start: 10, - end: 200, - } - }) - }).in(rootView) + scrollable: it, + scrollRange: { + start: 0, + end: 100, + }, + target: imageView, + changing: { + name: "width", + start: 10, + end: 200, + }, + }); + }) + .in(rootView); } onDestroy() { modal(context).toast('onDestroy') diff --git a/doric-iOS/Pod/Classes/Shader/DoricImageNode.m b/doric-iOS/Pod/Classes/Shader/DoricImageNode.m index f817cf2d..1b5400c2 100644 --- a/doric-iOS/Pod/Classes/Shader/DoricImageNode.m +++ b/doric-iOS/Pod/Classes/Shader/DoricImageNode.m @@ -564,7 +564,18 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id } else if ([@"stretchInset" isEqualToString:name]) { self.stretchInsetDic = (NSDictionary *) prop; } else if ([@"tileInset" isEqualToString:name]) { - self.tileInsetDic = (NSDictionary *) prop; + 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]) { //Do not need set } else if ([@"onAnimationEnd" isEqualToString:name]) { diff --git a/doric-js/index.d.ts b/doric-js/index.d.ts index 114bd61a..dc33ce8f 100644 --- a/doric-js/index.d.ts +++ b/doric-js/index.d.ts @@ -702,12 +702,19 @@ declare module 'doric/lib/src/widget/image' { right: 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. */ diff --git a/doric-js/lib/src/widget/image.d.ts b/doric-js/lib/src/widget/image.d.ts index 66276b93..d430b564 100644 --- a/doric-js/lib/src/widget/image.d.ts +++ b/doric-js/lib/src/widget/image.d.ts @@ -82,12 +82,19 @@ export declare class Image extends View { right: 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. */ diff --git a/doric-js/src/widget/image.ts b/doric-js/src/widget/image.ts index 2aba8884..d8fea34d 100644 --- a/doric-js/src/widget/image.ts +++ b/doric-js/src/widget/image.ts @@ -120,13 +120,20 @@ export class Image extends View { 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.