/** * AoflImg class implementation. * * @summary aofl-img * @version 3.0.0 * @since 3.0.0 * @author Arian Khosravi <arian.khosravi@aofl.com> */ import {AoflElement} from '@aofl/element'; import styles from './image.css'; import {findParent, isInViewportMixin} from '@aofl/component-utils'; /** * @memberof module:@aofl/picture * @private * @type {String} */ const BLANK_PIXEL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; /** * aofl-img componont lazy loads images by default as they enter the viewport. * * @memberof module:@aofl/picture * @extends {AoflElement} */ class AoflImg extends isInViewportMixin(AoflElement) { /** * Creates an instance of AoflImg */ constructor() { super(); this.imgSrc = BLANK_PIXEL; this.src = BLANK_PIXEL; this.widthThreshold = 1; this.heightThreshold = 1; } /** * * @readonly * @static * @type {String} */ static get is() { return 'aofl-img'; } /** * * @readonly * @static * @type {Object} */ static get properties() { return { src: {type: String}, imgSrc: {type: String, attribute: false}, width: {type: String}, height: {type: String}, alt: {type: String} }; } /** * @param {*} args */ connectedCallback(...args) { super.connectedCallback(...args); setTimeout(() => { this.checkInViewport(); }); this.loadImage(this.src); try { const parent = findParent(this, 'setImg'); /* istanbul ignore next */ parent.setImg(this); } catch (e) { this.loadImage(this.src); } } /** * Stop checking isInViewStatus and load the image */ firstWithinViewport() { this.stopIsInViewportCheck(); this.loadImage(this.src); } /** * * @return {Object} */ render() { return super.render((ctx, html) => html` <canvas width="${this.width}" height="${this.height}"></canvas> <img alt="${this.alt}" height="${this.height}" width="${this.width}" src="${this.imgSrc}" @load="${this.imageLoaded}"> `, [styles]); } /** * * @param {String} changedProperties * @return {Boolean} */ shouldUpdate(changedProperties) { if (changedProperties.has('src') && typeof this.src === 'string') { this.loadImage(this.src); } return true; } /** * * @param {String} src */ loadImage(src) { if (this.onceWithinViewport !== true) { return; } this.imgSrc = src; this.requestUpdate(); } /** * * @param {Event} e * @fires AoflImg#load */ imageLoaded(e) { if (typeof this.width === 'undefined') { this.width = e.target.width; } if (typeof this.height === 'undefined') { this.height = e.target.height; } this.dispatchEvent(new CustomEvent('load')); } } if (window.customElements.get(AoflImg.is) === void 0) { window.customElements.define(AoflImg.is, AoflImg); } export default AoflImg;