Skip to content

Commit eaa052a

Browse files
authored
Merge pull request #111 from martinRenou/sizing_logic
CanvasView: Make the canvas the main element
2 parents a97d781 + 132d954 commit eaa052a

File tree

2 files changed

+32
-49
lines changed

2 files changed

+32
-49
lines changed

examples/drag_and_drop_example.ipynb

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,9 @@
22
"cells": [
33
{
44
"cell_type": "code",
5-
"execution_count": 96,
5+
"execution_count": null,
66
"metadata": {},
7-
"outputs": [
8-
{
9-
"data": {
10-
"application/vnd.jupyter.widget-view+json": {
11-
"model_id": "00466ac5fda94b54807244ade58dd848",
12-
"version_major": 2,
13-
"version_minor": 0
14-
},
15-
"text/plain": [
16-
"Canvas(height=600, width=600)"
17-
]
18-
},
19-
"metadata": {},
20-
"output_type": "display_data"
21-
}
22-
],
7+
"outputs": [],
238
"source": [
249
"from ipycanvas import Canvas, hold_canvas\n",
2510
"\n",
@@ -120,13 +105,6 @@
120105
"\n",
121106
"canvas"
122107
]
123-
},
124-
{
125-
"cell_type": "code",
126-
"execution_count": null,
127-
"metadata": {},
128-
"outputs": [],
129-
"source": []
130108
}
131109
],
132110
"metadata": {
@@ -145,7 +123,7 @@
145123
"name": "python",
146124
"nbconvert_exporter": "python",
147125
"pygments_lexer": "ipython3",
148-
"version": "3.7.3"
126+
"version": "3.8.3"
149127
}
150128
},
151129
"nbformat": 4,

src/widget.ts

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -331,28 +331,25 @@ class CanvasModel extends DOMWidgetModel {
331331
export
332332
class CanvasView extends DOMWidgetView {
333333
render() {
334-
this.canvas = document.createElement('canvas');
335-
336-
this.el.appendChild(this.canvas);
337-
this.ctx = getContext(this.canvas);
334+
this.ctx = getContext(this.el);
338335

339336
this.resizeCanvas();
340337
this.model.on_some_change(['width', 'height'], this.resizeCanvas, this);
341338

342-
this.canvas.addEventListener('mousemove', { handleEvent: this.onMouseMove.bind(this) });
343-
this.canvas.addEventListener('mousedown', { handleEvent: this.onMouseDown.bind(this) });
344-
this.canvas.addEventListener('mouseup', { handleEvent: this.onMouseUp.bind(this) });
345-
this.canvas.addEventListener('mouseout', { handleEvent: this.onMouseOut.bind(this) });
346-
this.canvas.addEventListener('touchstart', { handleEvent: this.onTouchStart.bind(this) });
347-
this.canvas.addEventListener('touchend', { handleEvent: this.onTouchEnd.bind(this) });
348-
this.canvas.addEventListener('touchmove', { handleEvent: this.onTouchMove.bind(this) });
349-
this.canvas.addEventListener('touchcancel', { handleEvent: this.onTouchCancel.bind(this) });
339+
this.el.addEventListener('mousemove', { handleEvent: this.onMouseMove.bind(this) });
340+
this.el.addEventListener('mousedown', { handleEvent: this.onMouseDown.bind(this) });
341+
this.el.addEventListener('mouseup', { handleEvent: this.onMouseUp.bind(this) });
342+
this.el.addEventListener('mouseout', { handleEvent: this.onMouseOut.bind(this) });
343+
this.el.addEventListener('touchstart', { handleEvent: this.onTouchStart.bind(this) });
344+
this.el.addEventListener('touchend', { handleEvent: this.onTouchEnd.bind(this) });
345+
this.el.addEventListener('touchmove', { handleEvent: this.onTouchMove.bind(this) });
346+
this.el.addEventListener('touchcancel', { handleEvent: this.onTouchCancel.bind(this) });
350347

351348
this.updateCanvas();
352349
}
353350

354351
clear() {
355-
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
352+
this.ctx.clearRect(0, 0, this.el.width, this.el.height);
356353
}
357354

358355
updateCanvas() {
@@ -361,8 +358,8 @@ class CanvasView extends DOMWidgetView {
361358
}
362359

363360
protected resizeCanvas() {
364-
this.canvas.setAttribute('width', this.model.get('width'));
365-
this.canvas.setAttribute('height', this.model.get('height'));
361+
this.el.setAttribute('width', this.model.get('width'));
362+
this.el.setAttribute('height', this.model.get('height'));
366363
}
367364

368365
private onMouseMove(event: MouseEvent) {
@@ -402,14 +399,19 @@ class CanvasView extends DOMWidgetView {
402399
}
403400

404401
protected getCoordinates(event: MouseEvent | Touch) {
405-
const rect = this.canvas.getBoundingClientRect();
406-
const x = event.clientX - rect.left;
407-
const y = event.clientY - rect.top;
402+
const rect = this.el.getBoundingClientRect();
403+
404+
const x = this.el.width * (event.clientX - rect.left) / rect.width;
405+
const y = this.el.height * (event.clientY - rect.top) / rect.height;
408406

409407
return { x, y };
410408
}
411409

412-
canvas: HTMLCanvasElement;
410+
get tagName(): string {
411+
return 'canvas';
412+
}
413+
414+
el: HTMLCanvasElement;
413415
ctx: CanvasRenderingContext2D;
414416

415417
model: CanvasModel;
@@ -513,17 +515,20 @@ class MultiCanvasView extends DOMWidgetView {
513515
// The following ts-ignore is needed due to ipywidgets's implementation
514516
// @ts-ignore
515517
return this.create_child_view(canvasModel).then((canvasView: CanvasView) => {
516-
canvasView.el.style.zIndex = index;
518+
const canvasContainer = document.createElement('div');
519+
520+
canvasContainer.style.zIndex = index.toString();
517521

518522
if (index == 0) {
519523
// This will enforce the container to respect the children size.
520-
canvasView.el.style.position = 'relative';
521-
canvasView.el.style.float = 'left';
524+
canvasContainer.style.position = 'relative';
525+
canvasContainer.style.float = 'left';
522526
} else {
523-
canvasView.el.style.position = 'absolute';
527+
canvasContainer.style.position = 'absolute';
524528
}
525529

526-
this.container.appendChild(canvasView.el);
530+
canvasContainer.appendChild(canvasView.el);
531+
this.container.appendChild(canvasContainer);
527532

528533
return canvasView;
529534
});

0 commit comments

Comments
 (0)