Надо написать контейнер для Img, такой чтобы реагировал на изменения размера экрана. К примеру, если где-то изображение меньше своего основного размера, там внутри изображение в правом нижнем углу появлялась лупа, если больше исчезала. Причем все, это должно быть кроссбраузерно и чтобы это на мобильных устройствах. Вот мои попытки.
файл компонента
import {Component, ElementRef, EventEmitter, HostListener, Input,
OnDestroy, OnInit, Output} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subscription} from 'rxjs/Subscription';
import {Observer} from 'rxjs/Observer';
@Component({
selector: 'img-container',
templateUrl: './image-container.html'
})
export class ImageContainerComponent implements OnInit, OnDestroy {
isVisible = 'hidden';
@Output() change = new EventEmitter<{ type: string, data: any }>();
private originWidth: number;
private originHeight: number;
private currentHeight: number;
private currentWidth: number;
private img: HTMLImageElement;
private element: HTMLElement;
private imageStatus: Subscription;
private resizing: Subscription;
private imageLoaded: boolean;
@Input() src: string;
@Input() buttonStyle: string;
@Input() buttonClasses: string;
constructor(elem: ElementRef) {
this.element = elem.nativeElement;
}
ngOnInit() {
this.imageLoaded = false;
const imgStatus = Observable.create((observer: Observer<any>) => {
this.img.onloadeddata = observer.next.bind(observer);
this.img.onload = observer.next.bind(observer);
this.img.onerror = observer.error.bind(observer);
});
if (this.imageStatus && !this.imageStatus.closed) {
this.imageStatus.unsubscribe();
}
this.img = this.element.getElementsByTagName('img')[0];
this.imageStatus = imgStatus.subscribe(
() => {
this.imageLoaded = true;
this.onChangeSize();
},
(err) => {
this.imageLoaded = false;
console.log(err);
});
}
ngOnDestroy() {
if (this.imageStatus && !this.imageStatus.closed) {
this.imageStatus.unsubscribe();
}
if (this.resizing && !this.resizing.closed) {
this.resizing.unsubscribe();
}
this.resizing = null;
this.imageStatus = null;
this.element = null;
}
@HostListener('window:resize', [])
onChangeSize() {
let buttonZoom: HTMLButtonElement;
if (this.resizing && !this.resizing.closed) {
this.resizing.unsubscribe();
}
this.resizing = Observable.of(this.imageLoaded)
.mergeMap((loaded: boolean) => {
if (loaded) {
buttonZoom = this.element.getElementsByTagName('button')[0];
buttonZoom.setAttribute('style', this.buttonStyle);
buttonZoom.setAttribute('class', this.buttonClasses);
buttonZoom.style.visibility = this.isVisible;
this.originWidth = this.img.naturalWidth;
this.originHeight = this.img.naturalHeight;
this.currentWidth = this.img.clientWidth;
this.currentHeight = this.img.clientHeight;
if (this.originWidth <= this.currentWidth || this.originHeight <= this.currentHeight) {
this.isVisible = 'hidden';
} else {
this.isVisible = 'visible';
return Observable.merge(
Observable.fromEvent(this.img, 'click'),
Observable.fromEvent(buttonZoom, 'click')
).mergeMap(() => {
this.openImagePopup(this.img.src, this.img.naturalWidth,
this.img.naturalHeight, this.img.alt);
return Observable.of(null);
});
}
return Observable.of(null);
} else {
return Observable.throw('image not loaded');
}
})
.subscribe(() => console.log('resizing'),
(err) => console.log(err));
}
private openImagePopup(imgUrl: string, width: number,
height: number, altText: string): void {
this.change.emit({
type: 'image',
data: {url: imgUrl, width: width, height: height, altText: altText}
});
}
}
Файл image-container.hmtl
<img [src]="src">
<button [style.visibility]="isVisible"></button>
Src и стили button задаются извне.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей