forked from JeremyHeleine/Photo-Sphere-Viewer
-
-
Notifications
You must be signed in to change notification settings - Fork 633
/
Loader.ts
110 lines (93 loc) · 3.83 KB
/
Loader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { ConfigChangedEvent, LoadProgressEvent } from '../events';
import { getStyleProperty } from '../utils';
import type { Viewer } from '../Viewer';
import { AbstractComponent } from './AbstractComponent';
/**
* Loader component
*/
export class Loader extends AbstractComponent {
private readonly loader: HTMLElement;
private readonly canvas: SVGElement;
private readonly size: number;
private readonly border: number;
private readonly thickness: number;
private readonly color: string;
private readonly textColor: string;
/**
* @internal
*/
constructor(viewer: Viewer) {
super(viewer, { className: 'psv-loader-container' });
this.loader = document.createElement('div');
this.loader.className = 'psv-loader';
this.container.appendChild(this.loader);
this.size = this.loader.offsetWidth;
this.canvas = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this.canvas.setAttribute('class', 'psv-loader-canvas');
this.canvas.setAttribute('viewBox', `0 0 ${this.size} ${this.size}`);
this.loader.appendChild(this.canvas);
this.textColor = getStyleProperty(this.loader, 'color');
this.color = getStyleProperty(this.canvas, 'color');
this.border = parseInt(getStyleProperty(this.loader, '--psv-loader-border'), 10);
this.thickness = parseInt(getStyleProperty(this.loader, '--psv-loader-tickness'), 10);
this.viewer.addEventListener(ConfigChangedEvent.type, this);
this.__updateContent();
this.hide();
}
/**
* @internal
*/
override destroy(): void {
this.viewer.removeEventListener(ConfigChangedEvent.type, this);
super.destroy();
}
/**
* @internal
*/
handleEvent(e: Event) {
if (e instanceof ConfigChangedEvent) {
e.containsOptions('loadingImg', 'loadingTxt') && this.__updateContent();
}
}
/**
* Sets the loader progression
*/
setProgress(value: number) {
const angle = (Math.min(value, 99.999) / 100) * Math.PI * 2;
const halfSize = this.size / 2;
const startX = halfSize;
const startY = this.thickness / 2 + this.border;
const radius = (this.size - this.thickness) / 2 - this.border;
const endX = Math.sin(angle) * radius + halfSize;
const endY = -Math.cos(angle) * radius + halfSize;
const largeArc = value > 50 ? '1' : '0';
this.canvas.innerHTML = `
<circle cx="${halfSize}" cy="${halfSize}" r="${halfSize}" fill="${this.color}"/>
<path d="M ${startX} ${startY} A ${radius} ${radius} 0 ${largeArc} 1 ${endX} ${endY}"
fill="none" stroke="${this.textColor}" stroke-width="${this.thickness}" stroke-linecap="round"/>
`;
this.viewer.dispatchEvent(new LoadProgressEvent(Math.round(value)));
}
private __updateContent() {
const current = this.loader.querySelector('.psv-loader-image, .psv-loader-text');
if (current) {
this.loader.removeChild(current);
}
let inner;
if (this.viewer.config.loadingImg) {
inner = document.createElement('img');
inner.className = 'psv-loader-image';
inner.src = this.viewer.config.loadingImg;
} else if (this.viewer.config.loadingTxt !== null) {
inner = document.createElement('div');
inner.className = 'psv-loader-text';
inner.innerHTML = this.viewer.config.loadingTxt || this.viewer.config.lang.loading;
}
if (inner) {
const size = Math.round(Math.sqrt(2 * Math.pow(this.size / 2 - this.thickness / 2 - this.border, 2)));
inner.style.maxWidth = size + 'px';
inner.style.maxHeight = size + 'px';
this.loader.appendChild(inner);
}
}
}