mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 03:31:45 +08:00
async image loading from data, files and resources for ios
Use the tns_safeDecodeImageNamedCompletion from the widgets framework Add loadMode on Image with sync and async options for local images
This commit is contained in:

committed by
Panayot Cankov

parent
b8785afd74
commit
1b395aac7f
@ -42,12 +42,7 @@ export var test_settingImageSource = function () {
|
||||
}
|
||||
*/
|
||||
|
||||
export var test_SettingImageSrc = function (done) {
|
||||
// >> img-create-src
|
||||
var image = new ImageModule.Image();
|
||||
image.src = "https://www.google.com/images/errors/logo_sm_2.png";
|
||||
// << img-create-src
|
||||
|
||||
function runImageTest(done, image: ImageModule.Image, src: string) {
|
||||
image.src = null;
|
||||
|
||||
var testModel = new ObservableModule.Observable();
|
||||
@ -61,10 +56,16 @@ export var test_SettingImageSrc = function (done) {
|
||||
TKUnit.assertTrue(!image.isLoading, "Image.isLoading should be false.");
|
||||
TKUnit.assertTrue(!testModel.get("imageIsLoading"), "imageIsLoading on viewModel should be false.");
|
||||
TKUnit.assertTrue(imageIsLoaded, "imageIsLoading should be true.");
|
||||
done(null);
|
||||
if (done) {
|
||||
done(null);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
if (done) {
|
||||
done(e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -74,53 +75,55 @@ export var test_SettingImageSrc = function (done) {
|
||||
twoWay: true
|
||||
}, testModel);
|
||||
|
||||
image.src = "https://www.google.com/images/errors/logo_sm_2.png";
|
||||
image.src = src;
|
||||
testModel.on(ObservableModule.Observable.propertyChangeEvent, handler);
|
||||
TKUnit.assertTrue(image.isLoading, "Image.isLoading should be true.");
|
||||
TKUnit.assertTrue(testModel.get("imageIsLoading"), "model.isLoading should be true.");
|
||||
if (done) {
|
||||
TKUnit.assertTrue(image.isLoading, "Image.isLoading should be true.");
|
||||
TKUnit.assertTrue(testModel.get("imageIsLoading"), "model.isLoading should be true.");
|
||||
} else {
|
||||
// Since it is synchronous check immediately.
|
||||
handler(null);
|
||||
}
|
||||
}
|
||||
|
||||
export var test_SettingImageSrcToFileWithinApp = function (done) {
|
||||
export var test_SettingImageSrc = function (done) {
|
||||
// >> img-create-src
|
||||
var image = new ImageModule.Image();
|
||||
image.src = "https://www.google.com/images/errors/logo_sm_2.png";
|
||||
// << img-create-src
|
||||
runImageTest(done, image, image.src)
|
||||
}
|
||||
|
||||
export var test_SettingImageSrcToFileWithinApp = function () {
|
||||
// >> img-create-local
|
||||
var image = new ImageModule.Image();
|
||||
image.src = "~/logo.png";
|
||||
// << img-create-local
|
||||
|
||||
var testFunc = function (views: Array<ViewModule.View>) {
|
||||
var testImage = <ImageModule.Image> views[0];
|
||||
TKUnit.waitUntilReady(() => !testImage.isLoading, 3);
|
||||
try {
|
||||
TKUnit.assertTrue(!testImage.isLoading, "isLoading should be false.");
|
||||
done(null);
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
}
|
||||
|
||||
helper.buildUIAndRunTest(image, testFunc);
|
||||
runImageTest(null, image, image.src)
|
||||
}
|
||||
|
||||
export var test_SettingImageSrcToDataURI = function (done) {
|
||||
export var test_SettingImageSrcToDataURI = function () {
|
||||
// >> img-create-datauri
|
||||
var image = new ImageModule.Image();
|
||||
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c6QAAABxpRE9UAAAAAgAAAAAAAAACAAAAKAAAAAIAAAACAAAARiS4uJEAAAASSURBVBgZYvjPwABHSMz/DAAAAAD//0GWpK0AAAAOSURBVGNgYPiPhBgQAACEvQv1D5y/pAAAAABJRU5ErkJggg==";
|
||||
// << img-create-datauri
|
||||
|
||||
var testFunc = function (views: Array<ViewModule.View>) {
|
||||
var testImage = <ImageModule.Image>views[0];
|
||||
TKUnit.waitUntilReady(() => !testImage.isLoading, 3);
|
||||
try {
|
||||
TKUnit.assertTrue(!testImage.isLoading, "isLoading should be false.");
|
||||
TKUnit.assertNotNull(testImage.imageSource);
|
||||
done(null);
|
||||
}
|
||||
catch (e) {
|
||||
done(e);
|
||||
}
|
||||
}
|
||||
runImageTest(null, image, image.src)
|
||||
}
|
||||
|
||||
helper.buildUIAndRunTest(image, testFunc);
|
||||
export var test_SettingImageSrcToFileWithinAppAsync = function (done) {
|
||||
var image = new ImageModule.Image();
|
||||
image.loadMode = "async";
|
||||
image.src = "~/logo.png";
|
||||
runImageTest(done, image, image.src)
|
||||
}
|
||||
|
||||
export var test_SettingImageSrcToDataURIAsync = function (done) {
|
||||
var image = new ImageModule.Image();
|
||||
image.loadMode = "async";
|
||||
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c6QAAABxpRE9UAAAAAgAAAAAAAAACAAAAKAAAAAIAAAACAAAARiS4uJEAAAASSURBVBgZYvjPwABHSMz/DAAAAAD//0GWpK0AAAAOSURBVGNgYPiPhBgQAACEvQv1D5y/pAAAAABJRU5ErkJggg==";
|
||||
runImageTest(done, image, image.src)
|
||||
}
|
||||
|
||||
export var test_SettingStretch_AspectFit = function () {
|
||||
|
@ -98,27 +98,14 @@ export function request(options: http.HttpRequestOptions): Promise<http.HttpResp
|
||||
},
|
||||
toImage: () => {
|
||||
ensureImageSource();
|
||||
if (UIImage.imageWithData["async"]) {
|
||||
return UIImage.imageWithData["async"](UIImage, [data])
|
||||
.then(image => {
|
||||
if (!image) {
|
||||
throw new Error("Response content may not be converted to an Image");
|
||||
}
|
||||
|
||||
var source = new imageSource.ImageSource();
|
||||
source.setNativeSource(image);
|
||||
return source;
|
||||
});
|
||||
}
|
||||
|
||||
return new Promise<any>((resolveImage, rejectImage) => {
|
||||
var img = imageSource.fromData(data);
|
||||
if (img instanceof imageSource.ImageSource) {
|
||||
resolveImage(img);
|
||||
} else {
|
||||
rejectImage(new Error("Response content may not be converted to an Image"));
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
(<any>UIImage).tns_decodeImageWithDataCompletion(data, image => {
|
||||
if (image) {
|
||||
resolve(imageSource.fromNativeSource(image))
|
||||
} else {
|
||||
reject(new Error("Response content may not be converted to an Image"));
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
toFile: (destinationFilePath?: string) => {
|
||||
|
@ -33,12 +33,9 @@ export function getJSON<T>(arg: any): Promise<T> {
|
||||
}
|
||||
|
||||
export function getImage(arg: any): Promise<image.ImageSource> {
|
||||
return new Promise<image.ImageSource>((resolve, reject) => {
|
||||
httpRequest.request(typeof arg === "string" ? { url: arg, method: "GET" } : arg)
|
||||
.then(r => {
|
||||
r.content.toImage().then(source => resolve(source), e => reject(e));
|
||||
}, e => reject(e));
|
||||
});
|
||||
return httpRequest
|
||||
.request(typeof arg === "string" ? { url: arg, method: "GET" } : arg)
|
||||
.then(responce => responce.content.toImage());
|
||||
}
|
||||
|
||||
export function getFile(arg: any, destinationFilePath?: string): Promise<any> {
|
||||
|
@ -44,7 +44,7 @@ export class ImageSource implements definition.ImageSource {
|
||||
// Load BitmapDrawable with getDrawable to make use of Android internal caching
|
||||
var bitmapDrawable = <android.graphics.drawable.BitmapDrawable>res.getDrawable(identifier);
|
||||
if (bitmapDrawable && bitmapDrawable.getBitmap) {
|
||||
this.android = bitmapDrawable.getBitmap();
|
||||
this.android = bitmapDrawable.getBitmap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,6 +52,12 @@ export class ImageSource implements definition.ImageSource {
|
||||
return this.android != null;
|
||||
}
|
||||
|
||||
public fromResource(name: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
resolve(this.loadFromResource(name));
|
||||
});
|
||||
}
|
||||
|
||||
public loadFromFile(path: string): boolean {
|
||||
ensureFS();
|
||||
|
||||
@ -64,11 +70,23 @@ export class ImageSource implements definition.ImageSource {
|
||||
return this.android != null;
|
||||
}
|
||||
|
||||
public fromFile(path: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
resolve(this.loadFromFile(path));
|
||||
});
|
||||
}
|
||||
|
||||
public loadFromData(data: any): boolean {
|
||||
this.android = android.graphics.BitmapFactory.decodeStream(data);
|
||||
return this.android != null;
|
||||
}
|
||||
|
||||
public fromData(data: any): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
resolve(this.loadFromData(data));
|
||||
});
|
||||
}
|
||||
|
||||
public loadFromBase64(source: string): boolean {
|
||||
if (types.isString(source)) {
|
||||
var bytes = android.util.Base64.decode(source, android.util.Base64.DEFAULT);
|
||||
@ -77,6 +95,12 @@ export class ImageSource implements definition.ImageSource {
|
||||
return this.android != null;
|
||||
}
|
||||
|
||||
public fromBase64(data: any): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
resolve(this.loadFromBase64(data));
|
||||
});
|
||||
}
|
||||
|
||||
public setNativeSource(source: any): boolean {
|
||||
this.android = source;
|
||||
return source != null;
|
||||
|
24
image-source/image-source.d.ts
vendored
24
image-source/image-source.d.ts
vendored
@ -33,23 +33,47 @@ declare module "image-source" {
|
||||
*/
|
||||
loadFromResource(name: string): boolean;
|
||||
|
||||
/**
|
||||
* Loads this instance from the specified resource name asynchronously.
|
||||
* @param name The name of the resource (without its extension).
|
||||
*/
|
||||
fromResource(name: string): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Loads this instance from the specified file.
|
||||
* @param path The location of the file on the file system.
|
||||
*/
|
||||
loadFromFile(path: string): boolean;
|
||||
|
||||
/**
|
||||
* Loads this instance from the specified file asynchronously.
|
||||
* @param path The location of the file on the file system.
|
||||
*/
|
||||
fromFile(path: string): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Loads this instance from the specified native image data.
|
||||
* @param data The native data (byte array) to load the image from. This will be either Stream for Android or NSData for iOS.
|
||||
*/
|
||||
loadFromData(data: any): boolean;
|
||||
|
||||
/**
|
||||
* Loads this instance from the specified native image data asynchronously.
|
||||
* @param data The native data (byte array) to load the image from. This will be either Stream for Android or NSData for iOS.
|
||||
*/
|
||||
fromData(data: any): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Loads this instance from the specified native image data.
|
||||
* @param source The Base64 string to load the image from.
|
||||
*/
|
||||
loadFromBase64(source: string): boolean;
|
||||
|
||||
/**
|
||||
* Loads this instance from the specified native image data asynchronously.
|
||||
* @param source The Base64 string to load the image from.
|
||||
*/
|
||||
fromBase64(source: string): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Sets the provided native source object (typically a Bitmap).
|
||||
|
@ -11,10 +11,30 @@ export class ImageSource implements definition.ImageSource {
|
||||
public ios: UIImage;
|
||||
|
||||
public loadFromResource(name: string): boolean {
|
||||
this.ios = UIImage.imageNamed(name) || UIImage.imageNamed(`${name}.jpg`);
|
||||
this.ios = (<any>UIImage).tns_safeImageNamed(name) || (<any>UIImage).tns_safeImageNamed(`${name}.jpg`);
|
||||
return this.ios != null;
|
||||
}
|
||||
|
||||
public fromResource(name: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
try {
|
||||
(<any>UIImage).tns_safeDecodeImageNamedCompletion(name, image => {
|
||||
if (image) {
|
||||
this.ios = image;
|
||||
resolve(true);
|
||||
} else {
|
||||
(<any>UIImage).tns_safeDecodeImageNamedCompletion(`${name}.jpg`, image => {
|
||||
this.ios = image;
|
||||
resolve(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public loadFromFile(path: string): boolean {
|
||||
var fileName = types.isString(path) ? path.trim() : "";
|
||||
|
||||
@ -26,19 +46,67 @@ export class ImageSource implements definition.ImageSource {
|
||||
return this.ios != null;
|
||||
}
|
||||
|
||||
public fromFile(path: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
try {
|
||||
var fileName = types.isString(path) ? path.trim() : "";
|
||||
|
||||
if (fileName.indexOf("~/") === 0) {
|
||||
fileName = fs.path.join(fs.knownFolders.currentApp().path, fileName.replace("~/", ""));
|
||||
}
|
||||
|
||||
(<any>UIImage).tns_decodeImageWidthContentsOfFileCompletion(fileName, image => {
|
||||
this.ios = image;
|
||||
resolve(true);
|
||||
});
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public loadFromData(data: any): boolean {
|
||||
this.ios = UIImage.imageWithData(data);
|
||||
return this.ios != null;
|
||||
}
|
||||
|
||||
public fromData(data: any): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
try {
|
||||
(<any>UIImage).tns_decodeImageWithDataCompletion(data, image => {
|
||||
this.ios = image;
|
||||
resolve(true);
|
||||
});
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public loadFromBase64(source: string): boolean {
|
||||
if (types.isString(source)) {
|
||||
var data = NSData.alloc().initWithBase64EncodedStringOptions(source, NSDataBase64DecodingOptions.NSDataBase64DecodingIgnoreUnknownCharacters);
|
||||
this.ios = UIImage.imageWithData(data);
|
||||
}
|
||||
|
||||
return this.ios != null;
|
||||
}
|
||||
|
||||
public fromBase64(source: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
try {
|
||||
var data = NSData.alloc().initWithBase64EncodedStringOptions(source, NSDataBase64DecodingOptions.NSDataBase64DecodingIgnoreUnknownCharacters);
|
||||
UIImage.imageWithData["async"](UIImage, [data]).then(image => {
|
||||
this.ios = image;
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public setNativeSource(source: any): boolean {
|
||||
this.ios = source;
|
||||
return source != null;
|
||||
@ -103,4 +171,4 @@ function getImageData(instance: UIImage, format: string, quality = 1.0): NSData
|
||||
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@
|
||||
},
|
||||
"typings": "tns-core-modules.d.ts",
|
||||
"dependencies": {
|
||||
"tns-core-modules-widgets": "2.0.0"
|
||||
"tns-core-modules-widgets": "next"
|
||||
},
|
||||
"nativescript": {
|
||||
"platforms": {
|
||||
|
@ -8,7 +8,8 @@
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"noImplicitUseStrict": true,
|
||||
"experimentalDecorators": true
|
||||
"experimentalDecorators": true,
|
||||
"diagnostics": false
|
||||
},
|
||||
"filesGlob": [
|
||||
"**/*.ts",
|
||||
@ -695,8 +696,8 @@
|
||||
"ui/transition/transition.android.ts",
|
||||
"ui/transition/transition.d.ts",
|
||||
"ui/transition/transition.ios.ts",
|
||||
"ui/transition/fade-transition.d.ts",
|
||||
"ui/transition/slide-transition.d.ts",
|
||||
"ui/transition/fade-transition.d.ts",
|
||||
"ui/transition/slide-transition.d.ts",
|
||||
"ui/utils.d.ts",
|
||||
"ui/utils.ios.ts",
|
||||
"ui/web-view/web-view-common.ts",
|
||||
|
@ -11,6 +11,10 @@ import * as types from "utils/types";
|
||||
|
||||
var SRC = "src";
|
||||
var IMAGE_SOURCE = "imageSource";
|
||||
var LOAD_MODE = "loadMode";
|
||||
|
||||
var SYNC = "sync";
|
||||
var ASYNC = "async";
|
||||
|
||||
var IMAGE = "Image";
|
||||
var ISLOADING = "isLoading";
|
||||
@ -21,41 +25,8 @@ var AffectsLayout = platform.device.os === platform.platformNames.android ? depe
|
||||
|
||||
function onSrcPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
var image = <Image>data.object;
|
||||
var value = data.newValue;
|
||||
|
||||
if (types.isString(value)) {
|
||||
value = value.trim();
|
||||
image.imageSource = null;
|
||||
image["_url"] = value;
|
||||
|
||||
image._setValue(Image.isLoadingProperty, true);
|
||||
|
||||
if (utils.isDataURI(value)) {
|
||||
var base64Data = value.split(",")[1];
|
||||
if (types.isDefined(base64Data)) {
|
||||
image.imageSource = imageSource.fromBase64(base64Data);
|
||||
image._setValue(Image.isLoadingProperty, false);
|
||||
}
|
||||
}
|
||||
else if (imageSource.isFileOrResourcePath(value)) {
|
||||
image.imageSource = imageSource.fromFileOrResource(value);
|
||||
image._setValue(Image.isLoadingProperty, false);
|
||||
} else {
|
||||
imageSource.fromUrl(value).then((r) => {
|
||||
if (image["_url"] === value) {
|
||||
image.imageSource = r;
|
||||
image._setValue(Image.isLoadingProperty, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (value instanceof imageSource.ImageSource) {
|
||||
// Support binding the imageSource trough the src property
|
||||
image.imageSource = value;
|
||||
}
|
||||
else {
|
||||
image.imageSource = imageSource.fromNativeSource(value);
|
||||
}
|
||||
// Check for delay...
|
||||
image._createImageSourceFromSrc();
|
||||
}
|
||||
|
||||
export class Image extends view.View implements definition.Image {
|
||||
@ -72,6 +43,9 @@ export class Image extends view.View implements definition.Image {
|
||||
|
||||
public static stretchProperty = new dependencyObservable.Property(STRETCH, IMAGE,
|
||||
new proxy.PropertyMetadata(enums.Stretch.aspectFit, AffectsLayout));
|
||||
|
||||
public static loadModeProperty = new dependencyObservable.Property(LOAD_MODE, IMAGE,
|
||||
new proxy.PropertyMetadata(SYNC, 0, null, (value) => value === SYNC || value === ASYNC, null));
|
||||
|
||||
get imageSource(): imageSource.ImageSource {
|
||||
return this._getValue(Image.imageSourceProperty);
|
||||
@ -98,7 +72,80 @@ export class Image extends view.View implements definition.Image {
|
||||
this._setValue(Image.stretchProperty, value);
|
||||
}
|
||||
|
||||
get loadMode(): "sync" | "async" {
|
||||
return this._getValue(Image.loadModeProperty);
|
||||
}
|
||||
set loadMode(value: "sync" | "async") {
|
||||
this._setValue(Image.loadModeProperty, value);
|
||||
}
|
||||
|
||||
public _setNativeImage(nativeImage: any) {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_createImageSourceFromSrc(): void {
|
||||
var value = this.src;
|
||||
if (types.isString(value)) {
|
||||
value = value.trim();
|
||||
this.imageSource = null;
|
||||
this["_url"] = value;
|
||||
|
||||
this._setValue(Image.isLoadingProperty, true);
|
||||
|
||||
var source = new imageSource.ImageSource();
|
||||
var imageLoaded = () => {
|
||||
this.imageSource = source;
|
||||
this._setValue(Image.isLoadingProperty, false);
|
||||
}
|
||||
if (utils.isDataURI(value)) {
|
||||
var base64Data = value.split(",")[1];
|
||||
if (types.isDefined(base64Data)) {
|
||||
if (this.loadMode === SYNC) {
|
||||
source.loadFromBase64(base64Data);
|
||||
imageLoaded();
|
||||
} else if (this.loadMode === ASYNC) {
|
||||
source.fromBase64(base64Data).then(imageLoaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (imageSource.isFileOrResourcePath(value)) {
|
||||
if (value.indexOf(utils.RESOURCE_PREFIX) === 0) {
|
||||
let resPath = value.substr(utils.RESOURCE_PREFIX.length);
|
||||
if (this.loadMode === SYNC) {
|
||||
source.loadFromResource(resPath);
|
||||
imageLoaded();
|
||||
} else if (this.loadMode === ASYNC) {
|
||||
this.imageSource = null;
|
||||
source.fromResource(resPath).then(imageLoaded);
|
||||
}
|
||||
} else {
|
||||
if (this.loadMode === SYNC) {
|
||||
source.loadFromFile(value);
|
||||
imageLoaded();
|
||||
} else if (this.loadMode === ASYNC) {
|
||||
this.imageSource = null;
|
||||
source.fromFile(value).then(imageLoaded);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.imageSource = null;
|
||||
imageSource.fromUrl(value).then((r) => {
|
||||
if (this["_url"] === value) {
|
||||
this.imageSource = r;
|
||||
this._setValue(Image.isLoadingProperty, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (value instanceof imageSource.ImageSource) {
|
||||
// Support binding the imageSource trough the src property
|
||||
this.imageSource = value;
|
||||
}
|
||||
else {
|
||||
this.imageSource = imageSource.fromNativeSource(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
ui/image/image.d.ts
vendored
7
ui/image/image.d.ts
vendored
@ -44,5 +44,12 @@ declare module "ui/image" {
|
||||
* Gets or sets the image stretch mode.
|
||||
*/
|
||||
stretch: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the loading strategy for images on the local file system:
|
||||
* - **sync** *(default)* - blocks the UI if necessary to display immediately, good for small icons.
|
||||
* - **async** - will try to load in the background, may appear with short delay, good for large images.
|
||||
*/
|
||||
loadMode: "sync" | "async";
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user