Kekule.js 完整使用手册(中文完整版)

一、Kekule.js 概述

1. 简介

Kekule.js 是MIT 开源的纯前端化学信息学 JS 工具库,无后端依赖,可在浏览器 /electron 运行,核心能力:

  • 分子、反应式数据模型(原子、键、环、手性、立体化学)
  • 多格式 IO:SMILES、CML、MDL Mol/Mol2000、Kekule JSON/XML、InChI(扩展)
  • 2D/3D 分子渲染、骨架式 / 球棍 / 填充模型切换
  • 可视化组件:Viewer(只读展示)、Composer(交互式绘图编辑器)
  • 子结构检索、分子对比、芳香环识别、2D 自动布局
  • 快捷键、撤销重做、复制粘贴、自定义工具栏

2. 模块划分

模块 核心功能
Core 化学基础对象:Atom、Bond、Molecule、Reaction、坐标、立体结构
IO 分子格式读写、字符串 / 文件 / URL 加载导出
Render 2D/3D 渲染器,样式、显示模型配置
Widget 基础 UI 控件(弹窗、下拉、表格)
ChemWidget 化学专用组件:Viewer、Composer、周期表
Editor Composer 编辑器绘图工具逻辑
Extra 扩展:InChI、OpenBabel 适配器、自动 2D 布局

3. 官方文档地址

二、安装与引入(3 种方式)

方式 1:CDN 直接引入(快速 demo 推荐)

复制代码
<!-- 样式必须先引入 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kekule/dist/themes/default/kekule.css"/>
<!-- 核心JS -->
<script src="https://cdn.jsdelivr.net/npm/kekule/dist/kekule.min.js"></script>

方式 2:NPM 工程(Vue/React/ 原生工程)

复制代码
npm install --save kekule

ES Module:

复制代码
import { Kekule } from 'kekule'
// 使用Viewer/Composer必须导入主题样式
import 'kekule/theme/default'
console.log(Kekule.VERSION)

CommonJS:

复制代码
const { Kekule } = require('kekule')
require('kekule/theme/default')

方式 3:本地文件部署

dist/kekule.min.jsdist/themes/复制到项目静态目录:

复制代码
<link rel="stylesheet" href="./static/kekule/themes/default/kekule.css"/>
<script src="./static/kekule/kekule.min.js"></script>

三、基础分子对象操作(Core 模块)

1. 手动创建分子(环氧乙烷示例)

复制代码
// 1. 创建分子容器
const mol = new Kekule.Molecule()

// 2. 创建原子,链式设置元素、2D坐标
const C1 = new Kekule.Atom().setSymbol('C').setCoord2D({x:-0.4, y:0.23})
const C2 = new Kekule.Atom().setSymbol('C').setCoord2D({x:0.4, y:0.23})
const O1 = new Kekule.Atom().setSymbol('O').setCoord2D({x:0, y:-0.46})

// 3. 原子加入分子
mol.appendNode(C1)
mol.appendNode(C2)
mol.appendNode(O1)

// 4. 创建化学键(键级1单键、2双键、3三键)
const b1 = new Kekule.Bond().setBondOrder(1).setConnectedObjs([C1, C2])
const b2 = new Kekule.Bond().setBondOrder(1).setConnectedObjs([C2, O1])
const b3 = new Kekule.Bond().setBondOrder(1).setConnectedObjs([O1, C1])

mol.appendNode(b1)
mol.appendNode(b2)
mol.appendNode(b3)

2. 遍历原子 / 键、提取分子式

复制代码
// 遍历所有原子
mol.eachAtom(atom=>{
  console.log(atom.getSymbol(), atom.getCoord2D())
})
// 遍历所有键
mol.eachBond(bond=>{
  console.log('键级', bond.getBondOrder())
})
// 获取分子式
const formula = mol.getFormula()
console.log('分子式', formula)

四、IO 模块:分子导入导出(核心)

支持格式

smiles / cml / mol / mol2000 / kekule-json / kekule-xml

1. 从字符串加载分子

复制代码
// SMILES转分子对象
const smi = 'CCO'
const ethanol = Kekule.IO.loadFormatData(smi, 'smiles')

// CML字符串加载
const cmlStr = `<cml xmlns="http://www.xml-cml.org/schema"><molecule id="m1"/></cml>`
const emptyMol = Kekule.IO.loadFormatData(cmlStr, 'cml')

2. 分子导出为字符串

复制代码
const mol = ethanol
// 导出SMILES
const smiOut = Kekule.IO.saveFormatData(mol, 'smiles')
// 导出CML
const cmlOut = Kekule.IO.saveFormatData(mol, 'cml')
// 导出Mol文件
const molFile = Kekule.IO.saveFormatData(mol, 'mol')

3. 远程 URL 加载分子(异步)

复制代码
Kekule.IO.loadUrlData('./data/ethanol.mol', (mol, success)=>{
  if(success){
    console.log('加载成功', mol)
  }else{
    console.error('文件加载失败')
  }
})

4. 本地文件上传加载(File 对象)

复制代码
const fileInput = document.getElementById('file')
fileInput.onchange = e=>{
  const file = e.target.files[0]
  Kekule.IO.loadFileData(file, (mol, ok)=>{
    if(ok) viewer.setChemObj(mol)
  })
}

五、ChemWidget.Viewer:只读分子查看器

用于展示分子、支持缩放 / 平移 / 3D 旋转,不可编辑。

1. 快速创建 Viewer

复制代码
<div id="viewerWrap" style="width:700px;height:450px;border:1px solid #ccc;"></div>

// 实例化,挂载到DOM
const viewer = new Kekule.ChemWidget.Viewer(document.getElementById('viewerWrap'))
// 设置宽高
viewer.setDimension('700px', '450px')
// 加载乙醇分子
const mol = Kekule.IO.loadFormatData('CCO', 'smiles')
viewer.setChemObj(mol)

2. 关键配置属性

复制代码
// 2D/3D切换
viewer.setRenderType(Kekule.Render.rendererType.R2D)
// viewer.setRenderType(Kekule.Render.rendererType.R3D)

// 2D显示模式:骨架式/简式
viewer.setMoleculeDisplayType(Kekule.Render.Molecule2DDisplayType.SKELETAL)
// viewer.setMoleculeDisplayType(Kekule.Render.Molecule2DDisplayType.CONDENSED)

// 3D模型:线框/棍状/球棍/空间填充
// WIRE / STICKS / BALL_STICK / SPACE_FILL
viewer.setMoleculeDisplayType(Kekule.Render.Molecule3DDisplayType.BALL_STICK)

// 启用顶部工具栏
viewer.setEnableToolbar(true)
// 自定义工具栏按钮
viewer.setToolButtons(['zoomIn','zoomOut','resetView','switch2D3D'])

// 鼠标交互缩放平移
viewer.setEnableMouseControl(true)
// 允许双击打开编辑器
viewer.setEnableEdit(false)
// 自适应尺寸
viewer.setAutoSize(false)

六、Editor.Composer:交互式分子绘图编辑器(最常用)

网页版化学结构式绘制面板,支持手绘、快捷键、撤销、复制粘贴。

1. 创建编辑器

复制代码
<div id="composerBox" style="width:800px;height:500px;border:1px solid #999;"></div>

// 创建编辑器实例
const composer = new Kekule.Editor.Composer()
// 设置尺寸并挂载DOM
composer.setDimension('800px','500px')
composer.appendToElem(document.getElementById('composerBox'))

// 自定义顶部工具栏
composer.setCommonToolButtons([
  'undo','redo','cut','copy','paste',
  'zoomIn','zoomOut','reset','clearAll'
])

// 初始加载分子(可选)
const initMol = Kekule.IO.loadFormatData('C6H6', 'smiles')
composer.setChemObj(initMol)

2. 获取编辑器内分子、导出格式

复制代码
// 获取当前画布分子对象
const currentMol = composer.getChemObj()
// 导出SMILES
const smi = Kekule.IO.saveFormatData(currentMol, 'smiles')
console.log('绘制结果SMILES:', smi)
// 导出CML
const cml = Kekule.IO.saveFormatData(currentMol, 'cml')

3. Composer 全局快捷键(编辑器获焦点生效)

绘图快捷键
按键 功能
A 添加碳原子
O/N/S/P 添加氧 / 氮 / 硫 / 磷
1/2/3 单键 / 双键 / 三键
W 实楔键(向前立体)
Shift+W 虚楔键(向后立体)
T 任意单键
编辑通用快捷键
快捷键 功能
Ctrl+A 全选原子 / 键
Delete / Backspace 删除选中对象
Ctrl+Z 撤销
Ctrl+Shift+Z / Ctrl+Y 重做
Ctrl+C 复制
Ctrl+X 剪切
Ctrl+V 粘贴
鼠标滚轮 缩放画布

七、渲染样式自定义

1. 修改原子、键颜色

复制代码
// 获取渲染配置
const renderCfg = viewer.getRenderConfig()
// 碳元素颜色
renderCfg.elementColors['C'] = '#222222'
// 氧红色
renderCfg.elementColors['O'] = '#ff3333'
// 键粗细
renderCfg.bondLineWidth = 2
viewer.setRenderConfig(renderCfg)

2. 隐藏氢原子(骨架图常用)

复制代码
const renderCfg = composer.getRenderConfig()
renderCfg.showHydrogen = false
composer.setRenderConfig(renderCfg)

八、分子高级功能

1. 子结构检索

复制代码
// 母分子:乙醇 CCO
const parent = Kekule.IO.loadFormatData('CCO','smiles')
// 子结构模板:羟基 -OH
const subTemplate = Kekule.IO.loadFormatData('O','smiles')
// 执行子结构匹配
const matcher = new Kekule.MolSearch.SubstructureMatcher(parent)
const matchResult = matcher.match(subTemplate)
console.log('匹配数量', matchResult.length)

2. 分子相等对比

复制代码
const mol1 = Kekule.IO.loadFormatData('CCO','smiles')
const mol2 = Kekule.IO.loadFormatData('OCC','smiles')
const isSame = Kekule.MolCompare.isIsomorphic(mol1, mol2)
console.log('分子同分等价', isSame) // true

3. 芳香环自动识别

复制代码
const benzene = Kekule.IO.loadFormatData('c1ccccc1','smiles')
const rings = benzene.getRings()
rings.forEach(ring=>{
  if(ring.isAromatic()) console.log('芳香环', ring.getAtomCount())
})

九、Web Component 标签式使用(零 JS 初始化)

无需写 JS,DOM 属性直接创建 Viewer/Composer:

复制代码
<!-- Viewer查看器 -->
<div style="width:600px;height:400px"
     data-widget="Kekule.ChemWidget.Viewer"
     data-render-type="R2D"
     data-chem-data="CCO"
     data-chem-format="smiles">
</div>

<!-- Composer编辑器 -->
<div style="width:800px;height:500px"
     data-widget="Kekule.Editor.Composer"
     data-tool-buttons="undo,redo,copy,paste,zoomIn,zoomOut">
</div>
<script>
// 自动初始化页面所有data-widget组件
Kekule.Widget.autoBindWidgets()
</script>

十、React/Vue 集成说明

React:kekule-react 封装

复制代码
npm install kekule kekule-react

import { Kekule } from 'kekule'
import 'kekule/theme/default'
import { KekuleReact } from 'kekule-react'

// 包装编辑器组件
const Composer = KekuleReact.Utils.wrapWidget(Kekule.Editor.Composer)

function MolEditor(){
  return (
    <Composer
      style={{width:'800px', height:'500px'}}
      toolButtons={['undo','redo','clearAll']}
      onChange={(widget)=>{
        const mol = widget.getChemObj()
        const smi = Kekule.IO.saveFormatData(mol, 'smiles')
        console.log(smi)
      }}
    />
  )
}

Vue 原生封装思路

  1. mounted生命周期实例化 Composer/Viewer
  2. beforeUnmount销毁组件释放内存
  3. 通过 ref 获取 DOM 容器挂载编辑器

十一、常见问题与排错

  1. 编辑器空白、样式丢失 未引入kekule.css,必须先加载样式再加载 JS。
  2. SMILES 加载失败 检查 SMILES 合法性,或改用mol/cml格式测试。
  3. 快捷键不生效 点击编辑器画布获取焦点后再按快捷键。
  4. 跨域无法加载本地 mol 文件 本地文件协议file://会触发 AJAX 跨域,需部署本地 web 服务。
  5. 3D 渲染卡顿 降低分子原子数量,切换 WIRE 线框模式。
  6. NPM 打包报错找不到 theme 确认导入路径:import 'kekule/theme/default',部分打包器需配置静态资源复制。

十二、完整最小可运行 Demo(复制直接打开)

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Kekule Demo</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kekule/dist/themes/default/kekule.css"/>
</head>
<body>
<h3>分子编辑器</h3>
<div id="editBox" style="width:800px;height:480px;border:1px solid #666;"></div>
<button id="exportBtn">导出SMILES</button>
<div id="result"></div>

<script src="https://cdn.jsdelivr.net/npm/kekule/dist/kekule.min.js"></script>
<script>
// 创建编辑器
const composer = new Kekule.Editor.Composer()
composer.setDimension('800px','480px')
composer.appendToElem(document.getElementById('editBox'))
composer.setCommonToolButtons(['undo','redo','copy','paste','zoomIn','zoomOut','clearAll'])

// 导出按钮
document.getElementById('exportBtn').onclick = ()=>{
  const mol = composer.getChemObj()
  const smi = Kekule.IO.saveFormatData(mol, 'smiles')
  document.getElementById('result').innerText = 'SMILES:' + smi
}
// 初始加载苯
const benzene = Kekule.IO.loadFormatData('c1ccccc1', 'smiles')
composer.setChemObj(benzene)
</script>
</body>
</html>