mapillary-js
Version:
WebGL JavaScript library for displaying street level imagery from mapillary.com
149 lines (125 loc) • 5.62 kB
text/typescript
import {of as observableOf, combineLatest as observableCombineLatest, Observable, Subscription} from "rxjs";
import {map, distinctUntilChanged, switchMap, first, filter} from "rxjs/operators";
import * as vd from "virtual-dom";
import {
CoverState,
ICoverConfiguration,
ComponentService,
Component,
} from "../Component";
import {Node} from "../Graph";
import {
IVNodeHash,
ISize,
} from "../Render";
import {Urls} from "../Utils";
import {
Container,
ImageSize,
Navigator,
} from "../Viewer";
export class CoverComponent extends Component<ICoverConfiguration> {
public static componentName: string = "cover";
private _renderSubscription: Subscription;
private _keySubscription: Subscription;
constructor(name: string, container: Container, navigator: Navigator) {
super(name, container, navigator);
}
public _activate(): void {
this._configuration$.pipe(
distinctUntilChanged(
undefined,
(configuration: ICoverConfiguration): CoverState => {
return configuration.state;
}),
switchMap(
(configuration: ICoverConfiguration): Observable<[CoverState, Node]> => {
return observableCombineLatest(
observableOf(configuration.state),
this._navigator.stateService.currentNode$);
}),
switchMap(
([state, node]: [CoverState, Node]): Observable<[string, string]> => {
const keySrc$: Observable<[string, string]> = observableCombineLatest(
observableOf(node.key),
node.image$.pipe(
filter(
(image: HTMLImageElement): boolean => {
return !!image;
}),
map(
(image: HTMLImageElement): string => {
return image.src;
})));
return state === CoverState.Visible ? keySrc$.pipe(first()) : keySrc$;
}),
distinctUntilChanged(
([k1, s1]: [string, string], [k2, s2]: [string, string]): boolean => {
return k1 === k2 && s1 === s2;
}),
map(
([key, src]: [string, string]): ICoverConfiguration => {
return { key: key, src: src };
}))
.subscribe(this._configurationSubject$);
this._renderSubscription = observableCombineLatest(
this._configuration$,
this._container.renderService.size$).pipe(
map(
([configuration, size]: [ICoverConfiguration, ISize]): IVNodeHash => {
if (!configuration.key) {
return { name: this._name, vnode: vd.h("div", []) };
}
const compactClass: string = size.width <= 640 || size.height <= 480 ? ".CoverCompact" : "";
if (configuration.state === CoverState.Hidden) {
const doneContainer: vd.VNode = vd.h(
"div.CoverContainer.CoverDone" + compactClass,
[this._getCoverBackgroundVNode(configuration)]);
return { name: this._name, vnode: doneContainer };
}
const container: vd.VNode = vd.h(
"div.CoverContainer" + compactClass,
[this._getCoverButtonVNode(configuration)]);
return { name: this._name, vnode: container };
}))
.subscribe(this._container.domRenderer.render$);
}
public _deactivate(): void {
this._renderSubscription.unsubscribe();
this._keySubscription.unsubscribe();
}
protected _getDefaultConfiguration(): ICoverConfiguration {
return { state: CoverState.Visible };
}
private _getCoverButtonVNode(configuration: ICoverConfiguration): vd.VNode {
const cover: string = configuration.state === CoverState.Loading ? "div.Cover.CoverLoading" : "div.Cover";
const coverButton: vd.VNode = vd.h(
"div.CoverButton",
[vd.h("div.CoverButtonIcon", [])]);
const coverLogo: vd.VNode = vd.h("a.CoverLogo", {href: Urls.explore, target: "_blank"}, []);
const coverIndicator: vd.VNode = vd.h(
"div.CoverIndicator",
{ onclick: (): void => { this.configure({ state: CoverState.Loading }); } },
[]);
return vd.h(
cover,
[
this._getCoverBackgroundVNode(configuration),
coverIndicator,
coverButton,
coverLogo,
]);
}
private _getCoverBackgroundVNode(conf: ICoverConfiguration): vd.VNode {
let url: string = conf.src != null ?
conf.src : Urls.thumbnail(conf.key, ImageSize.Size640);
let properties: vd.createProperties = { style: { backgroundImage: `url(${url})` } };
let children: vd.VNode[] = [];
if (conf.state === CoverState.Loading) {
children.push(vd.h("div.Spinner", {}, []));
}
return vd.h("div.CoverBackground", properties, children);
}
}
ComponentService.registerCover(CoverComponent);
export default CoverComponent;