meta data for this page
Anatomy of a Design
A JSCAD design (script) must have at least one function defined, the main() function, which must to return a shape.
const { sphere } = require('@jscad/modeling').primitives const main = () => { return sphere() // a single shape } module.exports = { main }
Or an array of shapes.
const { cube, cylinder, sphere } = require('@jscad/modeling').primitives const main () => { const a = cube() const b = sphere() const c = cylinder() return [a,b,c] // an array of shapes } module.exports = { main }
In addition, functions can be created to split the design into managable pieces, i.e. parts, etc.
const { cube, sphere } = require('@jscad/modeling').primitives const partA = (options) => { // called from main() below var shapes = [] shapes.push( sphere() ) shapes.push( cube(options) ) return shapes } const main = () => { let list = partA({radius: 10}) return list } module.exports = { main }
Projects
As designs grow in complexity, the need for smaller, reusable parts becomes apparent. This is the time to consider using a “project”.
Projects are simple directories, containing several files (parts) of the design. For example, a project for a RC car design would have various parts. And the reusable parts can be separated out.
- …/rc-car
- chassis.js
- body.js
- tire.js
- index.js
The 'index' within the project is the entry point of the project. The main function of the 'index' creates each of the pieces, move the pieces into position, and returns the complete design. And by convention, exports the main function.
const chassis = require('./chassis') const body = require('./body') const tire = require('./tire') const main = (params) => { const partA = chassis(params) const partB = body(params) const tires = [ ... ] return [partA, partB, tires] } module.exports = { main }
Projects can also be used when working with external formats, such as STL files. This allows designs to include STL meshes just like any other part. The STL file is placed within the project directory just like any other part.
- …/rc-car
- chassis.js
- body.js
- tire.js
- index.js
- rc_receiver.stl
And the design is adjusted to include the new part from the STL file.
const chassis = require('./chassis') const body = require('./body') const tire = require('./tire') const receiver = require('./rc_receiver.stl') const main = (params) => { const partA = chassis(params) const partB = body(params) const tires = [ ... ] return [partA, partB, tires, receiver] } module.exports = { main }
Design Parameters
A design can have interactive parameters by declaring a special function; getParameterDefinitions().
In applications and browsers, these parameters are presented to users, allowing users to change designs.
Usage
This function must return an array of parameter definitions, as show below.
const getParameterDefinitions = () => { return [ { name: 'length', type: 'int', initial: 150, caption: 'Length?' }, { name: 'width', type: 'int', initial: 100, caption: 'Width?' }, ] }
The parameters are evaluated and values are passed into the main function. Be sure to declare the main function properly.
const main = (params) => { var l = params.length var w = params.width ... }
Parameter Types
The parameters are defined as input fields on a single HTML5 form, i.e. the list of parameters. For more information on HTML5 input fields, see some examples at W3 Schools.
Note: Browsers are NOT the same and will treat unsupported parameter types as TEXT.
Type | Example | Returned Value |
---|---|---|
checkbox | {name: 'bigorsmall', type: 'checkbox', checked: true, caption: 'Big?'} | if checked true, else false |
checkbox | {name: 'bigorsmall', type: 'checkbox', checked: true, initial: 20, caption: 'Big?'} | if checked 20, else false |
color | { name: 'color', type: 'color', initial: '#FFB431', caption: 'Color?' } | “#rrggbb”, use html2rgb() to convert |
date | {name: 'birthday', type: 'date', caption: 'Birthday?'} | “YYYY-MM-DD” |
{name: 'address', type: 'email', caption: 'Email Address?'} | string value | |
float | {name: 'angle', type: 'number', initial: 2.5, step: 0.5, caption: 'Angle?'} | float value |
int | {name: 'age', type: 'int', initial: 20, caption: 'Age?'} | integer value |
number | {name: 'angle', type: 'number', initial: 2.5, step: 0.5, caption: 'Angle?'} | float value |
password | {name: 'password', type: 'password', caption: 'Secret?'} | string value |
slider | {name: 'count', type: 'slider', min: 2, max: 10, caption: 'How many?'} | float value |
text | {name: 'name', type: 'text', caption: 'Name?'} | string value |
url | {name: 'webpage', type: 'url', caption: 'Web page URL?'} | string value |
group | { name: 'balloon', type: 'group', caption: 'Balloons' } | none, only displayed |
The parameters accept additional restrictions and assistance. These include 'initial', 'max', 'maxLength', 'min', 'pattern', 'placeholder', 'size', and 'step'.
There is one more special parameter type called 'choice', which defines a list of choices for selection.
const getParameterDefinitions = () => { return [ { name: 'rounded', type: 'choice', caption: 'Rounded edges', values: [0, 1], captions: ['No', 'Yes (slow!)'], initial: 0 } ] }
The list of captions are those shown as a pull down list. The list of values define a value for each caption. And, the chosen value is passed into the main function.