1、原生js
kekule可以單獨畫一張圖片,也可以使用化學(xué)小工具渲染一個可以交互的視窗,使用化學(xué)小工具還可以對分子進行編輯。
首先將smiles轉(zhuǎn)換成kekule.js可以使用的mol格式(兩種方法)
// 第一種方法,使用kekule.js轉(zhuǎn)換,不推薦
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 轉(zhuǎn) MOL2000, 前提是需要下載一個RDkit.js
*/
function RDKitSmilesToMOL2000(smiles) {
var mol = RDKitModule.get_mol(smiles);
return mol.get_kekule_form();
}
單獨畫一張靜態(tài)的圖片:
這個案例可以在官網(wǎng)看到: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);
// 創(chuàng)建畫筆,綁定要畫的分子(mol格式可以通過RDkit將smiles轉(zhuǎn)換成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軸旋轉(zhuǎn)
// 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環(huán)境上會報錯,只能通過別的途徑渲染,或者可以嘗試使用kekule-vue,作者目前還沒有嘗試過。
注意安裝kekule.js的同時需要安裝three.js,這樣才能渲染3d視圖
安裝kekule.js
vue中使用npm安裝kekule.js項目啟動后導(dǎo)入的kekule對象是空對象,沒法使用,如果是webpack可以通過設(shè)置解決,如果是vue-cli我嘗試使用的配置無法生效,所以建議使用script標簽導(dǎo)入。
webpack的設(shè)置
詳細的關(guān)于這個問題的討論在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必須用線上的資源,使用國內(nèi)的鏡像資源可以避免訪問國外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關(guān)聯(lián)
three.js可以通過npm安裝
npm i three
與kekule關(guān)聯(lián),可以在app.vue中關(guān)聯(lián)(或許),但是我是在渲染的組件內(nèi)關(guān)聯(lián)的,可以多嘗試一下。
import * as THREE from 'three';
...
created() {
Kekule.externalResourceManager.register('three.js', THREE);
},
渲染3d視窗
在vue中渲染3d視圖不能使用官網(wǎng)提供的代碼,會導(dǎo)致報錯,下面的代碼可以完成渲染任務(wù)。
function molRender3DView(mol) {
// 父容器
var parentElem = document.getElementById("example-3D-output");
// 清除之前渲染的3d視圖
Kekule.DomUtils.clearChildContent(parentElem);
// 創(chuàng)建新的視圖
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軸旋轉(zhuǎn)
// 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)
}