simpledit-material

0.1.0-beta.1

CIFParser

Parser and generator for CIF (Crystallographic Information File) format. Supports CIF1 (text key-value + loop_ blocks).

Handles:

  • Cell parameters (cell_length, cell_angle)
  • Space-group metadata
  • Symmetry operations (_symmetry_equiv_pos_as_xyz or _space_group_symop_operation_xyz)
  • Atom sites with fractional coordinates (atom_site loop)
  • Automatic application of symmetry-equivalent positions
new CIFParser()
Static Members
parse(content)
_evalExpr(expr, x, y, z)
generate(crystal, name?)

LatticeParams

Lattice parameters for a crystal structure. Stores conventional cell parameters (a, b, c in Angstroms; angles in degrees) and provides conversion between fractional and Cartesian coordinates.

new LatticeParams(a: number, b: number, c: number, alpha: number, beta: number, gamma: number)
Parameters
a (number = 5) Length of a-vector (Angstroms)
b (number = 5) Length of b-vector (Angstroms)
c (number = 5) Length of c-vector (Angstroms)
alpha (number = 90) Angle between b and c (degrees)
beta (number = 90) Angle between a and c (degrees)
gamma (number = 90) Angle between a and b (degrees)
Static Members
fromVectors(va, vb, vc)
Instance Members
toLatticeVectors()
fracToCart(fx, fy, fz)
cartToFrac(x, y, z)
volume()
minimumImage(dx, dy, dz)

Crystal

Crystal structure: a periodic solid with a unit cell. Extends Molecule so that existing rendering and selection code works unchanged. Adds:

  • lattice (LatticeParams)
  • fractional coordinates for each atom
  • space-group metadata
  • wrap(), generateSupercell()
new Crystal(name: any)

Extends Molecule

Parameters
name (any = 'Crystal')
Instance Members
lattice
spaceGroup
spaceGroupNumber
fracCoords
isCrystal
addAtomFractional(element, fx, fy, fz)
getFrac(atom)
getFracSafe(atom)
wrapAtoms()
generateSupercell(na, nb, nc)
generateSupercell(na, nb, nc)
generateSupercellMatrix(S)

Atom

Represents an atom in the molecular structure

new Atom(element: any, position: any, id: any)
Parameters
element (any)
position (any)
id (any)
Properties
element (string) : Chemical element symbol
position (THREE.Vector3) : 3D coordinates
selected (boolean) : Selection state
mesh (THREE.Mesh) : Visual mesh representation
bonds (Array) : Array of bonds connected to this atom

Bond

Represents a chemical bond between two atoms

new Bond(atom1: any, atom2: any, order: any)
Parameters
atom1 (any)
atom2 (any)
order (any = 1)
Properties
atom1 (Atom) : First atom in the bond
atom2 (Atom) : Second atom in the bond
order (number) : Bond order (1=single, 2=double, 3=triple)
mesh (THREE.Mesh) : Visual mesh representation

Molecule

Represents a molecular structure containing atoms and bonds

new Molecule(name: any)
Parameters
name (any = 'Molecule')
Properties
name (string) : Molecule name
atoms (Array<Atom>) : Array of atoms in the molecule
bonds (Array<Bond>) : Array of bonds in the molecule

CrystalRenderManager

Manages crystal-specific 3D rendering:

  • Unit cell wireframe (the parallelepiped defined by the lattice vectors)
  • Ghost (image) atoms in adjacent unit cells (optional)

This manager works alongside the standard RenderManager. Call drawUnitCell(crystal) after rebuildScene() to overlay the cell box.

new CrystalRenderManager(editor: any)
Parameters
editor (any)
Instance Members
unitCellMesh
ghostMeshes
polyhedralMeshes
polyhedralElements
drawUnitCell(crystal)
drawGhostAtoms(crystal, renderManager)
drawPolyhedra(mol, renderManager)
setPolyhedra(visible, elements?)
addMillerPlane(h, k, l)
clearMillerIndices()
refresh()

FileIOManager

Manages file import/export operations Handles XYZ, SMILES, SDF formats and coordinate conversions

new FileIOManager(editor: any)
Parameters
editor (any)
Instance Members
importSMILES(content, options, smiles)
updateFromMolBlock(molBlock)
updateFromMolBlock(molBlock)
importSDF(sdfString, options)
exportXYZ(options)
convertDeuteriumToDummy(molBlock)
atomsToMolBlock(atoms, options)
atomsToXYZ(atoms)
exportSMILES(options)
exportSDF(options)
getFragments()
atomsToOCL(atoms, options)
exportSVG(options)
exportPNG(options)
atomsToJSON(atoms)
downloadXYZ()
loadXYZFile(file)
importXYZ(xyz, options)
importCIF(content)
exportCIF()
downloadCIF()
importPOSCAR(content)
exportPOSCAR()
downloadPOSCAR()

GeometryController

Controls geometry manipulation sliders and operations Handles bond length, angle, and dihedral adjustments

new GeometryController(editor: any)
Parameters
editor (any)
Instance Members
bindGeometrySliders()
bindBondLengthSlider()
bindBondLengthSlider()
bindAngleSlider()
bindDihedralSlider()
setBondLength(targetDist, saveHistory)
setAngle(targetAngle, saveHistory)
setDihedral(targetAngle, saveHistory)
getMovingFragmentForDihedral(axisStart, axisEnd, excludeAtoms)
getMovingFragment(pivot, direction, excludeAtoms)

calculateDistance

Calculate distance between two points

calculateDistance(p1: THREE.Vector3, p2: THREE.Vector3): number
Parameters
p1 (THREE.Vector3)
p2 (THREE.Vector3)
Returns
number: Distance in Angstroms

calculateAngle

Calculate angle between three points (p1-p2-p3)

calculateAngle(p1: THREE.Vector3, p2: THREE.Vector3, p3: THREE.Vector3): number
Parameters
p1 (THREE.Vector3)
p2 (THREE.Vector3) Vertex
p3 (THREE.Vector3)
Returns
number: Angle in degrees

calculateDihedral

Calculate dihedral angle (p1-p2-p3-p4)

calculateDihedral(p1: THREE.Vector3, p2: THREE.Vector3, p3: THREE.Vector3, p4: THREE.Vector3): number
Parameters
p1 (THREE.Vector3)
p2 (THREE.Vector3)
p3 (THREE.Vector3)
p4 (THREE.Vector3)
Returns
number: Dihedral angle in degrees

getNewPositionsForBondLength

Calculate new positions for bond length adjustment Moves 'movingAtoms' to satisfy target distance between atom1 and atom2

getNewPositionsForBondLength(pos1: THREE.Vector3, pos2: THREE.Vector3, movingAtomPositions: Array<THREE.Vector3>, targetDist: number): Array<THREE.Vector3>
Parameters
pos1 (THREE.Vector3) Position of fixed atom
pos2 (THREE.Vector3) Position of moving atom (pivot)
movingAtomPositions (Array<THREE.Vector3>) Positions of all atoms to move (including pos2)
targetDist (number) Target distance
Returns
Array<THREE.Vector3>: New positions for moving atoms

getNewPositionsForAngle

Calculate new positions for bond angle adjustment Rotates 'movingAtoms' around axis (pivot-normal) to satisfy target angle p1-pivot-p3

getNewPositionsForAngle(p1: THREE.Vector3, pivot: THREE.Vector3, p3: THREE.Vector3, movingAtomPositions: Array<THREE.Vector3>, targetAngleDegrees: number): Array<THREE.Vector3>
Parameters
p1 (THREE.Vector3) Fixed atom position
pivot (THREE.Vector3) Pivot atom position (vertex)
p3 (THREE.Vector3) Moving atom position (defines current angle)
movingAtomPositions (Array<THREE.Vector3>) Atoms to rotate
targetAngleDegrees (number) Target angle in degrees
Returns
Array<THREE.Vector3>: New positions

getNewPositionsForDihedral

Calculate new positions for dihedral angle adjustment Rotates 'movingAtoms' around axis p2-p3

getNewPositionsForDihedral(p1: THREE.Vector3, p2: THREE.Vector3, p3: THREE.Vector3, p4: THREE.Vector3, movingAtomPositions: Array<THREE.Vector3>, targetDihedralDegrees: number): Array<THREE.Vector3>
Parameters
p1 (THREE.Vector3)
p2 (THREE.Vector3) Axis start
p3 (THREE.Vector3) Axis end
p4 (THREE.Vector3)
movingAtomPositions (Array<THREE.Vector3>) Atoms to rotate
targetDihedralDegrees (number) Target dihedral
Returns
Array<THREE.Vector3>: New positions

getCenterOfMass

Calculate center of mass of atoms

getCenterOfMass(atoms: Array<Object>): THREE.Vector3
Parameters
atoms (Array<Object>) Array of atom objects with position property
Returns
THREE.Vector3: Center of mass

getRotatedPositions

Get positions rotated by Euler angles (degrees) around (0,0,0)

getRotatedPositions(positions: Array<THREE.Vector3>, xDeg: number, yDeg: number, zDeg: number): Array<THREE.Vector3>
Parameters
positions (Array<THREE.Vector3>)
xDeg (number)
yDeg (number)
zDeg (number)
Returns
Array<THREE.Vector3>:

getTranslatedPositions

Get translated positions

getTranslatedPositions(positions: Array<THREE.Vector3>, x: number, y: number, z: number): Array<THREE.Vector3>
Parameters
positions (Array<THREE.Vector3>)
x (number)
y (number)
z (number)
Returns
Array<THREE.Vector3>:

calculateSmartOffset

Calculate smart offset to avoid overlap

calculateSmartOffset(incomingAtoms: Array<Object>, currentAtoms: Array<Object>, minDistance: number): THREE.Vector3
Parameters
incomingAtoms (Array<Object>) Atoms to add
currentAtoms (Array<Object>) Existing atoms
minDistance (number) Minimum distance required
Returns
THREE.Vector3: Offset vector

getAlignmentTransform

Calculate alignment transform (Rotation only) Aligns Source Vector (Anchor -> Leaving) to be Anti-Parallel to Target Vector (Anchor -> Leaving)

getAlignmentTransform(targetAnchor: THREE.Vector3, targetLeaving: THREE.Vector3, sourceAnchor: THREE.Vector3, sourceLeaving: THREE.Vector3): {rotation: THREE.Quaternion}
Parameters
targetAnchor (THREE.Vector3)
targetLeaving (THREE.Vector3)
sourceAnchor (THREE.Vector3)
sourceLeaving (THREE.Vector3)
Returns
{rotation: THREE.Quaternion}:

JSMEManager

Manages JSME (Java Script Molecule Editor) instance

new JSMEManager()
Instance Members
init(containerId)
setMol(molBlock)
getMol()
getJME()
getSMILES()

OCLEditorManager

Manages OpenChemLib 2D Editor instance

new OCLEditorManager()
Instance Members
init(containerId)
setMol(molBlock)
setMol(molBlock)
getMol()

OCLManager

Manages OpenChemLib operations for 3D generation and hydrogen addition

new OCLManager()
Instance Members
init()
generate3D(input)
molBlockToSmiles(molBlock)
addHydrogens(smiles)

POSCARParser

Parser and generator for VASP POSCAR / CONTCAR format.

Supported variants:

  • VASP 5+: element names on line 6, counts on line 7
  • VASP 4: counts on line 6 (element names inferred as A, B, ...)
  • Coordinate modes: Direct (fractional) and Cartesian
  • Selective dynamics block (skipped)
  • Negative scale factor treated as absolute cell volume (approximate)

File layout (VASP 5): Line 1 : comment / structure name Line 2 : universal scale factor Lines 3-5: lattice vectors a1, a2, a3 (one per line, 3 floats) Line 6 : element symbols (VASP 5) or counts (VASP 4) Line 7 : atom counts (VASP 5) Line 8 : "Selective dynamics" (optional) Line 9 : "Direct" or "Cartesian" Lines 10+: atom positions

new POSCARParser()
Static Members
parse(content)
_vectorsToLatticeParams(va, vb, vc)
generate(crystal, name?)

RDKitManager

Manages RDKit WASM instance and provides wrapper methods

new RDKitManager()
Instance Members
load()
getInstance()
smilesToMolBlock(smiles, options)
getSVG(smiles, width, height)
molBlockToSmiles(molBlock)

RenderManager

Manages 3D rendering of atoms and bonds Handles mesh creation, color management, and scene updates

new RenderManager(editor: any)
Parameters
editor (any)
Instance Members
createAtomMesh(atom)
createBondMesh(bond)
getElementColor(element)
getElementRadius(element)
updateAtomColors()
updateBondMeshes()
rebuildScene()
updateAtomVisuals(atom)
updateBondVisuals()
updateBondVisuals()
setAtomScale(scale)
setBondScale(scale)

SelectionManager

Manages atom selection state and UI Handles selection highlighting, order tracking, and status updates

new SelectionManager(editor: any)
Parameters
editor (any)
Instance Members
clearSelection()
selectAtom(atom, add)
toggleSelection(atom, multiSelect)
deselectAtom(atom)
selectByIndices(indices)
selectRange(start, end)
selectAll()
invertSelection()
getSelectedAtoms()
getSelectionCount()
getSelectionOrder()
setSelectionMode(mode)
cycleSelectionMode()
updateSelectionStatus()
clearSelectionStatus()
updateHighlights()
deleteSelected()
startSelection(x, y)
updateSelection(x, y)
endSelection(x, y, add)

gcd

Greatest common divisor (positive)

gcd(a: any, b: any)
Parameters
a (any)
b (any)

SlabGenerator

Builds surface slab models from a 3D crystal by cutting along an (hkl) plane.

Algorithm:

  1. Compute the surface normal via the reciprocal lattice (n̂ ∝ h·a* + k·b* + l·c*)
  2. Find the two shortest in-plane lattice vectors by searching small integer combos satisfying h·n1 + k·n2 + l·n3 = 0
  3. Build a temporary supercell large enough to contain layers atomic planes
  4. Project atoms onto n̂, group into discrete layers (within a tolerance)
  5. Retain the first layers planes; optionally centre the slab in the vacuum
  6. Convert to fractional coordinates of the new slab cell, wrap, and deduplicate
new SlabGenerator()
Static Members
generate(crystal, h, k, l, layers, vacuum, centered)

UIManager

Manages UI interactions, modals, and labels Handles toolbar events, periodic table, coordinate editor, and atom labels

new UIManager(editor: any)
Parameters
editor (any)
Instance Members
bindToolbarEvents()
bindModeButtons()
bindEditSubmodeButtons()
updateEditSubmodeUI(mode)
bindSelectSubmodeButtons()
bindMoveSubmodeButtons()
updateSelectSubmodeUI(mode)
updateMoveSubmodeUI(mode)
bindViewButtons()
bindLabelButton()
bindExportButton()
bindConsoleButton()
bindMoleculeButtons()
bindSidebarEvents()
bindUndoRedoEvents()
bindPeriodicTableEvents()
bindAutoBondButton()
bindCoordinateEditorButton()
bindJSMEButton()
bindBondThresholdSlider()
updateLabelButtonText()
openPeriodicTable(callback)
closePeriodicTable()
renderPeriodicTable()
bindFunctionalGroupsEvents()
openFunctionalGroupsModal()
closeFunctionalGroupsModal()
renderFunctionalGroupsGrid()
openCoordinateEditor()
closeCoordinateEditor()
toggleJSMEMaximize()
openJSME()
loadMoleculeTo2D(options)
switchEditor(editorType)
updateEditorVisibility()
closeJSME()
toggleMaximize(element)
exportPNG()
showError(message)
showSuccess(message)
createAtomLabel(atom)
updateAtomLabelText(atom, label)
updateAllLabels()
updateLabelPositions()
updateAtomCount()

FUNCTIONAL_GROUPS

Functional Groups definitions with pre-computed 3D coordinates from OCL The first atom (index 0) is the one that connects to the parent molecule NOTE: OCL converts * to C when parsing, so we manually mark the attachment

FUNCTIONAL_GROUPS

GROUP_CATEGORIES

Category display names

GROUP_CATEGORIES

ErrorHandler

Centralized error handling utility Provides consistent error/success response format across the application

new ErrorHandler()
Static Members
error(message, details)
success(message, data)
warning(message)
info(message)
logError(context, error)
validateParams(params, required)
validateNumber(value, name)
validatePositive(value, name)

LabelRenderer

Optimized label rendering with dirty checking and RAF batching Reduces DOM updates from every frame to only when needed

new LabelRenderer()
Instance Members
init(atoms, camera, canvas)
markDirty(atomIndex)
markAllDirty()
scheduleUpdate()
updateDirtyLabels()
getScreenPosition(atom)
updateAllLabels()
cancelUpdate()
dispose()

Vector3Pool

Object pool for THREE.Vector3 to reduce garbage collection Reuses Vector3 instances instead of creating new ones

new Vector3Pool(size: any)
Parameters
size (any = 100)
Instance Members
get()
getSet(x, y, z)
resize(newSize)