in gsoc2022/seagrid-rich-client/molview/src/js/lib/GLmol.js [2507:2708]
GLmol.prototype.render2d = function()
{
var ctx = this.canvas2d[0].getContext("2d");
this.scene.updateMatrixWorld();
ctx.clearRect(0, 0, this.WIDTH, this.HEIGHT);
ctx.fillStyle = "rgba(" + (this.bgColor >> 16) + "," + (this.bgColor >> 8 & 0xFF)
+ "," + (this.bgColor & 0xFF) + "," + this.bgAlpha + ")";
ctx.fillRect(0, 0, this.WIDTH, this.HEIGHT);
ctx.save();
ctx.translate(this.WIDTH / 2, this.HEIGHT / 2);
ctx.scale(this.zoom2D || 1, this.zoom2D || 1);
var lineWidth = 0.02;
var mvMat = new THREE.Matrix4();
mvMat.multiply(this.camera.matrixWorldInverse, this.modelGroup.matrixWorld);
var PI2 = Math.PI * 2;
var atoms = this.atoms;
//transform coordinates
for(var i = 0; i < this.atoms.length; i++)
{
var atom = atoms[i];
if(atom == undefined) continue;
if(atom.screen == undefined) atom.screen = new THREE.Vector3;
atom.screen.set(atom.x, atom.y, atom.z);
/*p*/
mvMat.multiplyVector3(atom.screen);
if(!this.webglFailed) atom.screen.y *= -1;//plus direction of y-axis: up in OpenGL, down in Canvas
}
//create draw stack
if(this.canvasdrawStack.length == 0)
{
for(var i = 0; i < atoms.length; i++)
{
var atom = atoms[i];
if(atom == undefined) continue;
var part = {
i: i,
screen: atom.screen,
color: "rgb(" + (atom.color >> 16) + "," + (atom.color >> 8 & 255) + "," + (atom.color & 255) + ")",
r: this.canvasVDW ? GLmolVDWRadii[atom.elem] : this.canvasAtomRadius
};
//cache arc
part.arc = [];
if(part.r > 0)
{
var detail = this.canvasDetail;
for(var v = 0; v < detail; v++)
{
part.arc.push([ part.r * Math.cos(PI2 / detail * v),
part.r * Math.sin(PI2 / detail * v) ]);
}
}
//add bonds
part.bonds = [];
for(var j = 0; j < atom.bonds.length; j++)
{
var atom2 = atoms[atom.bonds[j]];
if(atom2 == undefined) continue;
part.bonds.push(atom.bonds[j]);
}
this.canvasdrawStack.push(part);
}
}
//sort draw stack
this.canvasdrawStack.sort(function(a, b)
{
return a.screen.z - b.screen.z;
});
//prepare
for(var i = 0; i < this.canvasdrawStack.length; i++)
{
atoms[this.canvasdrawStack[i].i].zIndex = i;
}
//draw
for(var i = 0; i < this.canvasdrawStack.length; i++)
{
var part = this.canvasdrawStack[i];
//draw atom black body
if(!this.isDragging && part.r > 0)
{
ctx.save();
ctx.translate(part.screen.x, part.screen.y);
ctx.fillStyle = "#000000";
ctx.lineWidth = lineWidth;
ctx.beginPath();
var mult = (part.r + lineWidth) / part.r;
for(var v = 0; v < part.arc.length; v++)
{
if(v == 0) ctx.moveTo(mult * part.arc[v][0], mult * part.arc[v][1]);
else ctx.lineTo(mult * part.arc[v][0], mult * part.arc[v][1]);
}
ctx.closePath();
ctx.fill();
ctx.restore();
//draw bonds blackbody
if(!this.canvasVDW)
{
for(var j = 0; j < part.bonds.length; j++)
{
var atom = atoms[part.bonds[j]];
if(atom.screen.z > part.screen.z ||
(atom.screen.z == part.screen.z && atom.zIndex > atoms[part.i].zIndex))
{
var cx = (part.screen.x + atom.screen.x) / 2;
var cy = (part.screen.y + atom.screen.y) / 2;
ctx.lineWidth = ((this.isDragging || this.canvasLine) ?
1 / this.zoom2D : this.canvasBondWidth) + lineWidth * 2;
ctx.strokeStyle = "#000000";
ctx.beginPath();
ctx.moveTo(part.screen.x, part.screen.y);
ctx.lineTo(cx, cy);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(atom.screen.x, atom.screen.y);
ctx.lineTo(cx, cy);
ctx.closePath();
ctx.stroke();
}
}
}
}
//draw colored bonds
if(!this.canvasVDW || this.isDragging)
{
for(var j = 0; j < part.bonds.length; j++)
{
var atom = atoms[part.bonds[j]];
var atomColor = this.canvasdrawStack[atoms[part.bonds[j]].zIndex].color;
if(atom.screen.z > part.screen.z ||
(atom.screen.z == part.screen.z && atom.zIndex > atoms[part.i].zIndex))
{
var cx = (part.screen.x + atom.screen.x) / 2;
var cy = (part.screen.y + atom.screen.y) / 2;
ctx.lineWidth = (this.isDragging || this.canvasLine) ?
1 / this.zoom2D : this.canvasBondWidth;
ctx.strokeStyle = part.color;
ctx.beginPath();
ctx.moveTo(part.screen.x, part.screen.y);
ctx.lineTo(cx, cy);
ctx.closePath();
ctx.stroke();
ctx.strokeStyle = atomColor;
ctx.beginPath();
ctx.moveTo(atom.screen.x, atom.screen.y);
ctx.lineTo(cx, cy);
ctx.closePath();
ctx.stroke();
}
}
}
//draw atom
if(!this.isDragging && part.r > 0)
{
ctx.save();
ctx.translate(part.screen.x, part.screen.y);
ctx.fillStyle = part.color;
ctx.beginPath();
for(var v = 0; v < part.arc.length; v++)
{
if(v == 0) ctx.moveTo(part.arc[v][0], part.arc[v][1]);
else ctx.lineTo(part.arc[v][0], part.arc[v][1]);
}
ctx.closePath();
ctx.fill();
ctx.restore();
}
}
ctx.restore();
};