/*
Cross Point
CompactDOM script
Version: 1.0, 2022-05-19
Author: Vladimir Kheifets (kheifets.vladimir@online.de)
Copyright ©2022 Vladimir Kheifets All Rights Reserved
Online-tutorial of the Java Script Library CompactDOM:
https://www.alto-booking.com/developer/CompactDOM/
CompactDOM on GitHub:
https://github.com/VladimirKheifets/Java-Script-library-CompactDOM
*/
__.laSelector("en");
dic = __.getDictionary(_dirLa);
//---------------------------------
__.ready(() => {
Env = __.env();
__.on(Env.eor, ev => { __.reload();});
//------------------------------------------------
head = _("head");
title = dic.title;
head.create( title, {tag:"title"} );
head.create(1,{ tag:"meta", charset:"utf-8" });
head.create(1,
{
tag:"meta",
name:"viewport",
content:"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, user-scalable=0"
});
__.link("css/index.css,css/modal.css,css/button_to_up.css,css/selLanguages.css");
ctx = [];
lay = [];
lines = {};
inp = _("input");
lab = _("label");
//------------------------------------------------
colors = {1:"blue", 2:"purple", 3:"red"};
canvasWidthD = [300,500,500,600,860];
canvasHeightD = [300,300,300,400,400];
Env = __.env();
canvasWidth = canvasWidthD[Env.dev];
canvasHeight = canvasHeightD[Env.dev];
gridCell = 10;
X0 = canvasWidth/2 - 1;
Y0 = canvasHeight/2 - 1;
main = _("main");
mainCanvasSt = "width:"+canvasWidth+"px;height:"+canvasHeight+"px"
main.css(mainCanvasSt);
_("header h1").content(title);
//-- canvas -------------------------------------------------------
main.create(3,
{
tag: "canvas",
id: "lay",
width: canvasWidth,
height: canvasHeight,
style:mainCanvasSt
});
elCanvas = _("canvas");
//---LINE div --------------------------------------
_("header div").each((el,ind) => {
i = ind + 1;
el.css("color:" + colors[i]);
el.attr("id","dL"+i);
});
labContent=dic.switch.concat(dic.switch);
_("label").each((el,ind)=>{el.content(labContent[ind])});
//-- footer -------------------------------------------------------
d = new Date();
year = d.getFullYear();
footer = "<p>© </p>" + year + " Alto Booking"
footerSt="margin-top:"+ (canvasHeight+20) + "px";
main.create(footer, {add:"after",tag:"footer"});//, style:footerSt
//------------------------------------------------------------------
nav = __.create(1, {tag:"nav"});
nav.create(
dic.button,
{
tag:"button",
id:"but"
}
);
navCSS = "top:"+(_("header").position().top+10)+"px";
nav.css(navCSS);
navHide = () =>{if(Env.dev<3) nav.hide();};
res = __.create(1,{tag:"p"});
res.css("height:55px");
res.hide(100);
if(Env.dev < 3)
{
menu = main.create(1, {add:"after",tag:"div", id:"menu"});
fileName=(Env.tou?"menuts":"menu")+".html";
menu.include(fileName);
nav.hide();
res.css(navCSS);
menu.click(()=>{
if(nav.ishide())
nav.show();
else
nav.hide();
if(!res.ishide())
res.hide(100);
});
}
i=1;
while(i<3)
{
aI = "a" + i;
bI = "b" + i;
lines[aI] = _("#" + aI);
lines[bI] = _("#" + bI);
_("#dL"+i +" input").each((el,ind) => {
el.attr(
{
"type" : "radio",
"id" : "inp" + i,
"name" : "inp" + i,
"value" : ind+1
}
);
});
i++;
}
// Defining canvas & layots
elCanvas.each((el,ind) => {
ctx[ind] = el.d.getContext('2d');
lay[ind] = el;
el.css("z-index:" + ind);
});
startSetting = () => {
pXY = {
width: canvasWidth,
height: canvasHeight,
1:{line:{}},
2:{line:{}}
};
activesPoint = {1:"a", 2:"a"};
Drawing = {1:true,2:true};
lay[2].hide();
_("span").each((el) => {el.content("")});
but = [];
_("button").each( (el, ind) => {
but[ind] = el;
if(ind>1) el.hide();
});
inp.each( (el, ind) => {
if(ind == 0 || ind == 2) el.checked(2);
el.css("opacity:0");
});
lab.each( (el, ind) => {
if(ind == 1 || ind == 3) el.css("opacity:0");
});
res.css("opacity:0");
};
showLineSelector = (iL) => {
inpEl = {1:[0,1], 2:[2,3]};
labEl = {1:[1],2:[3]};
inp.each( (el, ind) => {
if(inpEl[iL].includes(ind))
el.css("opacity:1");
});
lab.each( (el, ind) => {
if(labEl[iL].includes(ind))
el.css("opacity:1");
});
}
drawingGrid = (cansasW, cansasH, sizeCell, c, color) => {
c.strokeStyle = "#ddd";
for (var x = sizeCell; x < cansasW; x += sizeCell) {
c.moveTo(x, 0);
c.lineTo(x, cansasH);
}
for (var y = sizeCell; y < cansasH; y += sizeCell) {
c.moveTo(0, y);
c.lineTo(cansasW, y);
}
c.stroke();
}
drawingAxes = (cansasW, cansasH, c, color) => {
// Drawing axes, Decart 0 in canvas x=399, y=198
// Axis X
x1X = 10;
y1X = cansasH/2;
x2X = cansasW - 20;
y2X = y1X;
drawingLine(c, x1X, y1X, x2X, y2X, color);
drawingLine(c, x2X-10, y2X+5, x2X, y2X, color);
drawingLine(c, x2X-10, y2X-5, x2X, y2X, color);
drawingText(c,'X', x2X+2, y2X+7, color);
// Axis Y
x1Y = cansasW/2;
y1Y = x1X+10;
x2Y = x1Y;
y2Y = cansasH - 10;
drawingLine(c, x1Y, y1Y, x2Y, y2Y, color);
drawingLine(c, x2Y+5, y1Y+10, x1Y, y1Y, color);
drawingLine(c, x2Y-5, y1Y+10, x1Y, y1Y, color);
drawingText(c,'Y', x1Y-6, y1Y-3, color);
}
drawingLine = (c, x1, y1, x2, y2, color )=> {
c.beginPath();
c.strokeStyle = color;
c.moveTo(x1, y1);
c.lineTo(x2, y2);
c.closePath();
c.stroke();
};
drawingPoint = (c, x, y, color )=> {
c.beginPath();
c.fillStyle = color;
c.arc(x, y, 3, 0, 2 * Math.PI);
c.fill();
c.closePath();
c.stroke();
};
drawingText = (c, text, x, y, color, font )=> {
if(__.u(font)) font = '16px arial'
c.beginPath();
c.fillStyle = color;
c.font = font;
c.fillText(text, x, y);
c.fill();
c.closePath();
c.stroke();
};
clearCanvas = (c) => {c.clearRect(0, 0, canvasWidth, canvasHeight)};
butShowHide = (s) => {
i = 2;
while(i<but.length)
{
if(s)
but[i].show();
else
but[i].hide();
i++;
}
};
ePoint = (e) => {
id = e.target.id;
ind = parseInt(id.substr(3))-1;
x = e.offsetX;
y = e.offsetY;
Xd = x - X0;
Yd = Y0 - y;
};
getlineABC = (XY) => {
if(__.a(XY))
{
x1 = XY[0];
y1 = XY[1];
x2 = XY[2];
y2 = XY[3];
}
else
{
x1 = XY["Xad"];
y1 = XY["Yad"];
x2 = XY["Xbd"];
y2 = XY["Ybd"];
}
A = y2 - y1;
B = x1 - x2;
C = -x1*y2 + y1*x2;
return [A,B,C];
};
crossPoint = (ABC1, ABC2) => {
A1 = ABC1[0];
B1 = ABC1[1];
C1 = ABC1[2];
A2 = ABC2[0];
B2 = ABC2[1];
C2 = ABC2[2];
Xcd = Math.round((B1*C2 - B2*C1)/(A2*B2 - A2*B1));
Ycd = Math.round((A1*C2 - A2*C1)/(A2*B1 - A1*B2));
Xc = Xcd + X0;
Yc = Y0 - Ycd;
return [Xc, Yc, Xcd, Ycd];
};
crossPointK = (XY1, XY2, X0, Y0 ) => {
x1 = XY1["Xad"];
y1 = XY1["Yad"];
x2 = XY1["Xbd"];
y2 = XY1["Ybd"];
x3 = XY2["Xad"];
y3 = XY2["Yad"];
x4 = XY2["Xbd"];
y4 = XY2["Ybd"];
//-----------------------------------
z1 = (x3-x1)*(y2-y1)-(y3-y1)*(x2-x1);
z2 = (x4-x1)*(y2-y1)-(y4-y1)*(x2-x1);
z3 = (x1-x3)*(y4-y3)-(y1-y3)*(x4-x3);
z4 = (x2-x3)*(y4-y3)-(y2-y3)*(x4-x3);
crossPointCheck = (z3*z4>0 || z1*z2>0)?false:true;
//-----------------------------------
if(crossPointCheck)
{
k1 = (y1 - y2) / (x1 - x2);
b1 = y2 - k1 * x2;
k2 = (y3 - y4) / (x3 - x4);
b2 = y4 - k2 * x4;
Xd = Math.round((b2 - b1)/(k1 - k2));
Yd = Math.round(k1*Xd + b1);
X = Xd + X0;
Y = Y0 - Yd;
return {
crossPointCheck: true,
X:X,
Y:Y,
Xd:Xd,
Yd:Yd
};
}
else
return {
crossPointCheck:false
};
};
elCanvas.on('click', (e) => { //mouseclick or touchstart
navHide();
ePoint(e);
if(Drawing[ind])
{
drawingPoint(ctx[ind], x, y, colors[ind]);
if(activesPoint[ind]==="a")
{
activesPoint[ind] = "b";
pXY[ind]["Xa"] = x;
pXY[ind]["Ya"] = y;
pXY[ind]["Xad"] = Xd;
pXY[ind]["Yad"] = Yd;
}
else
{
pXY[ind]["Xb"] = x;
pXY[ind]["Yb"] = y;
pXY[ind]["Xbd"] = Xd;
pXY[ind]["Ybd"] = Yd;
drawingLine(ctx[ind], pXY[ind]["Xa"], pXY[ind]["Ya"], x, y, colors[ind]);
lay[2].show();
Drawing[ind] = false;
if(ind == 2)
{
butShowHide(1);
showLineSelector(1);
showLineSelector(2);
}
}
}
});
elCanvas.on('mousemove', (e) => {
navHide();
ePoint(e);
if(Drawing[ind])
{
ab = activesPoint[ind];
if(ab === "b")
{
clearCanvas(ctx[ind]);
drawingPoint(ctx[ind], pXY[ind]["Xa"], pXY[ind]["Ya"], colors[ind]);
drawingLine(ctx[ind], pXY[ind]["Xa"], pXY[ind]["Ya"], x, y, colors[ind]);
contP = dic.points[1] + ": ";
}
else
contP = " "+dic.points[0]+": ";
lines[ab+ind].content(contP + "x = "+Xd+", y = "+Yd);
}
});
inp.change((e) => {
el = e.target;
id = _(el).attr("id");
i = id.substr(3);
if(activesPoint[i]==="b")
{
val = parseInt(_(el).val());
if(val === 2)
{
ABC1 = getlineABC(pXY[i]);
cHalbW = canvasWidth/2;
cHalbH = canvasHeight/2;
ABC2a = getlineABC([-cHalbW, -cHalbH, -cHalbW, cHalbH]);
ABC2b = getlineABC([cHalbW, -cHalbH, cHalbW, cHalbH]);
XYca = crossPoint(ABC1, ABC2a);
XYcb = crossPoint(ABC1, ABC2b);
drawingLine(ctx[i], XYca[0], XYca[1], XYcb[0], XYcb[1], colors[i]);
pXY[i]["line"] = {
Xa: XYca[0],
Ya: XYca[1],
Xad: XYca[2],
Yad: XYca[3],
Xb: XYcb[0],
Yb: XYcb[1],
Xbd: XYcb[2],
Ybd: XYcb[3]
};
}
else
{
clearCanvas(ctx[i]);
drawingPoint(ctx[i], pXY[i]["Xa"], pXY[i]["Ya"], colors[i]);
drawingLine(ctx[i], pXY[i]["Xa"], pXY[i]["Ya"], pXY[i]["Xb"], pXY[i]["Yb"], colors[i]);
drawingPoint(ctx[i], pXY[i]["Xb"], pXY[i]["Yb"], colors[i]);
delete pXY[i].line;
}
}
});
showResult = (XYcp, code) => {
if(__.u(code)) code="PHP";
res.show(1);
if(XYcp["crossPointCheck"])
{
drawingPoint(ctx[2], XYcp["X"], XYcp["Y"], colors[3]);
out = "Crossing point found.<br>";
out += "Coordinates ";
out += "X: "+XYcp["Xd"] + ", Y: " + XYcp["Yd"];
out += "<br>calculated with " + code;
res.content(out);
}
else
{
out = "Crossing point not found!<br>";
out += "Please click the \"clear\"<br>button and try again.";
res.content(out);
}
};
printInfo = (rsp) => {
txt=dic.structure;
var out = "<div>";
if(rsp)
{
out += txt[0];
}
out += txt[1];
if(rsp)
{
out += txt[2];
}
out += "</div>";
return out;
};
_("button").click((e) => {
id = e.target.id;
i = parseInt(id.substr(3));
switch(i)
{
case 1:
obj=
{
url:_dirLa+"/help.html",
method:"get",
func:(rsp) => {
__.modal(rsp);
},
debug:1
}
__.send(obj);
break;
case 2:
clearCanvas(ctx[0]);
if(gridOn)
{
gridOn = false
drawingAxes(canvasWidth, canvasHeight, ctx[0], "#aaa");
}
else
{
gridOn = true;
drawingGrid(canvasWidth, canvasHeight, 10, ctx[0], "#ddd");
drawingAxes(canvasWidth, canvasHeight, ctx[0], "#aaa");
}
break;
case 3:
XY1 = (pXY[1].line.Xa)?pXY[1].line:pXY[1];
XY2 = (pXY[2].line.Xb)?pXY[2].line:pXY[2];
XYcp = crossPointK(XY1, XY2, X0, Y0 );
showResult(XYcp,"Java Script");
console.log(XYcp);
break;
case 4:
obj=
{
url:"crossPoint.php",
method:"post",
dataType: "json",
responseType: "json",
data:pXY,
func: showResult
}
__.send(obj);
break;
case 5:
obj=
{
url:"crossPoint.php?pr=1",
method:"post",
dataType: "json",
data:pXY,
func: (rsp) => {
out = "<div class = 'outPr'>";
out += rsp;
out += printInfo(true);
out += "</div>";
__.modal(out);
}
}
__.send(obj);
break;
case 6:
obj=
{
url:"crossPoint.php?pr=2",
method:"post",
dataType: "json",
data:pXY,
func: (rsp) => {
out = "<div class = 'outPr'>";
out += rsp;
out += printInfo();
out += "</div>";
__.modal(out);
}
}
__.send(obj);
break;
case 7:
clearCanvas(ctx[1]);
clearCanvas(ctx[2]);
startSetting();
break;
}
navHide();
});
//----------------------------------------------
gridOn = true;
drawingGrid(canvasWidth, canvasHeight, gridCell, ctx[0], "#ddd");
drawingAxes(canvasWidth, canvasHeight, ctx[0], "#aaa");
startSetting();
__.modal();
__.scroll();
__.laSelector();
});