Saltar al contenido
MellowCAD

Esta sección solo está escrita en inglés.

Cómo…

En npm

Without a browser

CadDriver: the engine driven by script, in Node, in tests and on a server, and demos you can replay.

CadDriver is the same engine as CadEngine, with no canvas: it is driven as a user would drive it — commands typed, clicks in world coordinates, keys — and runs anywhere JavaScript does. Use it to script drawings, to test code that builds on the engine, or to render drawings on a server.

A first script

examples/engine-node/main.ts
import { writeFileSync } from "node:fs"
import { CadDriver, SvgScenePresenter } from "@mellowcad/engine"
// The engine with no browser: typed commands and clicks in world// coordinates, as a user would draw them. SAVE hands the drawing file to the// host's transport, which here writes it to disk.const cad = new CadDriver({  files: {    save: (text, fileName) => writeFileSync(fileName, text),    open: async () => null,  },})
cad.command("RECTANG").click({ x: 0, y: 0 }).click({ x: 200, y: 100 })cad.command("CIRCLE").click({ x: 100, y: 50 }).type("30").enter()cad.command("SAVE")
// What the canvas would show, as an SVG document.writeFileSync("drawing.svg", new SvgScenePresenter().render(cad.scene()))
console.log(cad.commandLog().join("\n"))cad.dispose()

That is examples/engine-node, run with node main.ts. The package's declarations name DOM types, because CadEngine takes a canvas, so a TypeScript project that checks them (skipLibCheck off) has "dom" in its lib, even in Node.

Driving it

Every input returns the driver, so a gesture reads as one line. Points are world coordinates: the driver projects them through its view, 1000×800 pixels at scale 1 unless width and height say otherwise.

InputWhat the user does
command("CIRCLE")Types a command at the Command: prompt and presses Enter
click(point), doubleClick(point)Picks a point
type("30"), enter(), escape()Types into the prompt's field, then Enter or Escape
option("Close")Answers [Close/Undo] with a keyword, by its global id
press("F8")Presses a key on the drawing
moveTo, drag, rightClick, wheelMoves, drags a window or a grip, right-clicks, zooms
select(...ids), selectAll()Sets the selection directly, with no clicks
undo(), redo()U and REDO

option names a keyword by its global id in every language, and types it as a user of the command language would: option("Close") types C in English and C for Cerrar in Spanish. An id the prompt does not offer throws, since it is a mistake in the script.

To read what happened:

ReaderWhat it returns
entities(), latest(), byId(id)The drawing's objects, the last one added, one by its id
entityCount, typeCounts()How many objects, and how many of each type
selectedIds()The selection
state()The same EngineState a page's engine has
scene()The frame a canvas would show, for a presenter
commandLog()The command line's history, as text

Options

import { CadDriver, createMemoryDrawingStore } from "@mellowcad/engine"import { es } from "@mellowcad/engine/locales/es"
const cad = new CadDriver({  locale: es, // the language it speaks  store: createMemoryDrawingStore(), // where it autosaves, and what it starts from  snap: true, // running object snaps, off by default  polar: true, // polar tracking, off by default})

Object snaps, polar tracking and the UCS icon start off, so a script lands exactly where it clicks; turn them on when a script is about them. entities and blocks seed the drawing, and files and clipboard stand in for SAVE, OPEN and the clipboard, which have no browser to use.

In tests

The driver makes a test read like the steps a user takes:

import { CadDriver } from "@mellowcad/engine"import { expect, it } from "vitest"
it("draws a line 100 long", () => {  const cad = new CadDriver()  cad.command("LINE").click({ x: 0, y: 0 }).type("@100,0").enter().escape()
  expect(cad.latest()).toMatchObject({ type: "line", end: { x: 100, y: 0 } })  cad.dispose()})

A drawing file as a picture

On a server, a drawing file becomes SVG through a driver that starts from it:

import { CadDriver, SvgScenePresenter, createMemoryDrawingStore } from "@mellowcad/engine"
export function drawingToSvg(file: string): string {  const cad = new CadDriver({ store: createMemoryDrawingStore(file), width: 800, height: 600 })  cad.command("ZOOM").option("Extents")  cad.press("F7") // no grid  const svg = new SvgScenePresenter().render(cad.scene())  cad.dispose()  return svg}

The scene is the frame a user would see, so the crosshair is in it. For the objects alone, see demos.

Demos

A demo is a script that can be replayed: the landing page's animations and the figures in the docs are demos. demo() starts one, each step returns a new script, and recordDemo replays it on a fresh engine:

import { buildDrawingPreview, demo, recordDemo, transcript } from "@mellowcad/engine"
const script = demo({ width: 800, height: 400 })  .command("LINE")  .click(0, 0)  .type("100")  .enter()  .escape()
const recording = await recordDemo(script)transcript(recording) // the command line's history, line by linebuildDrawingPreview(recording.document, { width: 400, height: 200 }) // the objects alone, framed

A recording holds each step with the prompt it answered and the objects it added or removed, the drawing as the session left it, and the last frame. recordDemo(script, { locale }) records the same script in another language.