Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding instructions, ESC and Ctrl-Z functionality and some bug fixes. #10

Merged
merged 7 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ To use PolygonZone, open up the [PolygonZone web application](https://roboflow.g
4. Continue to draw as many polygons as you need.
5. Copy the NumPy array or JSON object that contains the coordinates of the polygons you have drawn.

You can zoom in and out of an image using the mouse wheel or a laptop track pad.
## Functionalities
- You can zoom in and out of an image using the mouse wheel or a laptop track pad.
- You can undo the last point pressing Ctrl/Cmd+Z
- You can discard the last unsaved polygon pressing Esc

## Contributing 🤝

Expand Down
23 changes: 22 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,35 @@ <h1>Draw points to create polygon coordinates</h1>
</div>
</div>
<div class="right">
<div class="how-to">
<h2>How to use</h2>
<ol class="ta-left">
<li>Drop an image to the indicated area</li>
<li>Select the desired mode: Press <kbd>L</kbd> to draw a line, or <kbd>P</kbd> to draw a polygon</li>
<li>Start creating your polygon, clicking in the desired points of the image</li>
<li>If in polygon mode, press <kbd>ENTER</kbd> to finish the polygon</li>
<li>Repeat steps 2 - 4 as many times as you want</li>
<li>To finish, copy the numpy points to your clipboard</li>
</ol>
</div>
<div class="shortcuts">
<h2>Keyboard shortcuts</h2>
<ul class="ta-left">
<li><kbd>L</kbd>: Switch to line drawing mode</li>
<li><kbd>P</kbd>: Swicth to polygon drawing mode</li>
<li><kbd>Enter</kbd>: If you drawing a polygon, end the polygon</li>
<li><kbd>Esc</kbd>: When drawing, clear the current polygon</li>
<li><kbd>Ctrl(Cmd)-Z</kbd>: Undo the last point</li>
</ul>
</div>
<h2>NumPy Points</h2>
<p>Copy the points below into your Python code.</p>
<a href="" id="clipboard" class="widgetButton">Copy Python to Clipboard</a>
<pre id="python">
<code>
</code>
</pre>
<div class="show_normalized" style="margin-bottom: 25px;">
<div class="show_normalized mb-3">
<label for="normalize_checkbox">Show Normalized Points from 0-1</label>
<input type="checkbox" id="normalize_checkbox" name="normalize_checkbox" value="normalize_checkbox">
</div>
Expand Down
178 changes: 92 additions & 86 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,50 @@ function getScaledCoords(e) {
return [x / scaleFactor, y / scaleFactor];
}

function drawCurrentPolygon (cursorX, cursorY) {
//ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
for (var i = 0; i < points.length - 1; i++) {
// draw arc around each point
ctx.beginPath();
ctx.strokeStyle = rgb_color;
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
// fill with white
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();
drawLine(points[i][0], points[i][1], points[i + 1][0], points[i + 1][1]);
}

if ((points.length > 0 && drawMode == "polygon") || (points.length > 0 && points.length < 2 && drawMode == "line")) {
ctx.beginPath();
ctx.strokeStyle = rgb_color;
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
// fill with white
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();

if (cursorX && cursorY) {
drawLine(points[points.length - 1][0], points[points.length - 1][1], cursorX, cursorY);
}

if (points.length == 2 && drawMode == "line") {
console.log("line");
// draw arc around each point
ctx.beginPath();
ctx.strokeStyle = rgb_color;
ctx.arc(points[0][0], points[0][1], 5, 0, 2 * Math.PI);
// fill with white
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();
masterPoints.push(points);
points = [];
}
}
}

function drawAllPolygons () {
// draw all points for previous regions
for (var i = 0; i < masterPoints.length; i++) {
Expand Down Expand Up @@ -124,6 +168,15 @@ function drawAllPolygons () {
}
}

function getParentPoints () {
var parentPoints = [];
for (var i = 0; i < masterPoints.length; i++) {
parentPoints.push(masterPoints[i]);
}
parentPoints.push(points);
return parentPoints;
}

function clearall() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
Expand Down Expand Up @@ -180,83 +233,25 @@ canvas.addEventListener('mousemove', function(e) {
ycoord.innerHTML = y;

if (canvas.style.cursor == 'crosshair') {
//ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
for (var i = 0; i < points.length - 1; i++) {
// draw arc around each point
ctx.beginPath();
ctx.strokeStyle = rgb_color;
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
// fill with white
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();
drawLine(points[i][0], points[i][1], points[i + 1][0], points[i + 1][1]);
}
if ((points.length > 0 && drawMode == "polygon") || (points.length > 0 && points.length < 2 && drawMode == "line")) {
ctx.beginPath();
ctx.strokeStyle = rgb_color;
ctx.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI);
// fill with white
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();
drawLine(points[points.length - 1][0], points[points.length - 1][1], x, y);

if (points.length == 2 && drawMode == "line") {
console.log("line");
// draw arc around each point
ctx.beginPath();
ctx.strokeStyle = rgb_color;
ctx.arc(points[0][0], points[0][1], 5, 0, 2 * Math.PI);
// fill with white
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();
masterPoints.push(points);
points = [];
}
}
var parentPoints = [];

for (var i = 0; i < masterPoints.length; i++) {
parentPoints.push(masterPoints[i]);
}
parentPoints.push(points);

drawCurrentPolygon(x, y)
drawAllPolygons();
}
});



window.addEventListener('keydown', function(e) {
e.stopImmediatePropagation()
let validKey = false

if (e.key === 'Enter') {
validKey = true
canvas.style.cursor = 'default';
// remove line drawn by mouseover
// ctx.clearRect(0, 0, canvas.width, canvas.height);
// join the dots
drawLine(points[0][0], points[0][1], points[points.length - 1][0], points[points.length - 1][1]);
// fill polygon with color
if (drawMode == 'polygon') {
ctx.beginPath();
ctx.moveTo(points[0][0], points[0][1]);
ctx.fillStyle = opaque_color;
for (var i = 1; i < points.length; i++) {
ctx.lineTo(points[i][0], points[i][1]);
}
ctx.closePath();
ctx.fill();
// draw line connecting last two points
}

// save current polygon points
masterPoints.push(points);
// draw arc around last point
ctx.beginPath();
ctx.strokeStyle = rgb_color;
ctx.arc(points[points.length - 1][0], points[points.length - 1][1], 5, 0, 2 * Math.PI);
// fill with white
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke();
points = [];

// dont choose a color that has already been chosen
var remaining_choices = color_choices.filter(function(x) {
return !masterColors.includes(x);
Expand All @@ -267,9 +262,25 @@ window.addEventListener('keydown', function(e) {
}

rgb_color = remaining_choices[Math.floor(Math.random() * remaining_choices.length)];

masterColors.push(rgb_color);
}

if (e.key === 'Escape') {
validKey = true
points = []
}

if (e.key === 'z' && (e.ctrlKey || e.metaKey)) {
validKey = true
points.pop()
}

if (validKey) {
drawCurrentPolygon()
drawAllPolygons();
var parentPoints = getParentPoints();
writePoints(parentPoints);
}
});

canvas.addEventListener('drop', function(e) {
Expand Down Expand Up @@ -327,6 +338,15 @@ function writePoints(parentPoints) {
parentPoints = normalized;
}

// clean empty points
parentPoints = parentPoints.filter(points => !!points.length);

if (!parentPoints.length) {
document.querySelector('#python').innerHTML = '';
document.querySelector('#json').innerHTML;
return;
}

// create np.array list
var code_template = `
[
Expand All @@ -339,6 +359,7 @@ ${points.map(function(point) {
}).join(',')}
]
`;

document.querySelector('#python').innerHTML = code_template;

var json_template = `
Expand Down Expand Up @@ -378,28 +399,13 @@ canvas.addEventListener('click', function(e) {
}

ctx.arc(x, y, 155, 0, 2 * Math.PI);
// concat all points into one array
var parentPoints = [];

for (var i = 0; i < masterPoints.length; i++) {
parentPoints.push(masterPoints[i]);
}
// add "points"
parentPoints.push(points);

var parentPoints = getParentPoints();
writePoints(parentPoints);
});

document.querySelector('#normalize_checkbox').addEventListener('change', function(e) {
showNormalized = e.target.checked;
// normalize all
var parentPoints = [];

for (var i = 0; i < masterPoints.length; i++) {
parentPoints.push(masterPoints[i]);
}

parentPoints.push(points);

var parentPoints = getParentPoints();
writePoints(parentPoints);
});
21 changes: 21 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,24 @@ pre {
footer {
margin-top: 20px;
}

li {
margin-bottom: 4px;
}

/* Helpers */
.ta-left {
text-align: left;
}

.mb-1 {
margin-bottom: 8px;
}

.mb-2 {
margin-bottom: 16px;
}

.mb-3 {
margin-bottom: 24px;
}
Loading