<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Viewport Proof of Concept Dimensioning - RJM Programming - October, 2019</title>
<script type='text/javascript'>
var EquityTolerance = 0.000000001;
var divs=[];
var pofinterest=',5;6,';
var areatemplate='<area shape="rect" coords="20,86,78,160" title="Rectangle 1" href="#" target="_blank" onclick="if (1 == 3) { alert(99); }" />';
var maphtml='<map id="mijigsaw" name="mijigsaw"><area shape="default" nohref alt="" /></map>';
var onenp=[], onepoly=[], onell=[];
var atitle='';
var isstart=true;
var poly='poly';
var rest='';
function IsEqual(d1, d2) {
return Math.abs(d1-d2) <= EquityTolerance;
}
//math logic from http://www.wyrmtale.com/blog/2013/115/2d-line-intersection-in-c
function GetIntersectionPoint(l1p1, l1p2, l2p1, l2p2) {
var l1p1_X=eval('' + l1p1.split(',')[0]);
var l1p1_Y=eval('' + l1p1.split(',')[1]);
var l1p2_X=eval('' + l1p2.split(',')[0]);
var l1p2_Y=eval('' + l1p2.split(',')[1]);
var l2p1_X=eval('' + l2p1.split(',')[0]);
var l2p1_Y=eval('' + l2p1.split(',')[1]);
var l2p2_X=eval('' + l2p2.split(',')[0]);
var l2p2_Y=eval('' + l2p2.split(',')[1]);
var A1 = l1p2_Y - l1p1_Y;
var B1 = l1p1_X - l1p2_X;
var C1 = A1 * l1p1_X + B1 * l1p1_Y;
var A2 = l2p2_Y - l2p1_Y;
var B2 = l2p1_X - l2p2_X;
var C2 = A2 * l2p1_X + B2 * l2p1_Y;
//lines are parallel
var det = A1 * B2 - A2 * B1;
if (IsEqual(det, 0)) {
//alert(56);
return null; //parallel lines
} else {
var x = (B2 * C1 - B1 * C2) / det;
var y = (A1 * C2 - A2 * C1) / det;
var online1 = ((Math.min(l1p1_X, l1p2_X) < x || IsEqual(Math.min(l1p1_X, l1p2_X), x))
&& (Math.max(l1p1_X, l1p2_X) > x || IsEqual(Math.max(l1p1_X, l1p2_X), x))
&& (Math.min(l1p1_Y, l1p2_Y) < y || IsEqual(Math.min(l1p1_Y, l1p2_Y), y))
&& (Math.max(l1p1_Y, l1p2_Y) > y || IsEqual(Math.max(l1p1_Y, l1p2_Y), y))
);
var online2 = ((Math.min(l2p1_X, l2p2_X) < x || IsEqual(Math.min(l2p1_X, l2p2_X), x))
&& (Math.max(l2p1_X, l2p2_X) > x || IsEqual(Math.max(l2p1_X, l2p2_X), x))
&& (Math.min(l2p1_Y, l2p2_Y) < y || IsEqual(Math.min(l2p1_Y, l2p2_Y), y))
&& (Math.max(l2p1_Y, l2p2_Y) > y || IsEqual(Math.max(l2p1_Y, l2p2_Y), y))
);
if (online1 && online2) {
//alert('there ' + x + ',' + y);
onell.push(new_LinkedList2D(new_Point2D(x, y), isstart)); isstart=false;
return new_Point2D(x, y);
} else {
//alert('not there ' + online1 + online2 + x + ',' + y);
//onell.push(new_LinkedList2D(new_Point2D(x, y), isstart)); isstart=false;
return new_Point2D(x, y);
}
}
return null; //intersection is at out of at least one segment.
}
// taken from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html
function IsPointInsidePoly(test, poly) {
var i;
var j;
var result = false;
//alert(poly.Corners.length);
for (i = 0, j = poly.Corners.length - 1; i < poly.Corners.length; j = i++) {
//alert('i=' + i + ' and j=' + j);
console.log("here at " + i);
console.log(poly.CornersX(i));
if ((poly.Corners[i].toString().split(',')[1] > test.toString().split(',')[1]) != (poly.Corners[j].Y > test.Y) &&
(test.X < (poly.Corners[j].X - poly.Corners[i].X) * (test.Y - poly.Corners[i].Y) / (poly.Corners[j].Y - poly.Corners[i].Y) + poly.Corners[i].X)) {
result = !result;
}
}
return result;
}
function new_IsPointInsidePoly(testx, testy, poly) {
var i;
var j;
var result = false;
//alert(poly.CornersX.length);
for (i = 0, j = poly.CornersX.length - 1; i < poly.CornersX.length; j = i++) {
//alert('i=' + i + ' and j=' + j);
//console.log("here at " + i);
//console.log(poly.CornersX[i]);
console.log("here at " + testx + ',' + testy + '?' + (testx < (poly.CornersX[j] - poly.CornersX[i]) * (testy - poly.CornersY[i]) / (poly.CornersY[j] - poly.CornersY[i]) + poly.CornersX[i]));
if ((poly.CornersY[i] > testy) != (poly.CornersY[j] > testy) &&
(testx < (poly.CornersX[j] - poly.CornersX[i]) * (testy - poly.CornersY[i]) / (poly.CornersY[j] - poly.CornersY[i]) + poly.CornersX[i])) {
result = !result;
}
}
return result;
}
function GetIntersectionPoints(l1p1, l1p2, poly) {
var l1p1_X=eval('' + l1p1.split(',')[0]);
var l1p1_Y=eval('' + l1p1.split(',')[1]);
var l1p2_X=eval('' + l1p2.split(',')[0]);
var l1p2_Y=eval('' + l1p2.split(',')[1]);
var ip=null, ipx=null;
var next, i;
//List<Point2D> intersectionPoints = new List<Point2D>();
intersectionPoints = null;
for (i = 0; i < poly.CornersX.length; i++) {
next = (i + 1 == poly.CornersX.length) ? 0 : i + 1;
ip = GetIntersectionPoint('' + l1p1_X + ',' + l1p1_Y, '' + l1p2_X + ',' + l1p2_Y, '' + poly.CornersX[i] + ',' + poly.CornersY[i], '' + poly.CornersX[next] + ',' + poly.CornersY[next]);
if (ip != null) { ipx=ip; onell.push(ip, istart); isstart=false; }
}
return ipx; //intersectionPoints.ToArray();
}
function GetIntersectionOfPolygons(poly1, poly2) { // thanks to https://www.swtestacademy.com/intersection-convex-polygons-algorithm/
var clippedCorners = new Array();
var isin=false;
isstart=true;
var newp=null;
var i, j, next, sofar='';
onell=[];
//Add the corners of poly1 which are inside poly2
//alert(' poly1.CornersX.length=' + poly1.CornersX.length);
for (i = 0; i < poly1.CornersX.length; i++) {
if (new_IsPointInsidePoly(poly1.CornersX[i], poly1.CornersY[i], poly2)) {
isin=true;
//alert(54);
//clippedCorners.AddPoints(new Point2D(poly1.Corners[i] ));
onell.push(new_LinkedList2D('' + poly1.CornersX[i] + ',' + poly1.CornersY[i], isstart));
isstart=false;
}
}
//Add the corners of poly2 which are inside poly1
for (i = 0; i < poly2.CornersX.length; i++) {
if (new_IsPointInsidePoly(poly2.CornersX[i], poly2.CornersY[i], poly1)) {
isin=true;
//alert(154);
//clippedCorners.AddPoints(new Point2D(poly2.Corners[i]));
onell.push(new_LinkedList2D('' + poly2.CornersX[i] + ',' + poly2.CornersY[i], isstart));
isstart=false;
}
}
//Add the intersection points
for (i = 0; i < eval(0 + poly1.CornersX.length); i++) {
for (j = 0; j < eval(0 + poly2.CornersX.length); j++) {
//alert('i=' + i + ' and j=' + j + ' ... ' + poly1.CornersX.length + ',' + poly2.CornersX.length);
newp=GetIntersectionPoint('' + poly1.CornersX[i] + ',' + poly1.CornersY[i], '' + poly1.CornersX[eval((i + 1) % poly1.CornersX.length)] + ',' + poly1.CornersY[eval((i + 1) % poly1.CornersX.length)], '' + poly2.CornersX[j] + ',' + poly2.CornersY[j], '' + poly2.CornersX[eval((j + 1) % poly2.CornersX.length)] + ',' + poly2.CornersY[eval((j + 1) % poly2.CornersX.length)]);
if (newp) { isin=true; }
}
}
if (1 == 7) {
for (i = 0, next = 1; i < poly1.CornersX.length; i++, next = (i + 1 == poly1.CornersX.length) ? 0 : i + 1) {
//alert('i=' + i + ' and next=' + next + ' ... ' + poly1.CornersX[i] + ',' + poly1.CornersY[i] + ';' + poly1.CornersX[next] + ',' + poly1.CornersY[next]);
//clippedCorners.AddPoints(GetIntersectionPoints(poly1.Corners[i], poly1.Corners[next], poly2));
newp=GetIntersectionPoints('' + poly1.CornersX[i] + ',' + poly1.CornersY[i], '' + poly1.CornersX[next] + ',' + poly1.CornersY[next], poly2);
if (newp) { isin=true; }
}
}
if (isin) { poly='poly'; mapareait(); return true; }
return null;
//if (clippedCorners.length == 0) { return null; }
//return new ConvexPolygon2D(OrderClockwise(clippedCorners.slice()));
}
function ltom(allfour) {
var retval='' + Math.min(eval(allfour.split(',')[0]), eval(allfour.split(',')[2]));
rest+='<div class="dglow" style="position:absolute;left:' + retval + 'px;top:' + Math.min(eval(allfour.split(',')[1]), eval(allfour.split(',')[3])) + 'px;width:';
retval+=',' + Math.min(eval(allfour.split(',')[1]), eval(allfour.split(',')[3]));
rest+='' + eval(Math.max(eval(allfour.split(',')[0]), eval(allfour.split(',')[2])) - Math.min(eval(allfour.split(',')[0]), eval(allfour.split(',')[2]))) + 'px;height:';
retval+=',' + Math.max(eval(allfour.split(',')[0]), eval(allfour.split(',')[2]));
retval+=',' + Math.max(eval(allfour.split(',')[1]), eval(allfour.split(',')[3]));
rest+='' + eval(Math.max(eval(allfour.split(',')[1]), eval(allfour.split(',')[3])) - Math.min(eval(allfour.split(',')[1]), eval(allfour.split(',')[3]))) + 'px;z-index:12;background-color:yellow;opacity:0.6;text-align:center;"><br><br>Intersection of ' + atitle + '</div>';
return retval;
}
function mapareait() {
// var areatemplate='<area shape="rect" coords="20,86,78,160" title="Rectangle 1" href="#" target="_blank" onclick="if (1 == 3) { alert(99); }" />';
var picked=false, coords='', delim='', lastx='', lasty='', finalcoords=',', prelastx='', prelasty='';
if (onell.length > 0) {
//alert('onell.length=' + onell.length);
for (var i=0; i < onell.length; i++) {
picked=false;
//alert('i=' + i);
for (var j=0; j < onell.length; j++) {
if (picked) {
picked=picked;
} else if (i >= 1 && finalcoords == '' && poly == 'rect') {
picked=picked;
onell[j].tagged=true;
} else if (!onell[j].tagged && coords == '') {
coords+=delim + onell[j].X[0] + ',' + onell[j].Y[0];
finalcoords+=coords;
lastx='' + onell[j].X[0];
lasty='' + onell[j].Y[0];
prelastx=lastx;
prelasty=lasty;
delim=',';
picked=true;
onell[j].tagged=true;
} else if (onell.length == 4 && i == 1 && !onell[j].tagged &&
((Math.round(('' + onell[j].X[0])) != Math.round(prelastx) && Math.round(('' + onell[j].Y[0])) != Math.round(prelasty)) ||
Math.round(('' + onell[j].X[0])) != Math.round(prelastx) && Math.round(('' + onell[j].Y[0])) != Math.round(prelasty))
) {
coords=finalcoords.substring(1);
if (eval(onell[j].X[0]) > eval(coords.split(',')[0])) {
coords=onell[j].X[0] + ',' + onell[j].Y[0] + delim + finalcoords.substring(1);
} else {
coords+=delim + onell[j].X[0] + ',' + onell[j].Y[0];
}
coords=ltom(coords);
lastx='' + onell[j].X[0];
lasty='' + onell[j].Y[0];
delim=',';
picked=true;
onell[j].tagged=true;
//alert('Yes');
poly='rect';
finalcoords='';
} else if (poly == 'poly' && !onell[j].tagged &&
((Math.round(('' + onell[j].X[0])) == Math.round(lastx) && Math.round(('' + onell[j].Y[0])) != Math.round(lasty)) ||
Math.round(('' + onell[j].X[0])) != Math.round(lastx) && Math.round(('' + onell[j].Y[0])) == Math.round(lasty))
) {
coords+=delim + onell[j].X[0] + ',' + onell[j].Y[0];
lastx='' + onell[j].X[0];
lasty='' + onell[j].Y[0];
delim=',';
if (i == 1 && onell.length == 4) { picked=picked; } else { picked=true; }
onell[j].tagged=true;
//alert('yes');
}
}
}
maphtml=maphtml.replace('>', '><area shape="' + poly + '" coords="' + coords + finalcoords + '" title="' + atitle +'" href="#" target="_blank" onclick="if (1 == 1) { alert(99); }" />');
}
}
function new_Point2D(isx, isy) {
return '' + isx + ',' + isy;
}
function new_LinkedList2D(isxy, isfirst) {
console.log(isxy);
var previs;
if (isfirst) {
return {
X: [eval(isxy.split(',')[0])],
Y: [eval(isxy.split(',')[1])],
tagged: false,
next: null,
prev: null
};
} else if (isxy != '') {
previs=null; //onell[eval(-1 + onell.length)];
//alert(isxy);
//new_LinkedList2D('', false);
return {
X: [eval(isxy.split(',')[0])],
Y: [eval(isxy.split(',')[1])],
tagged: false,
next: null,
prev: previs
};
} else {
previs=onell[eval(-2 + onell.length)];
previs.next=onell[eval(-1 + onell.length)];
return null;
}
}
function new_ConvexPolygon2D(isxy) {
console.log(isxy);
return {
CornersX: [eval(isxy.split(',')[0])],
CornersY: [eval(isxy.split(',')[1])],
CornersCurr: 1,
CornersLength: 4
};
}
function new_ZAddPoints(pool, newpoints) {
var found = false;
if (pool.CornersCurr >= 4) { found=true; }
//if (!found) { pool.CornersX[pool.CornersCurr]=eval(newpoints.split(',')[0]); pool.CornersY[pool.CornersCurr]=eval(newpoints.split(',')[1]); pool.CornersCurr++; }
if (!found) { onepoly[eval(-1 + onepoly.length)].CornersX.push(eval(newpoints.split(',')[0])); onepoly[eval(-1 + onepoly.length)].CornersY.push(eval(newpoints.split(',')[1])); onepoly[eval(-1 + onepoly.length)].CornersCurr++; }
}
function divpolys() {
var divsii;
divs=document.getElementsByTagName('div');
for (var ii=0; ii<divs.length; ii++) {
//alert(ii);
divsii=divs[ii].getBoundingClientRect();
divs[ii].title='Polygon ' + eval(1 + ii);
onenp.push(new_Point2D(divsii.left, divsii.top));
//alert(12);
onepoly.push(new_ConvexPolygon2D(onenp[eval(-1 + onenp.length)]));
//alert(13);
onenp.push(new_Point2D(eval(divsii.left + divsii.width), divsii.top));
//alert(14);
new_ZAddPoints(onepoly[eval(-1 + onepoly.length)],onenp[eval(-1 + onenp.length)]);
//alert(15);
onenp.push(new_Point2D(eval(divsii.left + divsii.width), eval(divsii.top + divsii.height)));
//alert(16);
new_ZAddPoints(onepoly[eval(-1 + onepoly.length)],onenp[eval(-1 + onenp.length)]);
//alert(17);
onenp.push(new_Point2D(divsii.left, eval(divsii.top + divsii.height)));
//alert(18);
new_ZAddPoints(onepoly[eval(-1 + onepoly.length)],onenp[eval(-1 + onenp.length)]);
//alert(19);
onenp.push(new_Point2D(divsii.left, divsii.top));
//alert(20);
new_ZAddPoints(onepoly[eval(-1 + onepoly.length)],onenp[eval(-1 + onenp.length)]);
//alert(1);
}
var sofar='';
for (var jj=0; jj<onepoly.length; jj++) {
for (var kk=0; kk<onepoly.length; kk++) {
if (jj != kk && sofar.indexOf(',' + eval(1 + jj) + ';' + eval(1 + kk) + ',') == -1 && pofinterest.indexOf(',' + eval(1 + jj) + ';' + eval(1 + kk) + ',') != -1) {
sofar+=',' + eval(1 + kk) + ';' + eval(1 + jj) + ',';
atitle='Polygon ' + eval(1 + jj) + ' and Polygon ' + eval(1 + kk);
GetIntersectionOfPolygons(onepoly[jj], onepoly[kk]);
//if (GetIntersectionOfPolygons(onepoly[jj], onepoly[kk])) {
// alert(atitle + ' intersect');
//} else {
// alert(atitle + ' do not intersect');
//}
}
}
}
if (maphtml.indexOf('oly') != -1) {
//alert(maphtml + ' ' + rest);
document.body.innerHTML+=maphtml.replace('<map ','<map style="z-index:7;width:100%;height:100%;" ') + rest;
}
}
</script>
<style>
* {
margin: 0 0 0 0;
padding: 0 0 0 0;
}
html {
background: linear-gradient(rgba(255,255,255,0.8),rgba(255,255,255,0.8)),url(../PHP/one.jpg) no-repeat center fixed;
background-size: contain;
}
.full {
color: blue;
width: 100vx;
height: 100vh;
border: 2px solid blue;
text-align: right;
}
.full::after {
content: "Am filling whole (100vx x 100vh) viewport";
}
.right {
color: green;
position: absolute;
z-index: 5;
top: 30px;
height: calc(100vh - 60px);
left: calc(100% - 150px);
width: 120px;
border: 2px dashed green;
text-align: right;
}
.right::after {
content: "Am on the right";
}
.left {
color: pink;
position: absolute;
z-index: 7;
top: 30px;
height: calc(100vh - 60px);
left: 30px;
width: 120px;
border: 2px dashed pink;
text-align: left;
}
.left::after {
content: "Am on the left";
}
.sfull {
color: brown;
position: absolute;
z-index: 15;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
border: 2px dotted brown;
vertical-align: middle;
}
.sfull::after {
content: "Am filling whole (100% x 100%) screen";
}
.center {
color: orange;
position: absolute;
z-index: 8;
top: 30px;
height: calc(100vh - 60px);
left: calc(50% - 60px);
width: 120px;
border: 2px dashed orange;
text-align: center;
vertical-align: middle;
}
.center::after {
content: "Am in the center of screen and middle of viewport";
}
.middle {
color: olive;
position: absolute;
z-index: 9;
top: calc(50vh - 60px);
height: 120px;
left: 30px;
width: calc(100% - 60px);
border: 2px dashed olive;
text-align: center;
vertical-align: middle;
}
.middle::after {
content: "Am in the middle of viewport and center of screen";
}
.glow {
-webkit-animation: glow 1s ease-in-out infinite alternate;
-moz-animation: glow 1s ease-in-out infinite alternate;
animation: glow 1s ease-in-out infinite alternate;
}
/* Thanks to https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_glowing_text */
@-webkit-keyframes glow {
from {
box-shadow: 0 0 3px #fff, 0 0 5px #fff, 0 0 37px #e60073, 0 0 9px #e60073, 0 0 11px #e60073, 0 0 13px #e60073, 0 0 15px #e60073;
}
to {
box-shadow: 0 0 24px #fff, 0 0 6px #ff4da6, 0 0 8px #ff4da6, 0 0 10px #ff4da6, 0 0 12px #ff4da6, 0 0 14px #ff4da6, 0 0 16px #ff4da6;
}
}
.dglow {
-webkit-animation: dglow 1s ease-in-out infinite alternate;
-moz-animation: dglow 1s ease-in-out infinite alternate;
animation: dglow 1s ease-in-out infinite alternate;
}
/* Thanks to https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_glowing_text */
@-webkit-keyframes dglow {
from {
box-shadow: 0 0 24px #fff, 0 0 6px #da6ff4, 0 0 8px #da6ff4, 0 0 10px #da6ff4, 0 0 12px #da6ff4, 0 0 14px #da6ff4, 0 0 16px #da6ff4;
}
to {
box-shadow: 0 0 3px #fff, 0 0 5px #fff, 0 0 37px #073e60, 0 0 9px #073e60, 0 0 11px #073e60, 0 0 13px #073e60, 0 0 15px #073e60;
}
}
</style>
</head>
<body onload='divpolys();'>
<div class='full glow'></div>
<div class='right glow'></div>
<div class='sfull glow'></div>
<div class='left glow'></div>
<div class='center glow'></div>
<div class='middle glow'></div>
</body>
</html>