使用kekule.js渲染3d分子结构-vue和js

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)
  }

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容