This notebook implements polygon editor which illustrates combining mouse event modalities with reference frames.
Click to start the polygon.
Type "." to drop a new vertex.
Click again to close the polygon.
Press the reset button to play again.
from jp_doodle import dual_canvas
from IPython.display import display
poly_edit = dual_canvas.SnapshotCanvas("editted polygon.png", width=320, height=320)
poly_edit.display_all()
poly_edit.js_init("""
// Add a light backdrop
var background = element.rect({name: "background", x:-15, y:-15, w:370, h:370, color:"#def"})
// Edit in cartesian area [-1:1] x [-1:1]
let frame = element.frame_region(20, 20, 300, 300,
-1, -1, 1, 1);
// Show axes for reference
frame.lower_left_axes({
x_anchor: 0,
y_anchor: 0,
tick_line_config: {color: "green"},
tick_text_config: {color: "blue"},
max_tick_count: 5
})
// Helpful informative text.
var info_div = $("<div>Useful information should show up here eventually.</div>").appendTo(element);
// Store polygon points here.
var polygon_points = [];
// Convenience to add a point to the polygon
var push_location = function (location) {
polygon_points.push([location.x, location.y]);
}
var poly = null;
var circ = null;
var start_polygon = function () {
debugger;
// wait for a mouse click to define the first point of the polygon.
frame.forget_objects(["poly", "circ"]); // forget graphical objects if they exist.
element.reset_events();
polygon_points = [];
// The graphical polygon to edit
poly = frame.polygon({
name: "poly", points: polygon_points, color:"red",
close:false, fill:false, lineWidth:5, events:false});
// A circle to track the mouse
circ = frame.circle({name: "circ", x:0, y:0, r:5, color:"magenta", hide:true, events:false});
var track_mouse = function(event) {
var frame_location = frame.event_model_location(event);
circ.change({x: frame_location.x, y: frame_location.y, hide: false});
};
background.on("mousemove", track_mouse);
var start_click = function(event) {
debugger
var frame_location = frame.event_model_location(event);
// store the initial point and a mouse tracking point
polygon_points = [];
push_location(frame_location); // first vertex
push_location(frame_location); // mouse tracking vertex
// switch modes to continue polygon after a short delay in case of duplicate mouse clicks
element.reset_events();
setTimeout(continue_polygon, 100);
};
background.on("click", start_click);
info_div.html("<div>Click to start polygon.</div>")
};
var continue_polygon = function () {
// space bar drops a point, mouse click completes the polygon
element.reset_events();
var track_mouse = function(event) {
// track the cursor
var frame_location = frame.event_model_location(event);
circ.change({x: frame_location.x, y: frame_location.y, hide: false});
// change the last polygon point to track the cursor
polygon_points.pop();
push_location(frame_location); // replace mouse tracking vertex
poly.change({points: polygon_points});
// set the focus to the canvas so the canvas can recieve keyboard events.
element.focus_canvas();
};
background.on("mousemove", track_mouse);
var dot_drops_point = function (event) {
// When the user hits "." drop a new vertex on the polygon
const dot_key_code = 190;
if (event.keyCode == dot_key_code) {
// 'keydown' events do not have locations. Duplicate the tracking vertex.
var vertex = polygon_points.pop();
polygon_points.push(vertex); // dropped location
polygon_points.push(vertex); // mouse tracking vertex
poly.change({points: polygon_points});
}
}
background.on("keydown", dot_drops_point);
var stop_click = function(event) {
// When the user "clicks" in "continue" mode, complete the polygon.
var frame_location = frame.event_model_location(event);
// switch modes to continue polygon
circ.change({hide: true});
// change the last polygon point to track the cursor
polygon_points.pop(); // remove previous mouse tracking vertex
polygon_points.push([frame_location.x, frame_location.y]);
poly.change({points: polygon_points, close: true});
element.reset_events();
info_div.html("<div>Polygon complete.</div>")
};
background.on("click", stop_click);
info_div.html("<div>Type '.' to add a vertex. Click to complete polygon.</div>");
};
//element.invisible_canvas.show();
start_polygon();
$("<button>Restart</button>")
.appendTo(element)
.click(start_polygon);
""")
Failed to display Jupyter Widget of type Tab
.
If you're reading this message in Jupyter Notebook or JupyterLab, it may mean that the widgets JavaScript is still loading. If this message persists, it likely means that the widgets JavaScript library is either not installed or not enabled. See the Jupyter Widgets Documentation for setup instructions.
If you're reading this message in another notebook frontend (for example, a static rendering on GitHub or NBViewer), it may mean that your frontend doesn't currently support widgets.