PageSourceSearch

https://heuresolaire.com/ressources/compass.js

js heuresolaire.com collected 2026-09-30 10:48:29 UTC 6,149 bytes, 243 lines download raw bytes

1// needs ./time.js
2
3var canvas = document.getElementById('canvas');
4var size = Math.min(screen.width, screen.height, window.innerWidth, window.innerHeight)*0.8;
5size = Math.floor(size/2)*2;
6canvas.width = size;
7canvas.height = size;
8
9var ctx = canvas.getContext('2d');
10
11var centerX = size/2;
12var centerY = size/2;
13
14function circle(radius) {
15	ctx.beginPath();
16	ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
17	ctx.fillStyle = 'rgba(0,0,0,0)';
18	ctx.fill();
19	ctx.lineWidth = 1.5;
20	ctx.strokeStyle = 'rgba(0,0,0,1)';
21	ctx.stroke();
22	ctx.closePath();
23};
24
25function radius(radius, angle) {
26	ctx.beginPath();
27	ctx.moveTo(centerX, centerY);
28	x = centerX+radius*Math.cos(angle);
29	y = centerY+radius*Math.sin(angle);
30	ctx.lineTo(x, y);
31	ctx.strokeStyle = 'rgba(0,0,0,1)';
32	ctx.lineWidth = 1.5;
33	ctx.stroke();
34	ctx.closePath();
35}
36
37function sun(radius, angle) {
38	x = centerX+radius*Math.cos(angle);
39	y = centerY+radius*Math.sin(angle);
40	ctx.beginPath();
41	ctx.arc(x, y, 20, 0, 2 * Math.PI, false);
42	ctx.fillStyle = '#DD0';
43	ctx.fill();
44	ctx.strokeStyle = 'rgba(0,0,0,1)';
45	ctx.lineWidth = 1;
46	ctx.stroke();
47	ctx.closePath();
48
49	ctx.fillStyle = 'black';
50	ctx.textAlign = 'center';
51	ctx.textBaseline = 'middle';
52	ctx.font = '20px Verdana,Arial,Helvetica,sans-serif';
53	if(language == 'fr')
54		ctx.fillText('Sol', x, y);
55	else
56		ctx.fillText('Sun', x, y);
57}
58
59function shadow(radius, length) {
60	ctx.beginPath();
61	ctx.moveTo(centerX+radius, centerY);
62	ctx.bezierCurveTo(centerX+radius, centerY+1.5*radius, centerX-radius, centerY+1.5*radius, centerX-radius, centerY);
63	ctx.lineTo(centerX-radius, centerY-length);
64	ctx.bezierCurveTo(centerX-radius, centerY-length-1.5*radius, centerX+radius, centerY-length-1.5*radius, centerX+radius, centerY-length);
65	ctx.lineTo(centerX+radius, centerY);
66	ctx.fillStyle = '#555';
67	ctx.fill();
68	ctx.strokeStyle = 'rgba(0,0,0,1)';
69	ctx.lineWidth = 1;
70	ctx.stroke();
71	ctx.closePath();
72
73	ctx.save();
74	ctx.translate(centerX,centerY);
75	ctx.rotate(Math.PI/2);
76	ctx.fillStyle = 'black';
77	ctx.textAlign = 'center';
78	ctx.textBaseline = 'middle';
79	ctx.font = '18px Verdana,Arial,Helvetica,sans-serif';
80	if(language == 'fr')
81	    ctx.fillText('Ombre', -length/2, 0);
82	else
83	    ctx.fillText('Shadow', -length/2, 0);
84    ctx.restore();
85}
86
87function needle(halfWidth, halfLength, angle) {
88	ctx.save();
89	ctx.translate(centerX,centerY);
90	ctx.rotate(angle);
91
92	ctx.beginPath();
93	ctx.moveTo(0, 0);
94	ctx.lineTo(-halfWidth,0);
95	ctx.lineTo(0, -halfLength);
96	ctx.lineTo(0, 0);
97	if(angle<0)
98		ctx.fillStyle = '#E55';
99	else
100		ctx.fillStyle = '#A00';
101	ctx.fill();
102	ctx.closePath();
103
104	ctx.beginPath();
105	ctx.moveTo(0, 0);
106	ctx.lineTo(halfWidth,0);
107	ctx.lineTo(0, -halfLength);
108	ctx.lineTo(0, 0);
109	if(angle<0)
110		ctx.fillStyle = '#A00';
111	else
112		ctx.fillStyle = '#E55';
113	ctx.fill();
114	ctx.closePath();
115
116	ctx.beginPath();
117	ctx.moveTo(0, 0);
118	ctx.lineTo(halfWidth,0);
119	ctx.lineTo(0, halfLength);
120	ctx.lineTo(0, 0);
121	if(angle<0)
122		ctx.fillStyle = '#999';
123	else
124		ctx.fillStyle = '#EEE';
125	ctx.fill();
126	ctx.closePath();
127
128	ctx.beginPath();
129	ctx.moveTo(0, 0);
130	ctx.lineTo(-halfWidth,0);
131	ctx.lineTo(0, halfLength);
132	ctx.lineTo(0, 0);
133	if(angle<0)
134		ctx.fillStyle = '#EEE';
135	else
136		ctx.fillStyle = '#999';
137	ctx.fill();
138	ctx.closePath();
139
140	ctx.beginPath();
141	ctx.moveTo(-halfWidth, 0);
142	ctx.lineTo(0, -halfLength);
143	ctx.lineTo(halfWidth, 0);
144	ctx.lineTo(0, halfLength);
145	ctx.lineTo(-halfWidth, 0);
146	ctx.strokeStyle = 'black';
147	ctx.lineWidth = 1;
148	ctx.stroke();
149	ctx.closePath();
150
151	ctx.beginPath();
152	ctx.arc(0, 0, 15, 0, 2 * Math.PI, false);
153	ctx.fillStyle = '#AAA';
154	ctx.fill();
155	ctx.strokeStyle = 'rgba(0,0,0,1)';
156	ctx.lineWidth = 1;
157	ctx.stroke();
158	ctx.closePath();
159
160	ctx.fillStyle = 'black';
161	ctx.textAlign = 'center';
162	ctx.textBaseline = 'middle';
163	ctx.font = '20px Verdana,Arial,Helvetica,sans-serif';
164    ctx.fillText('N', 0, -halfLength/4);
165    ctx.fillText('S', 0, halfLength/4);
166
167	ctx.restore();
168}
169
170function initAnimation() {
171	window.requestAnimationFrame(draw);
172}
173
174function draw() {
175	size = Math.min(screen.width, screen.height, window.innerWidth, window.innerHeight)*0.8;
176	size = Math.floor(size/2)*2;
177	canvas.width = size;
178	canvas.height = size;
179	centerX = size/2;
180	centerY = size/2;
181
182
183	var solarTime = trueSolarTime(getLon());
184	var timeAngle = (solarTime.hour-12+solarTime.minute/60+solarTime.second/3600+solarTime.millisecond/3600000)/12*Math.PI;
185	var declination = interpValue(sun_dec_arr);
186
187	var x1 = Math.cos(declination/180*Math.PI)*Math.sin(timeAngle);
188	var y1 = Math.cos(declination/180*Math.PI)*Math.cos(timeAngle);
189	var z1 = Math.sin(declination/180*Math.PI);
190
191	var lat = getLat()/180*Math.PI;
192	var c = Math.cos(Math.PI/2-lat);
193	var s = Math.sin(Math.PI/2-lat);
194	var x2 = x1;
195	var y2 = c*y1-s*z1;
196	var z2 = s*y1+c*z1;
197
198	var heightAngle = Math.atan(z2/Math.sqrt(x2*x2+y2*y2));
199	var azimut = Math.atan2(x2, y2);
200
201	var duration = 2000;
202	var date = new Date();
203	var timeDiff = date.getTime()-start.getTime();
204	var needlePositionDiff = -azimut-lastNeedlePosition;
205	start = date;
206
207	ctx.clearRect(0, 0, size, size);
208
209	ctx.fillStyle = '#05F';
210	ctx.fillRect(0, 0, size, size);
211
212	for(r=0;r<=1;r+=0.165)
213		circle(size/2*r);
214
215	for(angle=0;angle<2*Math.PI;angle+=Math.PI/12)
216		radius(size/2*0.99, angle);
217
218	if(heightAngle>=0) {
219		var needlePosition = lastNeedlePosition+needlePositionDiff*Math.min(timeDiff/duration,1)*0.9;
220		lengthSun = (Math.PI/2-heightAngle)/(Math.PI/2)*(size/2)*0.99;
221
222		shadow(20, lengthSun);
223		sun(lengthSun, Math.PI/2);
224		needle(20, size/2*0.99, needlePosition);
225
226		lastNeedlePosition = needlePosition;
227	}
228	else {
229		ctx.fillStyle = 'white';
230		ctx.textAlign = 'center';
231		ctx.textBaseline = 'middle';
232		ctx.font = '30px Verdana,Arial,Helvetica,sans-serif';
233		if(language == 'fr')
234			ctx.fillText("Le Soleil est couché", centerX, centerY);
235		else
236			ctx.fillText("The Sun has set", centerX, centerY);
237	}
238
239	window.requestAnimationFrame(draw);
240}
241
242var start = new Date();
243var lastNeedlePosition = 0;

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.