Drawing on Canvases

On the last page, we covered overriding abstract methods to implement Canvas functionality by handling input events. There are more abstract methods in the ChemDoodle Web Components library, and information on them can be found in the API. We will, however, cover one last abstract Canvas function, drawChildExtras(), which will allow you to draw on top of a canvas.

The drawChildExtras() function can be associated with any 2D canvas (so no WebGL yet). The function is sent a drawing context parameter that you will use to draw on top of the canvas. This function is called after the molecule has been drawn, so any graphics added will cover the molecule. Drawing underneath the molecule or specifically changing how molecules are drawn (without using the VisualSpecifications object), is much more complex and will require you to alter the ChemDoodle Web Components library.

If you have experience with drawing graphics in other toolkits, such as Java Swing, then you will feel right at home with HTML5 <canvas> programming. You can learn all about drawing graphics at the following documentation pages:

In this example, we will implement the drawChildExtras() function for a ViewerCanvas. We will load a structure of the toxic pesticide, DDT, into the canvas and then draw a warning on top of it. The source is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
  var viewer = new ChemDoodle.ViewerCanvas('viewer', 200, 200);
  viewer.drawChildExtras = function(ctx){
    //draw the symbol
    var radius = this.width/2-40;
    var diagonal = radius*Math.sin(Math.PI/4);
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 10;
    ctx.beginPath();
    ctx.moveTo(this.width/2-diagonal, this.height/2-diagonal);
    ctx.lineTo(this.width/2+diagonal, this.height/2+diagonal);
    ctx.stroke();
    ctx.beginPath();
    ctx.arc(this.width/2, this.height/2, radius, 0, Math.PI * 2, false);
    ctx.stroke();
    //draw the label
    ctx.fillStyle = 'red';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.font = 'bold 20px sans-serif';
    ctx.fillText('DDT is toxic!', this.width/2, this.height-5);
  }
  viewer.loadMolecule(ChemDoodle.readMOL('Molecule Name\n  CHEMDOOD01101120073D 0   0.00000     0.00000     0\n[Insert Comment Here]\n 19 20  0  0  0  0  0  0  0  0  1 V2000\n    0.0000    2.0000    0.0000  Cl 0  0  0  0  0  0  0  0  0  0  0  0\n   -0.0000    1.0000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n    1.0000    1.0000    0.0000  Cl 0  0  0  0  0  0  0  0  0  0  0  0\n   -1.0000    1.0001    0.0000  Cl 0  0  0  0  0  0  0  0  0  0  0  0\n   -0.0000    0.0001    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n   -0.8660   -0.4999    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n    0.8660   -0.5000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n   -1.7321    0.0000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n   -0.8660   -1.5000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n    1.7321   -0.0000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n    0.8660   -1.5000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n   -2.5981   -0.5000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n   -1.7320   -2.0000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n    2.5981   -0.5000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n    1.7320   -2.0000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n   -2.5981   -1.4999    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n    2.5981   -1.5000    0.0000   C 0  0  0  0  0  0  0  0  0  0  0  0\n   -3.4641   -1.9999    0.0000  Cl 0  0  0  0  0  0  0  0  0  0  0  0\n    3.4641   -2.0000    0.0000  Cl 0  0  0  0  0  0  0  0  0  0  0  0\n  1  2  1  0  0  0  0\n  3  2  1  0  0  0  0\n  4  2  1  0  0  0  0\n 19 17  1  0  0  0  0\n 18 16  1  0  0  0  0\n  5  6  1  0  0  0  0\n  5  7  1  0  0  0  0\n  5  2  1  0  0  0  0\n  6  8  2  0  0  0  0\n  6  9  1  0  0  0  0\n  7 11  2  0  0  0  0\n  7 10  1  0  0  0  0\n 11 15  1  0  0  0  0\n  8 12  1  0  0  0  0\n 10 14  2  0  0  0  0\n  9 13  2  0  0  0  0\n 12 16  2  0  0  0  0\n 15 17  2  0  0  0  0\n 13 16  1  0  0  0  0\n 14 17  1  0  0  0  0\nM  END'));
</script>

Using the ChemDoodle Web Components library, you can create any desired graphics for your scientific websites. As can be seen, this is only a static image, but combined with input events and animations, you can create much more advanced interfaces. It should be noted that setting the drawChildExtras() function does not repaint the canvas. So you will need to manually call the Canvas.repaint() function if you want a canvas to update. In the example above, the loadMolecule() function automatically calls the repaint.

Continue to Extending Canvases →