1、原生js
kekule可以单独画一张图片,也可以使用化学小工具渲染一个可以交互的视窗,使用化学小工具还可以对分子进行编辑。
首先将smiles转换成kekule.js可以使用的mol格式(两种方法)
// 第一种方法,使用kekule.js转换,不推荐
function smilesToKekule(smiles, callback) {
Kekule.OpenBabel.enable(function(error){
if (!error)
{
// var smiles = 'c1ccccc1';
var mol = Kekule.IO.loadFormatData(smiles, 'smi');
// the molecule loaded from SMILES by OpenBabel has no coordinates for atoms, and you can generate them manually
var generator = new Kekule.Calculator.ObStructure2DGenerator();
generator.setSourceMol(mol);
generator.executeSync(function() {
var newMol = generator.getGeneratedMol();
// console.log(newMol);
callback(newMol);
});
}
});
}
/**
* 使用RDkit.js 将 Smiles 转 MOL2000, 前提是需要下载一个RDkit.js
*/
function RDKitSmilesToMOL2000(smiles) {
var mol = RDKitModule.get_mol(smiles);
return mol.get_kekule_form();
}
单独画一张静态的图片:
这个案例可以在官网看到:Drawing Molecule — Kekule Tutorial 2023.01 documentation
var renderType = Kekule.Render.RendererType.R2D//R3D // 可以选择画3d还是2d的图片
// 选择一个父容器,将图片画到里面
var parentElem = document.getElementById('parent');
// 清除之前画的图片
Kekule.DomUtils.clearChildContent(parentElem);
// 创建画笔,绑定要画的分子(mol格式可以通过RDkit将smiles转换成mol格式)
RDKitSmilesToMOL2000('OC', mol => {
var painter = new Kekule.Render.ChemObjPainter(renderType, mol);
// 获取父容器的宽高
var dim = Kekule.HtmlElementUtils.getElemOffsetDimension(parentElem); // get width/height of parent element
var context = painter.createContext(parentElem, dim.width, dim.height); // create context fulfill parent element
// 开画
painter.draw(context, {'x': dim.width / 2, 'y': dim.height / 2});
})
渲染一个3d视窗
官方案例:Chem Viewer Widget — Kekule Tutorial 2023.01 documentation
function molRender3DView(mol) {
// 可以交互的3D视图
var parentElem = document.getElementById("example-3D-output");
// 清除之前的视窗
Kekule.DomUtils.clearChildContent(parentElem);
var chemViewer = new Kekule.ChemWidget.Viewer(document);
chemViewer.setDimension(paramsObj.width, paramsObj.height);
chemViewer.setRenderType(Kekule.Render.RendererType.R3D);
chemViewer.appendToElem(document.getElementById('example-3D-output')).setChemObj(mol);
setInterval(() => {
// 沿着y轴旋转
// var dx = Math.PI / 2, dy = Math.PI /3, dz = Math.PI / 4;
// rotate object by 90, 60 and 45 degrees on X/Y/Z axis
chemViewer.rotate3DBy(0, 0.03, 0);
}, 100)
}
2、vue
kekule.js对vue的支持并不是很好,官方的很多案例在vue环境上会报错,只能通过别的途径渲染,或者可以尝试使用kekule-vue,作者目前还没有尝试过。
注意安装kekule.js的同时需要安装three.js,这样才能渲染3d视图
安装kekule.js
vue中使用npm安装kekule.js项目启动后导入的kekule对象是空对象,没法使用,如果是webpack可以通过设置解决,如果是vue-cli我尝试使用的配置无法生效,所以建议使用script标签导入。
webpack的设置
详细的关于这个问题的讨论在github上也可以看到:Using Kekule npm module with Webpack does not load Kekule properly. · Issue #36 · partridgejiang/Kekule.js · GitHub
optimization: {
...
minimizer: [
...
new TerserPlugin({
...
mangle: {
safari10: true, // line 234
reserved: ['$super', '$origin'] // add this line of code
}
...
})
...
]
...
}
推荐在public/index.html中使用script标签引入
注意kekule.css可以下载在本地引用,但是kekule.js必须用线上的资源,使用国内的镜像资源可以避免访问国外npm资源加载缓慢。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
...
<link rel="stylesheet" type="text/css" href="<%= BASE_URL %>3Dviewer/kekule.css" />
<script src="https://npm.akass.cn/kekule/dist/kekule.min.js" exclude></script>
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
</head>
<body>
<div id="app"></div>
</body>
</html>
安装three.js并与kekule.js关联
three.js可以通过npm安装
npm i three
与kekule关联,可以在app.vue中关联(或许),但是我是在渲染的组件内关联的,可以多尝试一下。
import * as THREE from 'three';
...
created() {
Kekule.externalResourceManager.register('three.js', THREE);
},
渲染3d视窗
在vue中渲染3d视图不能使用官网提供的代码,会导致报错,下面的代码可以完成渲染任务。
function molRender3DView(mol) {
// 父容器
var parentElem = document.getElementById("example-3D-output");
// 清除之前渲染的3d视图
Kekule.DomUtils.clearChildContent(parentElem);
// 创建新的视图
var chemViewer = new Kekule.ChemWidget.Viewer(document);
chemViewer.setDimension(paramsObj.width, paramsObj.height);
chemViewer.setRenderType(Kekule.Render.RendererType.R3D);
chemViewer.appendToElem(document.getElementById('example-3D-output')).setChemObj(mol);
setInterval(() => {
// 沿着y轴旋转
// var dx = Math.PI / 2, dy = Math.PI /3, dz = Math.PI / 4;
// rotate object by 90, 60 and 45 degrees on X/Y/Z axis
chemViewer.rotate3DBy(0, 0.03, 0);
}, 100)
}