commit all archived files

This commit is contained in:
mappu 2013-09-23 07:16:17 +00:00
parent 7c2aecb834
commit c57b2e3261
3 changed files with 324 additions and 0 deletions

12
README.md Normal file
View File

@ -0,0 +1,12 @@
# monitortoy
![](https://img.shields.io/badge/written%20in-Javascript%20%28canvas%29-blue)
A utility to help measure and layout a multimonitor setup.
Features: Add monitors from a given diagonal and aspect ratio, swivel monitors, snap to edges, and measure between any two vertices.
## Download
- [⬇️ monitortoy.htm](dist-archive/monitortoy.htm) *(7.56 KiB)*

312
dist-archive/monitortoy.htm Normal file
View File

@ -0,0 +1,312 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
body { text-align:center; }
#c {
border:1px solid darkgrey;
margin:2px;
}
</style>
</head>
<body>
Monitor:
<input type="number" id="diag" value="24" min="7" max="70">
", ratio
<input type="number" id="ratioL" value="16" min="1" max="100">
<a href="javascript:;" id="swap">:</a>
<input type="number" id="ratioR" value="9" min="1" max="100">
<input type="button" id="add" value="Add &raquo;">
|
<input type="button" id="del" value="Delete &raquo;">
|
<input type="button" id="swivel" value="Swivel &raquo;">
|
<input type="button" id="measure" value="Measure &raquo;">
<br>
<canvas id="c">old browser</canvas>
<script type="text/javascript">
var SCALE = 6,
BOARDW = 512,
BOARDH = 512,
SNAPEDGE = 5,
PTSIZE = 5,
TEXTFADETIME = 2000;
var SEL_NONE = 0, SEL_DELETE = 1, SEL_SWIVEL = 2, SEL_MEASURE1 = 3, SEL_MEASURE2 = 4;;
function id(s) { return document.getElementById(s); };
var c, ctx, boxes=[], selidx=-1, dragoffset={}, selmode=SEL_NONE, measurept=[];
var txt="", txttimeout;
function onDraw() {
ctx.clearRect(0, 0, this.c.width, this.c.height);
ctx.fillStyle = "#FF0000";
if (txt.length) {
ctx.fillText(txt, 10, 15);
}
for (var i in boxes) {
if (selmode) {
ctx.strokeStyle="#FF0000";
} else if (selidx == i) {
ctx.strokeStyle="#0000FF";
} else {
ctx.strokeStyle="#000000";
};
ctx.strokeRect(boxes[i].x, boxes[i].y, boxes[i].w, boxes[i].h);
if (selmode && boxes[i].highlight) {
ctx.fillRect(boxes[i].x, boxes[i].y, boxes[i].w, boxes[i].h);
} else {
}
}
if (measurept.length) {
ctx.fillStyle = "#00FF00";
for (var i in measurept) {
if (measurept[i] === false) continue;
ctx.fillRect(
measurept[i][0] - PTSIZE,
measurept[i][1] - PTSIZE,
PTSIZE * 2,
PTSIZE * 2
);
}
}
return true;
};
function roundfmt(val, decimals) {
if (decimals <= 0) return Math.round(val);
return Math.round(val * Math.pow(10, decimals)) / Math.pow(10, decimals);
};
function findBox(x, y) {
for (var i in boxes) {
if (
x > boxes[i].x && x < (boxes[i].x + boxes[i].w) &&
y > boxes[i].y && y < (boxes[i].y + boxes[i].h)
) {
return i;
}
}
return -1;
}
function findCorner(x, y) {
for (var i in boxes) {
if (Math.abs(x - boxes[i].x) < SNAPEDGE &&
Math.abs(y - boxes[i].y) < SNAPEDGE
) {
return [boxes[i].x, boxes[i].y];
}
if (Math.abs(x - boxes[i].x - boxes[i].w) < SNAPEDGE &&
Math.abs(y - boxes[i].y) < SNAPEDGE
) {
return [boxes[i].x + boxes[i].w, boxes[i].y];
}
if (Math.abs(x - boxes[i].x) < SNAPEDGE &&
Math.abs(y - boxes[i].y - boxes[i].h) < SNAPEDGE
) {
return [boxes[i].x, boxes[i].y + boxes[i].h];
}
if (Math.abs(x - boxes[i].x - boxes[i].w) < SNAPEDGE &&
Math.abs(y - boxes[i].y - boxes[i].h) < SNAPEDGE
) {
return [boxes[i].x + boxes[i].w, boxes[i].y + boxes[i].h];
}
}
return false;
}
function onDown(x, y) {
if (selmode == SEL_MEASURE1 || selmode == SEL_MEASURE2) {
var c = findCorner(x, y);
if (c === false) {
// clicked out - cancel
selmode = SEL_NONE;
measurept = [];
return;
}
if (selmode == SEL_MEASURE1) {
selmode = SEL_MEASURE2;
return;
} else {
// measure
var dx = (measurept[SEL_MEASURE1][0] - measurept[SEL_MEASURE2][0]) / SCALE,
dy = (measurept[SEL_MEASURE1][1] - measurept[SEL_MEASURE2][1]) / SCALE;
txt = "Measurement: "+roundfmt(Math.sqrt( dx*dx + dy*dy ), 2)+'"';
clearTimeout(txttimeout);
txttimeout = setTimeout(function() {
txt = "";
}, TEXTFADETIME);
// clear
measurept = [];
}
}
var i = findBox(x, y);
if (i != -1) {
// found
if (selmode == SEL_DELETE) {
selmode = SEL_NONE;
selidx = -1;
delete boxes[i];
} else if (selmode == SEL_SWIVEL) {
selmode = SEL_NONE;
selidx = -1;
var tmp = boxes[i].w; boxes[i].w = boxes[i].h; boxes[i].h = tmp;
boxes[i].highlight = false; // clear highlight
} else {
selmode = SEL_NONE;
selidx = i;
dragoffset = {'x':x - boxes[i].x,'y':y - boxes[i].y};
}
} else {
// not found
selmode = SEL_NONE;
selidx = -1;
}
};
function onMove(x, y) {
if (selidx != -1) {
boxes[selidx].x = x - dragoffset.x;
boxes[selidx].y = y - dragoffset.y;
// snap to edges
for (var i in boxes) {
if (selidx == i) continue;
// horizontal snap
if (Math.abs(boxes[selidx].x - boxes[i].x) < SNAPEDGE) {
boxes[selidx].x = boxes[i].x;
} else if (Math.abs(boxes[selidx].x - boxes[i].x - boxes[i].w) < SNAPEDGE) {
boxes[selidx].x = boxes[i].x + boxes[i].w;
} else if (Math.abs(boxes[selidx].x + boxes[selidx].w - boxes[i].x) < SNAPEDGE) {
boxes[selidx].x = boxes[i].x - boxes[selidx].w;
} else if (Math.abs(boxes[selidx].x + boxes[selidx].w - boxes[i].x - boxes[i].w) < SNAPEDGE) {
boxes[selidx].x = boxes[i].x + boxes[i].w - boxes[selidx].w;
}
// vertical snap
if (Math.abs(boxes[selidx].y - boxes[i].y) < SNAPEDGE) {
boxes[selidx].y = boxes[i].y;
} else if (Math.abs(boxes[selidx].y - boxes[i].y - boxes[i].h) < SNAPEDGE) {
boxes[selidx].y = boxes[i].y + boxes[i].h;
} else if (Math.abs(boxes[selidx].y + boxes[selidx].h - boxes[i].y) < SNAPEDGE) {
boxes[selidx].y = boxes[i].y - boxes[selidx].h;
} else if (Math.abs(boxes[selidx].y + boxes[selidx].h - boxes[i].y - boxes[i].h) < SNAPEDGE) {
boxes[selidx].y = boxes[i].y + boxes[i].h - boxes[selidx].h;
}
};
} else if (selmode == SEL_MEASURE1 || selmode == SEL_MEASURE2) {
// collision detect with corner
measurept[selmode] = findCorner(x, y);
} else if (selmode) {
// collision detect with monitor
for (var i in boxes) {
boxes[i].highlight = false;
}
var i = findBox(x, y);
if (i != -1) boxes[i].highlight = true;
}
};
function onUp() {
// Unselect
selidx = -1;
};
function createBox(diag, rl, rr) {
// Convert to width/height
var x = diag / (Math.sqrt(rl*rl + rr*rr));
return [rl * x * SCALE, rr * x * SCALE];
};
function onLoad() {
// Events
id('swap').onclick = function() {
var rl = id('ratioL').value, rr = id('ratioR').value;
id('ratioR').value = rl;
id('ratioL').value = rr;
};
id('add').onclick = function() {
var newbox = createBox(
parseInt(id('diag').value, 10),
parseInt(id('ratioL').value, 10),
parseInt(id('ratioR').value, 10)
);
boxes.push({
'x': 10, 'y': 10, 'w': newbox[0], 'h': newbox[1]
});
};
id('del').onclick = function() {
selidx = -1;
selmode = SEL_DELETE;
};
id('swivel').onclick = function() {
selidx = -1;
selmode = SEL_SWIVEL;
};
id('measure').onclick = function() {
selidx = -1;
selmode = SEL_MEASURE1;
};
// Initialise canvas
c = id('c'); ctx = c.getContext("2d");
c.width = BOARDW;
c.height = BOARDH;
c.onmousedown = function(e) { return onDown(e.offsetX, e.offsetY); };
c.onmousemove = function(e) { return onMove(e.offsetX, e.offsetY); };
c.onmouseup = onUp;
var raf =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, ev) {
window.setTimeout(callback, 1000 / 60);
};
var callFrame = function() {
raf(function() {
if (onDraw() !== false) callFrame();
});
}
callFrame();
};
onLoad();
</script>
</body>
</html>

BIN
doc/monitortoy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB