Skip to content

Commit 9e75dad

Browse files
authored
Merge pull request #12 from mwomick/ui-rendering-corrections
UI rendering corrections and constrained angles feature
2 parents db9a898 + dcfd15a commit 9e75dad

File tree

1 file changed

+138
-79
lines changed

1 file changed

+138
-79
lines changed

script.js

+138-79
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ var color_choices = [
1212
"#CCCCCC",
1313
];
1414

15+
var radiansPer45Degrees = Math.PI / 4;
16+
1517
var canvas = document.getElementById('canvas');
1618
var ctx = canvas.getContext('2d');
19+
ctx.lineJoin = 'bevel';
20+
1721
var img = new Image();
1822
var rgb_color = color_choices[Math.floor(Math.random() * color_choices.length)]
1923
var opaque_color = 'rgba(0,0,0,0.5)';
@@ -28,13 +32,12 @@ var masterColors = [];
2832

2933
var drawMode
3034
setDrawMode('polygon')
31-
35+
var constrainAngles = false;
3236
var showNormalized = false;
3337

3438
var modeMessage = document.querySelector('#mode');
3539
var coords = document.querySelector('#coords');
3640

37-
3841
function clipboard(selector) {
3942
var copyText = document.querySelector(selector).innerText;
4043
navigator.clipboard.writeText(copyText);
@@ -53,6 +56,28 @@ function zoom(clicks) {
5356
canvas.style.height = h + 'px';
5457
}
5558

59+
function closePath() {
60+
canvas.style.cursor = 'default';
61+
masterPoints.push(points);
62+
masterColors.push(rgb_color);
63+
ctx.clearRect(0, 0, canvas.width, canvas.height);
64+
ctx.drawImage(img, 0, 0);
65+
66+
drawAllPolygons();
67+
points = [];
68+
69+
// dont choose a color that has already been chosen
70+
var remaining_choices = color_choices.filter(function(x) {
71+
return !masterColors.includes(x);
72+
});
73+
74+
if (remaining_choices.length == 0) {
75+
remaining_choices = color_choices;
76+
}
77+
78+
rgb_color = remaining_choices[Math.floor(Math.random() * remaining_choices.length)];
79+
}
80+
5681
// placeholder image
5782
img.src = 'https://assets.website-files.com/5f6bc60e665f54545a1e52a5/63d3f236a6f0dae14cdf0063_drag-image-here.png';
5883
img.onload = function() {
@@ -70,7 +95,7 @@ function drawLine(x1, y1, x2, y2) {
7095
ctx.lineWidth = 5;
7196
ctx.moveTo(x1, y1);
7297
ctx.lineTo(x2, y2);
73-
ctx.stroke();
98+
// ctx.stroke();
7499
}
75100

76101
function getScaledCoords(e) {
@@ -80,50 +105,6 @@ function getScaledCoords(e) {
80105
return [x / scaleFactor, y / scaleFactor];
81106
}
82107

83-
function drawCurrentPolygon (cursorX, cursorY) {
84-
//ctx.clearRect(0, 0, canvas.width, canvas.height);
85-
ctx.drawImage(img, 0, 0);
86-
for (var i = 0; i < points.length - 1; i++) {
87-
// draw arc around each point
88-
ctx.beginPath();
89-
ctx.strokeStyle = rgb_color;
90-
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
91-
// fill with white
92-
ctx.fillStyle = 'white';
93-
ctx.fill();
94-
ctx.stroke();
95-
drawLine(points[i][0], points[i][1], points[i + 1][0], points[i + 1][1]);
96-
}
97-
98-
if ((points.length > 0 && drawMode == "polygon") || (points.length > 0 && points.length < 2 && drawMode == "line")) {
99-
ctx.beginPath();
100-
ctx.strokeStyle = rgb_color;
101-
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
102-
// fill with white
103-
ctx.fillStyle = 'white';
104-
ctx.fill();
105-
ctx.stroke();
106-
107-
if (cursorX && cursorY) {
108-
drawLine(points[points.length - 1][0], points[points.length - 1][1], cursorX, cursorY);
109-
}
110-
111-
if (points.length == 2 && drawMode == "line") {
112-
console.log("line");
113-
// draw arc around each point
114-
ctx.beginPath();
115-
ctx.strokeStyle = rgb_color;
116-
ctx.arc(points[0][0], points[0][1], 5, 0, 2 * Math.PI);
117-
// fill with white
118-
ctx.fillStyle = 'white';
119-
ctx.fill();
120-
ctx.stroke();
121-
masterPoints.push(points);
122-
points = [];
123-
}
124-
}
125-
}
126-
127108
function drawAllPolygons () {
128109
// draw all points for previous regions
129110
for (var i = 0; i < masterPoints.length; i++) {
@@ -133,6 +114,17 @@ function drawAllPolygons () {
133114
for (var j = 1; j < newpoints.length; j++) {
134115
// draw all lines
135116
drawLine(newpoints[j - 1][0], newpoints[j - 1][1], newpoints[j][0], newpoints[j][1]);
117+
118+
// fill
119+
ctx.beginPath();
120+
ctx.fillStyle = opaque_color;
121+
ctx.moveTo(newpoints[0][0], newpoints[0][1]);
122+
for (var j = 1; j < newpoints.length; j++) {
123+
ctx.lineTo(newpoints[j][0], newpoints[j][1]);
124+
}
125+
ctx.closePath();
126+
ctx.fill();
127+
ctx.stroke();
136128
}
137129
drawLine(newpoints[newpoints.length - 1][0], newpoints[newpoints.length - 1][1], newpoints[0][0], newpoints[0][1]);
138130
// draw arc around each point
@@ -145,15 +137,7 @@ function drawAllPolygons () {
145137
ctx.fill();
146138
ctx.stroke();
147139
}
148-
// fill
149-
ctx.beginPath();
150-
ctx.fillStyle = opaque_color;
151-
ctx.moveTo(newpoints[0][0], newpoints[0][1]);
152-
for (var j = 1; j < newpoints.length; j++) {
153-
ctx.lineTo(newpoints[j][0], newpoints[j][1]);
154-
}
155-
ctx.closePath();
156-
ctx.fill();
140+
157141
}
158142
}
159143

@@ -166,6 +150,11 @@ function getParentPoints () {
166150
return parentPoints;
167151
}
168152

153+
window.addEventListener('keyup', function(e) {
154+
if (e.key === 'Shift') {
155+
constrainAngles = false;
156+
}
157+
});
169158

170159
document.querySelector('#clipboard').addEventListener('click', function(e) {
171160
e.preventDefault();
@@ -198,12 +187,54 @@ canvas.addEventListener('mousemove', function(e) {
198187
// update x y coords
199188
var xcoord = document.querySelector('#x');
200189
var ycoord = document.querySelector('#y');
190+
191+
if(constrainAngles) {
192+
var lastPoint = points[points.length - 1];
193+
var dx = x - lastPoint[0];
194+
var dy = y - lastPoint[1];
195+
var angle = Math.atan2(dy, dx);
196+
var length = Math.sqrt(dx * dx + dy * dy);
197+
const snappedAngle = Math.round(angle / radiansPer45Degrees) * radiansPer45Degrees;
198+
var new_x = lastPoint[0] + length * Math.cos(snappedAngle);
199+
var new_y = lastPoint[1] + length * Math.sin(snappedAngle);
200+
x = Math.round(new_x);
201+
y = Math.round(new_y);
202+
}
203+
201204
xcoord.innerHTML = x;
202205
ycoord.innerHTML = y;
203206

204207
if (canvas.style.cursor == 'crosshair') {
205-
drawCurrentPolygon(x, y)
208+
ctx.clearRect(0, 0, canvas.width, canvas.height);
209+
ctx.drawImage(img, 0, 0);
210+
206211
drawAllPolygons();
212+
213+
for (var i = 0; i < points.length - 1; i++) {
214+
ctx.strokeStyle = rgb_color;
215+
drawLine(points[i][0], points[i][1], points[i + 1][0], points[i + 1][1]);
216+
ctx.stroke();
217+
// draw arc around each point
218+
ctx.beginPath();
219+
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
220+
// fill with white
221+
ctx.fillStyle = 'white';
222+
ctx.fill();
223+
ctx.stroke();
224+
}
225+
226+
227+
if ((points.length > 0 && drawMode == "polygon") || (points.length > 0 && points.length < 2 && drawMode == "line")) {
228+
ctx.strokeStyle = rgb_color;
229+
drawLine(points[points.length - 1][0], points[points.length - 1][1], x, y);
230+
ctx.stroke(); // new
231+
ctx.beginPath();
232+
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
233+
// fill with white
234+
ctx.fillStyle = 'white';
235+
ctx.fill();
236+
ctx.stroke();
237+
}
207238
}
208239
});
209240

@@ -309,37 +340,59 @@ canvas.addEventListener('click', function(e) {
309340
x = Math.round(x);
310341
y = Math.round(y);
311342

312-
// If starting point os clicked, we complete the polygon
313-
if (drawMode === 'polygon' && points.length > 1) {
314-
const [firstPointX, firstPointY] = points[0]
315-
const overlapDistance = 15
316-
const isXOverlaped = Math.abs(x - firstPointX) <= overlapDistance
317-
const isYOverlaped = Math.abs(y - firstPointY) <= overlapDistance
318-
if (isXOverlaped && isYOverlaped) {
319-
completeCurrentPolygon()
320-
return
343+
if(constrainAngles) {
344+
var lastPoint = points[points.length - 1];
345+
var dx = x - lastPoint[0];
346+
var dy = y - lastPoint[1];
347+
var angle = Math.atan2(dy, dx);
348+
var length = Math.sqrt(dx * dx + dy * dy);
349+
const snappedAngle = Math.round(angle / radiansPer45Degrees) * radiansPer45Degrees;
350+
var new_x = lastPoint[0] + length * Math.cos(snappedAngle);
351+
var new_y = lastPoint[1] + length * Math.sin(snappedAngle);
352+
x = Math.round(new_x);
353+
y = Math.round(new_y);
354+
}
355+
356+
if (points.length > 2 && drawMode == "polygon") {
357+
distX = x - points[0][0];
358+
distY = y - points[0][1];
359+
// stroke is 3px and centered on the circle (i.e. 1/2 * 3px) and arc radius is
360+
if(Math.sqrt(distX * distX + distY * distY) <= 6.5) {
361+
closePath();
362+
return;
321363
}
322364
}
323365

324366
points.push([x, y]);
325367

326-
// if line mode and two points have been drawn, add to masterPoints
327-
if (drawMode == 'line' && points.length == 2) {
328-
masterPoints.push(points);
329-
points = [];
330-
}
331-
332368
ctx.beginPath();
333369
ctx.strokeStyle = rgb_color;
334-
// add rgb_color to masterColors
335-
336-
if (masterColors.length == 0) {
337-
masterColors.push(rgb_color);
370+
ctx.arc(x, y, 5, 0, 2 * Math.PI);
371+
// fill with white
372+
ctx.fillStyle = 'white';
373+
ctx.fill();
374+
ctx.stroke();
375+
376+
if(drawMode == "line" && points.length == 2) {
377+
closePath();
378+
}
379+
else {
380+
ctx.beginPath();
381+
ctx.strokeStyle = rgb_color;
338382
}
383+
384+
// ctx.arc(x, y, 155, 0, 2 * Math.PI);
385+
// concat all points into one array
386+
var parentPoints = [];
339387

340-
ctx.arc(x, y, 155, 0, 2 * Math.PI);
388+
for (var i = 0; i < masterPoints.length; i++) {
389+
parentPoints.push(masterPoints[i]);
390+
}
391+
// add "points"
392+
if(points.length > 0) {
393+
parentPoints.push(points);
394+
}
341395

342-
var parentPoints = getParentPoints();
343396
writePoints(parentPoints);
344397
});
345398

@@ -374,8 +427,9 @@ document.addEventListener('keydown', function(e) {
374427
})
375428

376429
function draw () {
377-
drawCurrentPolygon()
430+
378431
drawAllPolygons()
432+
drawCurrentPolygon()
379433
var parentPoints = getParentPoints()
380434
writePoints(parentPoints)
381435
}
@@ -415,6 +469,7 @@ function clearAll() {
415469

416470
points = []
417471
masterPoints = []
472+
masterColors = []
418473
document.querySelector('#json').innerHTML = ''
419474
document.querySelector('#python').innerHTML = ''
420475
}
@@ -466,6 +521,10 @@ window.addEventListener('keydown', function(e) {
466521
undo()
467522
}
468523

524+
if (e.key === 'Shift') {
525+
constrainAngles = true;
526+
}
527+
469528
if (e.key === 'Escape') {
470529
discardCurrentPolygon()
471530
}

0 commit comments

Comments
 (0)