import {Component, OnInit, Input, ElementRef, OnDestroy, OnChanges} from '@angular/core';
import {CloudinaryImage} from '@cloudinary/url-gen/assets/CloudinaryImage';
import {
cancelCurrentlyRunningPlugins,
HtmlImageLayer,
Plugins
} from '@cloudinary/html';
import {SDKAnalyticsConstants} from '../internal/SDKAnalyticsConstants';
/**
* @mixin AngularSDK
* @description The Cloudinary Angular SDK contains components like \<advanced-image\> to easily render your media assets from
* Cloudinary. The SDK also comes with support for optional JS plugins that make the components smart, with features
* like lazy loading, placeholder, accessibility & responsiveness.
*
* @example
* <caption>
* Please note that the order of the plugins is important. See {@link https://cloudinary.com/documentation/sdks/js/frontend-frameworks/index.html#plugin-order|Plugin Order} for more details.
* </caption>
* // In your app.module.ts inject the library.
* import { CloudinaryModule} from '@cloudinary/angular';
*
* imports: [
* ...,
* CloudinaryModule,
* ],
*
* // In your component.ts use `@cloudinary/url-gen` to generate your transformations.
* // Import the plugins you wish to use
*
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/angular';
*
* ngOnInit() {
* const myCld = new Cloudinary({ cloudName: 'demo'});
* this.img = myCld().image('sample');
*
* this.plugins = [lazyload(), placeholder()]
* }
*
* // In your view add the component with your transformation.
* <advanced-image [cldImg]="this.img" [plugins]="this.plugins"></advanced-image>
*/
/**
* @memberOf AngularSDK
* @type {Component}
* @description The Cloudinary image component.
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
* @prop imageAttributes Optional attributes include alt, width, height, loading
*/
@Component({
selector: 'advanced-image',
template: `
<img />
`,
styleUrls: ['./cloudinary-image.component.css']
})
export class CloudinaryImageComponent implements OnInit, OnChanges, OnDestroy {
@Input('cldImg') cldImg: CloudinaryImage;
@Input('plugins') plugins: Plugins;
@Input('alt') alt: string;
@Input('width') width: string;
@Input('height') height: string;
@Input('loading') loading: string;
htmlLayerInstance: HtmlImageLayer;
constructor(private el: ElementRef) { }
/**
* On init creates a new HTMLLayer instance and initializes with ref to img element,
* user generated cloudinaryImage and the plugins to be used.
*/
ngOnInit() {
this.htmlLayerInstance = new HtmlImageLayer(this.el.nativeElement.children[0], this.cldImg, this.plugins, SDKAnalyticsConstants);
this.addAttributes();
}
/**
* On update, we cancel running plugins and update the image instance with the state of user
* cloudinaryImage and the state of plugins.
*/
ngOnChanges() {
if (this.htmlLayerInstance) {
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
this.htmlLayerInstance.update(this.cldImg, this.plugins, SDKAnalyticsConstants);
}
}
/**
* On destroy, we cancel the currently running plugins.
*/
ngOnDestroy() {
// safely cancel running events on destroy
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
}
/**
* Add attributes to img element.
*/
addAttributes() {
['alt', 'width', 'height', 'loading'].forEach(attr => {
if (this[attr]) {
this.el.nativeElement.children[0].setAttribute(attr, this[attr]);
this.el.nativeElement.removeAttribute(attr);
}
});
}
}