File: /var/www/nowruzgan.com/vis/astrolabe/lib/scripts.js
var mouseIn = false;
var mouseDown = false;
var dragging = false;
var actionLayer;
var reteLayer;
var boundingRect;
var alpha = 0;
var refAlpha = 0;
var rotationAlpha = 0;
var direction = {lastAlpha: 0, sign: 0, textSign: false};
var transformationAlpha = 0;
var ctx;
var drawStars = true;
var stars = [
{ x: 394, y: 315, en: 'Deneb Dulfim', fa: 'ذنب الدلفین' },
{ x: 286, y: 352, en: '02', fa: 'شماره ۰۲' },
{ x: 297, y: 484, en: 'Merga', fa: 'المرأةالمسلسله' },
{ x: 417, y: 488, en: 'Caph', fa: 'کف الخضیب' },
{ x: 443, y: 415, en: 'Deneb', fa: 'ردف' },
{ x: 392, y: 794, en: 'Rigel', fa: 'رجل الجبار' },
{ x: 427, y: 814, en: 'Rigel', fa: 'رجل الجبار' },
{ x: 518, y: 850, en: 'Sirius', fa: 'شعرای یمانی' },
{ x: 651, y: 624, en: 'Regulus', fa: 'قلب الاسد' },
{ x: 400, y: 572, en: 'Algol', fa: 'رأس الغول' },
{ x: 456, y: 601, en: 'Capella', fa: 'عیّوق' },
{ x: 244, y: 237, en: 'Deneb Algedi', fa: 'ذنب الجدی' },
{ x: 295, y: 654, en: 'Kaffaljidhm', fa: 'کف الجذماء' },
{ x: 203, y: 577, en: '14', fa: 'جبهة قیطس' },
{ x: 162, y: 443, en: 'Dheneb', fa: 'ذنب قیطس' },
{ x: 605, y: 398, en: 'Alfecca Meridiana', fa: 'فکه' },
{ x: 500, y: 386, en: 'Vega', fa: 'نسر واقع' },
{ x: 416, y: 369, en: '18', fa: 'جناح الدجاجة' },
{ x: 593, y: 371, en: '19', fa: 'منکب الجاثی' },
{ x: 577, y: 564, en: '20', fa: 'شماره ۲۰' },
{ x: 587, y: 484, en: 'Almach', fa: 'العناق' },
{ x: 656, y: 431, en: 'Arcturus', fa: 'سماک رامح' },
{ x: 492, y: 702, en: '23', fa: 'شماره ۲۳' },
{ x: 505, y: 708, en: 'Alhena', fa: 'هنعه' },
{ x: 455, y: 731, en: 'Betelgeuse', fa: 'الید الجوزا' },
{ x: 423, y: 727, en: 'Betelgeuse', fa: 'الید الجوزا' },
{ x: 398, y: 671, en: 'Ain', fa: 'عین الثور' },
{ x: 623, y: 849, en: '28', fa: 'شماره ۲۸' },
{ x: 563, y: 726, en: 'Procyon', fa: 'شعرای شامی' },
{ x: 437, y: 279, en: 'Altair', fa: 'نسر طایر' },
{ x: 557, y: 301, en: 'Ras Alhague', fa: 'رأس الحوّاء' },
{ x: 659, y: 347, en: 'Unuk / Unukalhai', fa: 'عُنُق الحیه' },
{ x: 732, y: 182, en: 'Antares', fa: 'قلب العقرب' },
{ x: 685, y: 713, en: 'Alphard', fa: 'الفرد' },
// { x: 502, y: 97, en: '35', fa: 'شماره ۳۵' },
{ x: 793, y: 456, en: 'Spica', fa: 'سماک اعزل' },
{ x: 779, y: 322, en: '37', fa: 'شماره ۳۷' },
{ x: 796, y: 643, en: '38', fa: 'شماره ۳۸' },
{ x: 829, y: 549, en: 'Gienah Gurab', fa: 'جناح الغراب' },
{ x: 620, y: 648, en: 'Alterf', fa: 'طرف' },
];
window.addEventListener('load', () => init());
function init() {
actionLayer = document.querySelector('.layer.action');
reteLayer = document.querySelector('.layer.rete');
boundingRect = actionLayer.getBoundingClientRect();
ctx = document.querySelector('.layer.overlay canvas').getContext('2d');
ctx.fillStyle = 'rgba(0, 0, 0, 0)';
ctx.font = '10px Farhang';
ctx.fillText('الف', 0, 0)
window.addEventListener('touchstart', event => { console.log('touchstart'); press(event); });
window.addEventListener('mousedown', event => press(event));
window.addEventListener('touchmove', event => { console.log('touchmove'); move(event); });
window.addEventListener('mousemove', event => move(event));
window.addEventListener('touchend', event => { console.log('touchend'); release(); });
window.addEventListener('touchcancel', event => { console.log('touchcancel'); release(); });
window.addEventListener('mouseup', event => release(event));
window.addEventListener('click', event => click(event));
for(let star of stars) {
star.transX = star.x;
star.transY = star.y;
}
redraw();
}
function click(event) {
if(event.type == 'touchmove'){
event.x = event.touches[0].pageX;
event.y = event.touches[0].pageY;
}
let x = (event.x - boundingRect.x) / boundingRect.width;
let y = (event.y - boundingRect.y) / boundingRect.height;
if(!dragging)
for(let star of stars)
star.selected = Math.sqrt((star.transX - x*1000)**2 + (star.transY - y*1000)**2) < 10;
dragging = false;
redraw();
}
function press(event) {
dragging = false;
if(!mouseIn) return;
mouseDown = true;
refAlpha = alpha;
rotationDirection = 0;
direction.lastAlpha = alpha;
direction.d = 0;
}
function move(event) {
if(event.type == 'touchmove'){
event.x = event.touches[0].pageX;
event.y = event.touches[0].pageY;
}
let x = (event.x - boundingRect.x) / boundingRect.width - .5;
let y = (event.y - boundingRect.y) / boundingRect.height - .5;
if(Math.sqrt(x**2 + y**2)<.416 || mouseDown) {
mouseIn = true;
actionLayer.classList.add('hover');
alpha = Math.atan2(y, x);
if(alpha<0) alpha += 2*Math.PI;
for(let star of stars)
star.hover = Math.sqrt((star.transX - (x+.5)*1000)**2 + (star.transY - (y+.5)*1000)**2) < 10;
if(mouseDown) {
dragging = true;
transformationAlpha = rotationAlpha + (alpha - refAlpha);
reteLayer.style.transform = `rotate(${transformationAlpha}rad)`;
if(alpha!=direction.lastAlpha) {
let delta1 = delta(refAlpha, direction.lastAlpha);
let delta2 = delta(refAlpha, alpha);
let delta3 = delta(direction.lastAlpha, alpha);
if(delta3.d>=delta1.d && delta3.d>=delta2.d)
direction.sign = delta2.s;
direction.textSign = (direction.sign && alpha<refAlpha) || (!direction.sign && alpha>refAlpha);
direction.lastAlpha = alpha;
}
}
redraw();
}else {
actionLayer.classList.remove('hover');
mouseIn = false;
if(mouseDown)
release();
}
}
function release(event) {
mouseDown = false;
rotationAlpha += alpha - refAlpha;
refAlpha = 0;
redraw();
}
function redraw() {
ctx.clearRect(0, 0, 1000, 1000);
if(mouseDown) {
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
ctx.beginPath();
ctx.arc(500, 500, 415, refAlpha, alpha, !direction.sign);
ctx.lineTo(Math.cos(alpha)*438 + 500, Math.sin(alpha)*438 + 500);
ctx.arc(500, 500, 438, alpha, refAlpha, direction.sign);
ctx.lineTo(Math.cos(refAlpha)*415 + 500, Math.sin(refAlpha)*415 + 500);
ctx.fill();
ctx.strokeStyle = 'white';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(500, 500);
ctx.lineTo(Math.cos(alpha)*500 + 500, Math.sin(alpha)*500 + 500);
ctx.moveTo(500, 500);
ctx.lineTo(Math.cos(refAlpha)*500 + 500, Math.sin(refAlpha)*500 + 500);
ctx.stroke();
let text = Math.abs(alpha - refAlpha);
if(direction.textSign)
text = 2*Math.PI - text;
text = (text*180/Math.PI).toFixed()+'°';
ctx.save();
ctx.fillStyle = 'black';
ctx.textAlign = 'center';
let rotation = (alpha+refAlpha)/2;
if(direction.textSign)
rotation += Math.PI;
ctx.translate(Math.cos(rotation)*420 + 500, Math.sin(rotation)*420 + 500)
ctx.rotate(rotation + Math.PI/2);
ctx.font = '18px monospace';
ctx.fillText(text, 0, 0);
ctx.restore();
}
if(drawStars) {
for(let star of stars) {
let x = star.x - 500;
let y = star.y - 500;
let _alpha = Math.atan2(y, x);
let r = Math.sqrt(x*x + y*y);
let theta = _alpha + transformationAlpha;
if(mouseDown) {
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 255, 255, .75)';
ctx.lineWidth = 2;
ctx.arc(500, 500, r, rotationAlpha+_alpha, rotationAlpha + _alpha + alpha-refAlpha, !direction.sign);
ctx.stroke();
}
ctx.beginPath();
ctx.fillStyle = '#37C7FF';
ctx.strokeStyle = '#404040';
ctx.lineWidth = 1;
star.transX = r*Math.cos(theta) + 500;
star.transY = r*Math.sin(theta) + 500;
ctx.arc(star.transX, star.transY, ((star.hover && !dragging) || star.selected) ? 10 : 5, 0, 2*Math.PI);
ctx.stroke();
ctx.fill();
// ctx.fillStyle = '#FFFFFF';
// ctx.textAlign = 'center';
// ctx.fillText(star.en, star.transX, star.transY+2)
}
for(let star of stars)
if(star.selected) {
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(255, 255, 255, .5)';
ctx.fillStyle = 'rgba(70, 70, 70, .85)';
ctx.beginPath();
ctx.moveTo(star.transX, star.transY+5);
ctx.lineTo(star.transX+5, star.transY+10);
ctx.lineTo(star.transX+70, star.transY+10);
ctx.lineTo(star.transX+70, star.transY+60);
ctx.lineTo(star.transX-70, star.transY+60);
ctx.lineTo(star.transX-70, star.transY+10);
ctx.lineTo(star.transX-5, star.transY+10);
ctx.lineTo(star.transX, star.transY+5);
ctx.fill();
ctx.stroke();
ctx.font = '14px Farhang';
ctx.fillStyle = 'white';
ctx.textAlign = 'center';
ctx.fillText(star.en, star.transX, star.transY+30);
ctx.font = '16px Farhang';
ctx.fillText(star.fa, star.transX, star.transY+50);
}
}
}
function delta(a1, a2) {
let d = Math.abs(a1 - a2);
let _d = d;
if(d > Math.PI)
d = 2*Math.PI - d;
let s = (a2>a1 && d==_d) || (a2<a1 && d!=_d);
return {d, s};
}