PageSourceSearch

https://www.boatindustry.fr/src/javascript/spinner/spinner.js

js boatindustry.fr collected 2026-09-26 03:51:08 UTC 10,763 bytes, 322 lines download raw bytes

1"use strict";
2/**
3 *
4 * @param {string|HTMLElement} mountElement conteneur
5 * @param {int} spinnerSize taille du spinner en pixels
6 * @param {int} maxValue valeur maximale
7 * @param {string} [unit] unité bytes|numeric
8 * @constructor
9 */
10function Spinner(mountElement,spinnerSize,maxValue,unit)
11{
12	this.initialize=function()
13	{
14		this.setUnit(unit||"numeric");
15		this.spinnerSize=spinnerSize;
16		this.maxValue=maxValue;
17		this.mountElement= mountElement;
18		if(typeof this.mountElement==="string") this.mountElement = document.querySelector(this.mountElement);
19
20		// Geometry
21		this.spinnerDashWidth=Math.ceil(this.spinnerSize/15);
22		this.spinnerRadius=(this.spinnerSize-this.spinnerDashWidth)/2;
23		this.spinnerOffset=this.spinnerRadius+this.spinnerDashWidth/2;
24		this.spinnerLabelFontSize=Math.round(this.spinnerRadius/2);
25		this.timeStarted=new Date().getTime();
26		// DOM Elements
27		this.spinnerContainer=null;
28		this.spinner = null;
29		this.circle = null;
30		this.spinnerBackground = null;
31		this.spinnerForeground = null;
32		this.spinnerLabel = null;
33		this.spinnerTitle=null;
34		this.spinnerStatus = null;
35		this.spinnerTimeLeft = null;
36		// Stats
37		this.seconds_elapsed=0;
38		this.progress_per_second=0;
39		this.remaining_progress=0;
40		this.seconds_remaining=0;
41		this.currentValue=0;
42
43		this.stopAnimationTimeout=null;
44		this.hideTimeout=null;
45
46		this.initDisplay();
47	};
48	this.mount=function()
49	{
50		if(this.mountElement)
51		{
52			this.mountElement.appendChild(this.spinnerContainer);
53		}
54	};
55	this.buildDomElements = function()
56	{
57		this.spinnerContainer = document.createElement("div");
58		this.spinnerContainer.setAttribute("class","spinner-container");
59
60		this.spinner = document.createElement("div");
61		this.spinner.setAttribute("class","spinner");
62
63		this.circle = document.createElementNS('http://www.w3.org/2000/svg',"svg");
64		this.circle.setAttribute("class","x-circle");
65
66		this.spinnerBackground = document.createElementNS('http://www.w3.org/2000/svg',"circle");
67		this.spinnerBackground.setAttribute("class","x-background");
68		this.spinnerBackground.setAttribute("fill","transparent");
69
70		this.spinnerForeground = document.createElementNS('http://www.w3.org/2000/svg',"circle");
71		this.spinnerForeground.setAttribute("class","x-foreground");
72		this.spinnerForeground.setAttribute("fill","transparent");
73
74		this.spinnerLabel = document.createElementNS('http://www.w3.org/2000/svg',"text");
75		this.spinnerLabel.setAttribute("class","x-label");
76		this.spinnerLabel.setAttribute("x","50%");
77		this.spinnerLabel.setAttribute("y","50%");
78		this.spinnerLabel.setAttribute("fill","black");
79		this.spinnerLabel.setAttribute("text-anchor","middle");
80
81		this.spinnerError = document.createElementNS('http://www.w3.org/2000/svg',"image");
82		this.spinnerError.setAttribute("class","x-error-icon");
83		this.spinnerError.setAttribute("x","50%");
84		this.spinnerError.setAttribute("y","50%");
85		this.spinnerError.setAttribute("width","32");
86		this.spinnerError.setAttribute("height","32");
87		this.spinnerError.setAttribute("transform","translate(-16,-16)");
88		this.spinnerError.setAttribute("href","/src/images/icons/svg/close.svg");
89		this.spinnerError.textContent="!";
90
91
92		this.spinnerTitle = document.createElement("div");
93		this.spinnerTitle.setAttribute("class","x-title");
94
95		this.spinnerStatus = document.createElement("div");
96		this.spinnerStatus.setAttribute("class","x-status");
97
98		this.spinnerTimeLeft = document.createElement("div");
99		this.spinnerTimeLeft.setAttribute("class","x-timeleft");
100
101		this.circle.appendChild(this.spinnerBackground);
102		this.circle.appendChild(this.spinnerForeground);
103		this.circle.appendChild(this.spinnerLabel);
104		this.circle.appendChild(this.spinnerError);
105		this.spinner.appendChild(this.circle);
106		this.spinnerContainer.appendChild(this.spinner);
107		this.spinnerContainer.appendChild(this.spinnerTitle);
108		this.spinnerContainer.appendChild(this.spinnerStatus);
109		this.spinnerContainer.appendChild(this.spinnerTimeLeft);
110	};
111	this.initDisplay=function()
112	{
113		this.buildDomElements();
114		this.circle.setAttribute("height",this.spinnerSize.toString());
115		this.circle.setAttribute("width",this.spinnerSize.toString());
116		this.circle.setAttribute("viewBox","0 0 "+this.spinnerSize.toString()+" "+this.spinnerSize.toString());
117
118		this.spinnerBackground.setAttribute("r",this.spinnerRadius);
119		this.spinnerBackground.setAttribute("cx",this.spinnerOffset);
120		this.spinnerBackground.setAttribute("cy",this.spinnerOffset);
121		this.spinnerBackground.style.strokeDashoffset=this.getCirconf();
122		this.spinnerBackground.style.strokeDasharray=0;
123		this.spinnerBackground.style.strokeWidth=this.spinnerDashWidth;
124
125		this.spinnerForeground.setAttribute("r",this.spinnerRadius);
126		this.spinnerForeground.setAttribute("cx",this.spinnerOffset);
127		this.spinnerForeground.setAttribute("cy",this.spinnerOffset);
128		this.spinnerForeground.style.strokeDashoffset=this.getCirconf();
129		this.spinnerForeground.style.strokeDasharray=this.getCirconf();
130		this.spinnerForeground.style.strokeWidth=this.spinnerDashWidth;
131
132		this.spinnerLabel.style.fontSize=this.spinnerLabelFontSize+"px";
133		this.spinnerLabel.setAttribute("y",Math.round((this.spinnerSize+this.spinnerLabelFontSize-this.spinnerDashWidth)/2).toString());
134		this.mount();
135	};
136	/**
137	 *
138	 * @param {int|undefined} currentValue
139	 * @param {int|undefined} [maxValue]
140	 * @param [title]
141	 * @param [unit]
142	 */
143	this.updateSpinner = function(currentValue,maxValue,title,unit)
144	{
145		if(typeof title==="undefined") title="";
146		this.startAnimation();
147		if(typeof maxValue!=="undefined") this.maxValue=maxValue;
148		this.currentValue=currentValue;
149		this.spinnerForeground.style.strokeDashoffset=this.pctToDashOffset(this.getProgressAsPct());
150		this.computeProgressStats();
151		this.updateLabel(this.getProgressAsPct());
152		if(title!==null) this.setTitle(title);
153		if(unit!==undefined) this.setUnit(unit);
154		this.updateStatus();
155		this.updateTimeLeft();
156		if(this.maxValue===this.currentValue)
157		{
158			this.stopAnimationTimeout = setTimeout(function(){this.stopAnimation();}.bind(this),3000);
159		}
160	};
161	this.computeProgressStats=function()
162	{
163		this.seconds_elapsed = (new Date().getTime() - this.timeStarted)/1000;
164		this.progress_per_second =  this.seconds_elapsed ? this.currentValue / this.seconds_elapsed : 0 ;
165		this.remaining_progress =   this.maxValue - this.currentValue;
166		this.seconds_remaining = this.seconds_elapsed ? this.remaining_progress / this.progress_per_second : Infinity;
167	};
168	this.setUnit=function(unit)
169	{
170		this.unit=unit;
171	};
172	this.setLabel=function(string)
173	{
174		this.spinnerLabel.textContent=string;
175	};
176	this.setTitle=function(string)
177	{
178		this.spinnerTitle.innerHTML=string;
179	};
180	this.setStatus=function(string)
181	{
182		this.spinnerStatus.innerHTML=string;
183		this.setHasError(false);
184	};
185	this.setTimeLeft=function(string)
186	{
187		if(string==="" || string ===null) string=" ";
188		this.spinnerTimeLeft.innerHTML=string;
189	};
190	this.updateLabel=function(pctTransfered)
191	{
192		this.setLabel(Math.round(pctTransfered)+"%");
193	};
194	this.updateStatus=function()
195	{
196		this.setStatus(this.formatValue(this.currentValue)+" / "+this.formatValue(this.maxValue));
197	};
198	this.formatValue=function(value)
199	{
200		if(this.unit==="bytes") return this.formatBytes(value);
201		else if(this.unit==="numeric") return Math.round(value);
202		else return Math.round(value);
203	};
204	this.formatBytes=function(bytes)
205	{
206		if(bytes === 0) return '0 B';
207		var k = 1024,dm = 0,sizes = ['B', 'Ko', 'Mo', 'Go', 'To', 'Po', 'Eo', 'Zo', 'Yo'],i = Math.floor(Math.log(bytes) / Math.log(k));
208		return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
209	};
210	this.setError=function(errorMessage)
211	{
212		this.setLabel("");
213		this.stopAnimation();
214		this.setStatus(errorMessage);
215		this.setHasError(true);
216	};
217	this.setHasError=function(bool)
218	{
219		if(bool) 	this.spinnerContainer.classList.add("x-error");
220		else			this.spinnerContainer.classList.remove("x-error");
221	};
222	this.updateTimeLeft=function()
223	{
224		this.setTimeLeft(this.secondsFormat(this.seconds_remaining));
225	};
226	this.getCirconf=function()
227	{
228		return 2*Math.PI*this.spinnerRadius;
229	};
230	this.pctToDashOffset=function(pct)
231	{
232		var circonf=this.getCirconf();
233		var offset = circonf-(circonf*pct/100);
234		// pour que le cercle bleu soit toujours visible on assure une petite marge.
235		if(circonf-offset<1) offset=circonf-1;
236		return Math.round(offset);
237	};
238	this.secondsFormat=function(time)
239	{
240		if(!isFinite(time)) return "";
241		if(time>0)
242		{
243			var hrs = Math.floor(time / 3600);
244			var mins = Math.floor((time % 3600) / 60);
245			var secs = Math.floor(time % 60);
246			var ret = "&#x023F1; ";
247			if(hrs > 0 && isFinite(hrs))	ret += "" + hrs + " h " + (mins < 10 ? "0" : "");
248			if(hrs>0 || (mins>0 && isFinite(mins)))	ret += "" + mins + " m " + (secs < 10 ? "0" : "");
249			ret += "" + secs + " s";
250			return ret;
251		}
252		else return "";
253	};
254	this.getProgressAsPct=function()
255	{
256		if(this.maxValue>0) return this.currentValue/this.maxValue*100;
257		else return 0;
258	};
259	this.startAnimation=function()
260	{
261		if(this.spinner.classList)
262		{
263			this.spinner.classList.add("x-animated");
264		}
265	};
266	this.stopAnimation=function()
267	{
268		if(this.spinner.classList)
269		{
270			this.spinner.classList.remove("x-animated");
271		}
272	};
273	this.hide=function()
274	{
275		this.spinnerContainer.style.opacity=0;
276		this.hideTimeout = setTimeout(function(){this.spinnerContainer.style.display="none";}.bind(this),1000);
277	};
278	this.show=function()
279	{
280		this.spinnerContainer.style.opacity=0;
281		this.spinnerContainer.style.display="";
282		this.spinnerContainer.style.opacity=1;
283	};
284	this.destroy=function()
285	{
286		if(this.spinnerContainer && this.spinnerContainer.parentNode) this.spinnerContainer.parentNode.removeChild(this.spinnerContainer);
287		if(this.stopAnimationTimeout) clearTimeout(this.stopAnimationTimeout);
288		if(this.hideTimeout) clearTimeout(this.hideTimeout);
289		this.spinner=null;
290	};
291	this.initialize();
292}
293
294function SpinnerSimulator(fileSize,minIncr,maxIncr,spinner,interval)
295{
296	this.fileSize=fileSize;
297	this.transferedSize=0;
298	this.minIncr=minIncr;
299	this.maxIncr=maxIncr;
300	this.interval=interval;
301	this.spinner=spinner;
302	this.getRandomArbitrary=function(min, max)
303	{
304		return Math.round(Math.random() * (max - min) + min);
305	};
306	this.simulateUpload=function()
307	{
308		this.spinner.updateSpinner(this.transferedSize,this.fileSize,"Téléchargement en cours...");
309		var interval = setInterval(function()
310		{
311			if(this.transferedSize<this.fileSize) this.transferedSize+=this.getRandomArbitrary(this.minIncr,this.maxIncr);
312			else this.transferedSize=this.fileSize;
313			if(this.transferedSize>=this.fileSize)
314			{
315				this.transferedSize=this.fileSize;
316				clearInterval(interval);
317			}
318			this.spinner.updateSpinner(this.transferedSize,this.fileSize,"Téléchargement en cours...");
319
320		}.bind(this),this.interval);
321	};
322}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.