Skip to main content

What's New

Here you can read about major upgrades to the DynaMaker platform. If you experience any problems, let us know at

2022-11-09 Improved geometry projection and images in QuickBar

Highlights among the recent updates to DynaMaker are a new SKYCAD function for geometry projection and a more customizable QuickBar with support for custom images and automatic spinners that indicate loading or processing.


It is now possible to include texts, dimensions and images when generating projections. This is done using the new function SKYCAD.project():

SKYCAD.project(geometry: SKYCAD.GeometryGroup, plane: SKYCAD.Plane, args?: {
excludeTags?: (string | string[])[]
}): SKYCAD.Layout

It can also be used to project a SKYMATH.Vector3D onto a SKYCAD.Plane:

SKYCAD.project(vector: SKYMATH.Vector3D, plane: SKYCAD.Plane): SKYMATH.Vector2D

Images in QuickBar

Items passed to Studio.setQuickBarItems() can now have a property image:

action: () => {
// do something

In new apps, the image height is limited to 40 pixels by default. If you wish to change this or to use it in an app created before this change, add the following CSS to the STYLE tab in UI Studio:

.sky-quick-bar-item-container img {
max-height: 40px;

QuickBar items now also handle asynchronous functions by showing a spinner while the action is running. This is similar to how the SKYUI.Button works:

icon: 'download-alt',
action: () => {
return functionThatReturnsAPromise()

Customizable delay for Configurator callback

It is now possible to set the delay for the callback functions connected to a Configurator:

const configurator = new SKYPARAM.Configurator([
// parameters...

// set the completion callback delay to 1500 milliseconds instead of the default 500

configurator.addCompletionCallback((valid, values) => {
// this will run 1500 ms after a changes was made to the configurator

2022-10-10 Some adjustments and fixes

  • The toolbar at the top of the preview in the drawing editor will now stick to the top of the page when scrolling down.
  • Introduced an optimization that prevents very large static sketches from slowing down the editor experience.
  • Updated the Elfsquad plugin to automatically remove the <p></p> that wrapped all text values. Re-sync the plugin to get the latest version.
  • Fixed a bug in the Elfsquad plugin that in very rare cases caused an error when synchronizing.
  • Fixed a bug in SKYDRAWING where the validScales argument in drawing.addContent() could cause an endless loop.
  • Various SKYCAD fixes

2022-10-03 Merge open ends

Some sketches are not fully connected after importing them into the app dashboard which prevents extruding them into 3D geometry. To fix it, you had to use the sketch.mergeOpenEnds() function to connect the lines in the sketch. This is now done by default when creating the static sketch in the dashboard. Since this merge operation is a good idea most of the time, but not always, it is also possible to opt-out when creating the static sketch.

2022-09-14 Lighting adjustment in the room scene

This change only applies to apps that have sceneOptions: { type: 'room' } in ADVANCED.

To better support different materials, especially when working with imported GLTF models, we have updated the default lighting settings of the room scene. If you wish to opt out of this change, you can restore the original lighting settings by copying the following lightIntensity values into your sceneOptions in ADVANCED.

// other options...

sceneOptions: {
type: 'room',

// original room lighting settings
lightIntensity: {
ambient: 0,
point: 5,
far: 2,
near: 8,
left: 5,
right: 10,


Below is the same static model (GLB) shown in three different scene settings:

  1. Clean scene (current default)
  2. Room scene with original settings
  3. New room default settings

The new defaults are:

lightIntensity: {
ambient: 0.4,
point: 5,
far: 1,
near: 1,
left: 1,
right: 1,

2022-05-06 Better type checking and code formatting

The code editor in DynaMaker has been upgraded to catch some common coding patterns that might lead to unexpected errors and to make the code formatting more consistent.

Strict null checks

In the video below, postPositions.find has no guarantee that it will find a position. Previously, accessing position without checking that it is not undefined was not reported as an error by the editor, which could lead to errors occurring in production.

To verify that position exists, you can use an if-statement, for example:

If for some reason it is not possible to do a proper check, you can use the non-null assertion operator to disable the error message. We recommend that you avoid doing this if possible since it increases the risk of your app crashing in production:

You can read more about struct null checks here.

Code formatting

We have upgraded the formatting engine to use Prettier. You can automatically format your code in the DynaMaker editor by pressing shiftaltf or by pressing F1 and then searching for format.

2022-04-27 - Rotation of images

Rotation of an ImageInstance now behaves the same as rotation of a SketchInstance. Previously images were rotated around their center point instead of their lower-left corner. This led to inconsistent behavior, for example when rotating a Layout containing both sketches and images.

Sketch (unchanged)

The blue sketch has a rotation of 0 and the red has a rotation of Math.PI / 2.

Image before

The horizontal image has a rotation of 0 and the vertical has a rotation of Math.PI / 2. The rotation is done around the center of the image.

Image now

The horizontal image has a rotation of 0 and the vertical has a rotation of Math.PI / 2. The rotation is done around the lower left corner of the image.

Update 2022-02-09

With this update, we have cleaned up the SKYCAD.Layout API to make it easier to work with:

  • Deprecated many style-related functions such as getDefaultSketchFillColor() in favor of getDefaultStyle()
  • Deprecated getters for individual element types such as getDimensions() in favor of getElements()
  • Deprecated margins
  • Deprecated size (width and height)
  • Removed the default size (width and height)
  • Removed the default anchors
  • Renamed cropContent () to crop()
  • Renamed getContentBounds() to getBounds()
  • Renamed rotateContent () to rotate()
  • Renamed scaleContent () to scale()
  • Renamed translateContent () to translate()

Update 2022-02-01

This update contains the following changes:

New tutorial: My First App

A new tutorial My First App has been added. It covers the very basics of how to create an application, from template to deployment.

The rest of the tutorials have been updated to fit with the new simplified project and app templates.

Simplified application template

The new application template comes with no components or drawings out-of-the-box. By creating and connecting all the parts of the application, we hope that you as a developer will gain a better understanding of how your application works. Check the new tutorial My First App which covers the first steps of creating an application!

Simplified UI template

Since there are no components in the default project template, the new UI template should be much easier to grasp. Most of the template code is now in the UI tab when starting. As your application grows, you can structure your code into the COMPONENTS, ACTIONS and CONSTANTS tabs.

Although no component is added by default, there are a few lines of commented code that can help you when importing your first component.

Simplified component template

There have been a few changes in the component template as well to make it easier to get started with. Just like in the UI, most template code has been moved to the COMPONENT tab. As your component grows more complex, you should still move geometry logic to GEOM3D and GEOM2D, but when starting it is all contained within generateGeometry() in the Component itself.

PARAMETERS includes a new smart configurator that still works after modifying the component properties. It is intended to help you get started with implementing your custom component and it is recommended to replace it eventually.

Update 2021-11-04

Simplified SKYMATH API

The SKYMATH module has been reworked to be easier to understand and use! Many existing functions have been deprecated and will show up as strikethrough in the code. We recommend that you start using the new functions, but the deprecated function will continue to work as before.

The deprecation message (highlighted in the image above) will give you a hint of what function you can use instead of the deprecated one. In this example, you can replace the call to SKYMATH.addVectors2D(v1, v2) with SKYMATH.add(v1, v2).

Many of the new functions have overload signatures, which means that the same function can work with different inputs. For example, the new SKYMATH.add() works in both 2D and 3D and replaces both SKYMATH.addVectors2D() and SKYMATH.addVectors3D(). It can also add two instances of the new SKYMATH.Matrix class!

SKYMATH.add(new SKYMATH.Vector2D(1, 2), new SKYMATH.Vector2D(2, 1)) // returns new SKYMATH.Vector2D(3, 3)
SKYMATH.add(new SKYMATH.Vector3D(1, 2, 3), new SKYMATH.Vector3D(3, 2, 1)) // returns new SKYMATH.Vector2D(4, 4, 4)

You can see all the overloads by clicking the arrows (or using the up and down arrows on your keyboard) next to the function signature in the code editor.

You can read more about function overloads in the official TypeScript handbook.

Update 2021-10-21

Geometry loading effect

When geometry is being updated, after a Studio.requestGeometryUpdate(), the previous geometry will become blurred to indicate to the user that an update is running.

You can change this loading effect using CSS. For example, to make the geometry 50% grayscale in addition to the blur effect, add the following to the STYLE tab:

canvas.loading {
filter: blur(2px) grayscale(50%);

Applications created before this change was released can opt-in by adding a style rule in the STYLE tab. Here is the default rule used in new applications:

canvas.loading {
filter: blur(2px);

You can opt out of this change altogether in the ADVANCED tab:

export function productConfigurationFactory(): STUDIO.IProductConfiguration {
return {
disableLoadingEffectOnGeometryUpdate: true,
// other settings...

Update 2021-10-07

Simplified camera API

The functions used for handling the camera have been reworked and many existing functions have been deprecated. Although we recommend that you start using the new camera functions, the deprecated function will continue to work as before, but will show up as strikethrough in the code:

There are now four main camera functions:


You can read more about the new camera API here!

Update 2021-08-30

Editor layout change

We have simplified the layout of how you access the different files in the code editor. By flattening the file menu to a single list on the right-hand side, you can open any file in the editor with one click.

Easier access to the Studio service when working in UI

The UI template has been updated so that the Studio service is global in the UI file. This only applies to new projects that you create from this update and forward. If you want you can create a new project and copy-paste this change into your existing project.

Update 2021-06-20

Some CAD-related classes and functions have been moved from SKYMATH to SKYCAD. Your code has been automatically updated to reflect these changes.

RefPlane moved and renamed

SKYMATH.RefPlane is now SKYCAD.Plane.

Bounds moved

SKYMATH.Bounds2D and SKYMATH.Bounds3D are now SKYCAD.Bounds2D and SKYCAD.Bounds3D respectively.

Update 2021-06-01

This update to DynaMaker simplifies working with the CAD libraries by merging the whole SKYSKETCH namespace into the SKYCAD namespace.

How does this update affect existing projects?

All references to SKYSKETCH have been changed to SKYCAD, so this update should be non-breaking. Your projects will work just like before, but instead of writing new SKYSKETCH.Layout() to create a new Layout, you write new SKYCAD.Layout() instead.

Update 2021-02-17

This update to DynaMaker, which should not break any existing applications, makes it easier to use the ComponentHandler and brings out-of-the-box support for saving and loading.

How does this update affect existing projects?

This update introduces a new pattern of interacting with the ComponentHandler. Existing projects may choose to continue using the old pattern and can ignore the changes described below. If you create a new component in an existing project, you may have to update it manually to make it look like before. Another way, which may be easier, is to fork an existing component in your project and build from there.

Changes to the ComponentHandler

Define components

The ComponentHandler function defineComponent() is no longer needed and should not be used.

Add components

You no longer have to add a type string when adding components to the ComponentHandler.

// old
componentHandler.add('accessory', new ACCESSORY.Component())

// new
componentHandler.add(new ACCESSORY.Component())

If you need to separate the same component class into logical groups, you may do so using tags.

// old
componentHandler.add('accessory-top', new ACCESSORY.Component())
componentHandler.add('accessory-bottom', new ACCESSORY.Component())
const topAccessories = componentHandler.getInstances('accessory-top')

// new
componentHandler.add(new ACCESSORY.Component(), { tags: ['top'] })
componentHandler.add(new ACCESSORY.Component(), { tags: ['bottom'] })
const topAccessories = componentHandler
.filter(inst => inst.hasTag('top'))

Get components, instances and bundles

// old

// new (provides code completion!)

Clear a specific component

// old

// new, by class
// new, by tag

New application and component templates

When you create a new project or component, you might notice that the template has changed with this update.


  • Extending STUDIO.BaseComponent

Components now extend the STUDIO.BaseComponent class, which adds functionality such as the getProperty function to your component automatically.

  • Constructor arguments

It is best practice to have a Component constructor without input arguments. If you need to change the values of the properties you should call component.setProperties({ ... }) after creating the component. The template has been updated to reflect this.

// old
constructor(args: Partial<CONSTANTS.Properties> = {}) {
const width = args.width ?? 100
const depth = args.depth ?? 100
const height = args.height ?? 100 = { width, depth, height }

// new
constructor() {

depth: 100,
height: 100,
width: 100,

Save and load

If your project has authentication such as JSON Web Tokens or Auth0 enabled, the new application template together with the updated ComponentHandler allows for saving and loading configurations in your deployed project by default.

While developing

You can now test save and load directly in the UI Editor editor.

Update 2020-10-20

This update to DynaMaker, which should not break any existing projects, makes it easier to create and use geometry.


You will notice that some classes and functions that you've used previously have been deprecated. Deprecated classes and functions still work, but should be avoided in new code that you write.

Deprecated classes and functions will appear as strikethrough in the editor

Action Events

The way that actions related to the product are called from the UI code has changed for new projects. The new way brings a better developer experience through code completion and type checking.

// old way

// new way

The Geometry API

The way that we create and group geometry (models and sketches) has changed with this update.

  • The new class SKYCAD.GeometryGroup should be used for grouping geometry (parent-child structure)
  • SKYCAD.ModelInstance should no longer be used as a parent of other models via addChildInstance()
  • ComponentInstance.getModelInstance() is replaced by ComponentInstance.generateGeometry() and now returns a SKYCAD.GeometryGroup
  • SKYCAD.GeometryOnPlane has been deprecated in favor of the similar SKYCAD.LayoutOnPlane
  • SKYCAD.Model has been renamed to SKYCAD.ParametricModel to differentiate it from SKYCAD.MeshModel
  • SKYCAD.ModelMaterial has been renamed SKYCAD.Material

Geometry And The Component Handler

The component handler has been updated with some new functionality that makes it simple to gather all the geometry from your components!

componentHandler.generateAllGeometry(): SKYCAD.GeometryGroup
componentHandler.generateGeometry(componentType: string): SKYCAD.GeometryGroup
componentHandler.generateAllLightweightGeometry(): SKYCAD.GeometryGroup
componentHandler.generateLightweightGeometry(componentType: string): SKYCAD.GeometryGroup

These functions position the geometry for each component instance. They require that your components implement the generateGeometry() and generateLightweightGeometry() functions respectively.

Updating The Scene

For new projects, getModels() and getSketches() in the COMPONENTS tab of the UI Editor have been replaced by updateGeometry() and updateLightweightGeometry(), to give you more fine-grained control over what geometry should update and when.

// the old way

export function getModels(manager: STUDIO.Manager) {
// ...

export function getSketches(manager: STUDIO.Manager) {
// ...
// the new way

* Add new Geometry to the scene depending on app state
export function updateGeometry(data: STUDIO.DataForUpdateGeometry, worldControls: STUDIO.WorldControls) {
const geometryGroup = new SKYCAD.GeometryGroup()

switch (data.designStep) {

worldControls.updateGeometry(geometryGroup, { groupId: 'primary' })

* Optional lightweight geometry
export function updateLightweightGeometry(data: STUDIO.DataForUpdateGeometry, worldControls: STUDIO.WorldControls) {
const geometry = data.componentHandler.generateAllLightweightGeometry()
worldControls.updateGeometry(geometry, { groupId: 'lightweight' })

Instead of calling Studio.update() you should use Studio.requestGeometryUpdate() and Studio.requestLightweightGeometryUpdate() together with this new update geometry pattern.

Components And The Configurator

New components created from this point forward have a new pattern for generating their configurator(s). Instead of implementing the configure() function on the component, you should export one or more functions from the

PARAMETERS tab in the component-maker.

You can switch between different configurators with the dropdown in the upper left corner

In the application, use the generator functions to generate the configurator instead of calling configure().

// old way
export function actionEvent(type: string, args: any, manager: STUDIO.Manager) {
// ...

switch (type) {
case 'configure-component': return component.configure()

// new way
export function configureMainComponent() {
const component = getMainComponent()
return COMPONENT1.generateConfigurator(component)