1 | import { ElementRef, OnDestroy, Renderer } from '@angular/core';
|
2 | import { Img as IImg } from './img-interface';
|
3 | import { Content } from '../content/content';
|
4 | import { DomController } from '../../platform/dom-controller';
|
5 | import { Platform } from '../../platform/platform';
|
6 | /**
|
7 | * @name Img
|
8 | * @description
|
9 | * Two of the biggest cuprits of scroll jank is starting up a new HTTP
|
10 | * request, and rendering images. These two reasons is largely why
|
11 | * `ion-img` was created. The standard HTML `img` element is often a large
|
12 | * source of these problems, and what makes matters worse is that the app
|
13 | * does not have fine-grained control of requests and rendering for each
|
14 | * `img` element.
|
15 | *
|
16 | * The `ion-img` component is similar to the standard `img` element,
|
17 | * but it also adds features in order to provide improved performance.
|
18 | * Features include only loading images which are visible, using web workers
|
19 | * for HTTP requests, preventing jank while scrolling and in-memory caching.
|
20 | *
|
21 | * Note that `ion-img` also comes with a few more restrictions in comparison
|
22 | * to the standard `img` element. A good rule is, if there are only a few
|
23 | * images to be rendered on a page, then the standard `img` is probably
|
24 | * best. However, if a page has the potential for hundreds or even thousands
|
25 | * of images within a scrollable area, then `ion-img` would be better suited
|
26 | * for the job.
|
27 | *
|
28 | * > Note: `ion-img` is only meant to be used inside of [virtual-scroll](/docs/api/components/virtual-scroll/VirtualScroll/)
|
29 | *
|
30 | *
|
31 | * ### Lazy Loading
|
32 | *
|
33 | * Lazy loading images refers to only loading images which are actually
|
34 | * visible within the user's viewport. This also means that images which are
|
35 | * not viewable on the initial load would not be downloaded or rendered. Next,
|
36 | * as the user scrolls, each image which becomes visible is then requested
|
37 | * then rendered on-demand.
|
38 | *
|
39 | * The benefits of this approach is that unnecessary and resource intensive
|
40 | * HTTP requests are not started, valuable bandwidth isn't wasted, and this
|
41 | * allows the browser to free up resources which would be wasted on images
|
42 | * which are not even viewable. For example, animated GIFs are enourmous
|
43 | * performance drains, however, with `ion-img` the app is able to dedicate
|
44 | * resources to just the viewable images. But again, if the problems listed
|
45 | * above are not problems within your app, then the standard `img` element
|
46 | * may be best.
|
47 | *
|
48 | *
|
49 | * ### Image Dimensions
|
50 | *
|
51 | * By providing image dimensions up front, Ionic is able to accurately size
|
52 | * up the image's location within the viewport, which helps lazy load only
|
53 | * images which are viewable. Image dimensions can either by set as
|
54 | * properties, inline styles, or external stylesheets. It doesn't matter
|
55 | * which method of setting dimensions is used, but it's important that somehow
|
56 | * each `ion-img` has been given an exact size.
|
57 | *
|
58 | * For example, by default `<ion-avatar>` and `<ion-thumbnail>` already come
|
59 | * with exact sizes when placed within an `<ion-item>`. By giving each image
|
60 | * an exact size, this then further locks in the size of each `ion-item`,
|
61 | * which again helps improve scroll performance.
|
62 | *
|
63 | * ```html
|
64 | * <!-- dimensions set using attributes -->
|
65 | * <ion-img width="80" height="80" src="..."></ion-img>
|
66 | *
|
67 | * <!-- dimensions set using input properties -->
|
68 | * <ion-img [width]="imgWidth" [height]="imgHeight" src="..."></ion-img>
|
69 | *
|
70 | * <!-- dimensions set using inline styles -->
|
71 | * <ion-img style="width: 80px; height: 80px;" src="..."></ion-img>
|
72 | * ```
|
73 | *
|
74 | * Additionally, each `ion-img` uses the `object-fit: cover` CSS property.
|
75 | * What this means is that the actual rendered image will center itself within
|
76 | * it's container. Or to really get detailed: The image is sized to maintain
|
77 | * its aspect ratio while filling the containing element’s entire content box.
|
78 | * Its concrete object size is resolved as a cover constraint against the
|
79 | * element’s used width and height.
|
80 | *
|
81 | * ### Future Optimizations
|
82 | *
|
83 | * Future goals are to place image requests within web workers, and cache
|
84 | * images in-memory as datauris. This method has proven to be effective,
|
85 | * however there are some current limitations with Cordova which we are
|
86 | * currently working on.
|
87 | *
|
88 | */
|
89 | export declare class Img implements OnDestroy, IImg {
|
90 | private _elementRef;
|
91 | private _renderer;
|
92 | private _plt;
|
93 | private _content;
|
94 | private _dom;
|
95 | /** @internal */
|
96 | _src: string;
|
97 | /** @internal */
|
98 | _requestingSrc: string;
|
99 | /** @internal */
|
100 | _renderedSrc: string;
|
101 | /** @internal */
|
102 | _hasLoaded: boolean;
|
103 | /** @internal */
|
104 | _cache: boolean;
|
105 | /** @internal */
|
106 | _bounds: any;
|
107 | /** @internal */
|
108 | _rect: any;
|
109 | /** @internal */
|
110 | _w: string;
|
111 | /** @internal */
|
112 | _h: string;
|
113 | /** @internal */
|
114 | _wQ: string;
|
115 | /** @internal */
|
116 | _hQ: string;
|
117 | /** @internal */
|
118 | _img: HTMLImageElement;
|
119 | /** @internal */
|
120 | _unreg: Function;
|
121 | /** @hidden */
|
122 | canRequest: boolean;
|
123 | /** @hidden */
|
124 | canRender: boolean;
|
125 | constructor(_elementRef: ElementRef, _renderer: Renderer, _plt: Platform, _content: Content, _dom: DomController);
|
126 | /**
|
127 | * @input {string} The source of the image.
|
128 | */
|
129 | src: string;
|
130 | /**
|
131 | * @hidden
|
132 | */
|
133 | reset(): void;
|
134 | /**
|
135 | * @hidden
|
136 | */
|
137 | update(): void;
|
138 | /**
|
139 | * @internal
|
140 | */
|
141 | _isLoaded(isLoaded: boolean): void;
|
142 | /**
|
143 | * @internal
|
144 | */
|
145 | _srcAttr(srcAttr: string): void;
|
146 | /**
|
147 | * @hidden
|
148 | */
|
149 | readonly top: number;
|
150 | /**
|
151 | * @hidden
|
152 | */
|
153 | readonly bottom: number;
|
154 | private _getBounds();
|
155 | /**
|
156 | * @input {any} Sets the bounding rectangle of the element relative to the viewport.
|
157 | * When using `VirtualScroll`, each virtual item should pass its bounds to each
|
158 | * `ion-img`. The passed in data object should include `top` and `bottom` properties.
|
159 | */
|
160 | bounds: any;
|
161 | /**
|
162 | * @input {boolean} After an image has been successfully downloaded, it can be cached
|
163 | * in-memory. This is useful for `VirtualScroll` by allowing image responses to be
|
164 | * cached, and not rendered, until after scrolling has completed, which allows for
|
165 | * smoother scrolling.
|
166 | */
|
167 | cache: boolean;
|
168 | /**
|
169 | * @input {string} Image width. If this property is not set it's important that
|
170 | * the dimensions are still set using CSS. If the dimension is just a number it
|
171 | * will assume the `px` unit.
|
172 | */
|
173 | width: string | number;
|
174 | /**
|
175 | * @input {string} Image height. If this property is not set it's important that
|
176 | * the dimensions are still set using CSS. If the dimension is just a number it
|
177 | * will assume the `px` unit.
|
178 | */
|
179 | height: string | number;
|
180 | private _setDims();
|
181 | /**
|
182 | * @input {string} Set the `alt` attribute which gets assigned to
|
183 | * the inner `img` element.
|
184 | */
|
185 | alt: string;
|
186 | /**
|
187 | * @hidden
|
188 | */
|
189 | ngAfterContentInit(): void;
|
190 | /**
|
191 | * @hidden
|
192 | */
|
193 | ngOnDestroy(): void;
|
194 | }
|