Tutorial: Markup

Markup

Basics

What is Markup?

Markup is a Viewer extension that allows users to draw 2d shapes on top of the WebGL viewport.
The 2d shapes will scale as you zoom the camera in and out.
Markups can be rendered over 2d and 3d models, though for 3d models only orthographic projection is supported.

Markups can be created by end-users using mouse/touch input or by developers using the exposed APIs.

All of the API can be accessed from MarkupsCore extension instance.

Drawing Tools

The extension contains a set of built-in drawing tools:

  • Arrow
  • Text
  • Rectangle
  • Circle / Oval
  • Cloud (rectangle with curvy edges)

Developers can extend the drawing tools by implementing additional
EditModes.
See section Advance concepts below.

Markup features

  • Draw over 2d and 3d models
  • Create, Resize, Rotate and Delete a Markup
  • Undo / Redo
  • Copy / Cut / Paste
  • Color, Transparency, Thickness and additional modifiers
  • Generate SVG String from current Markups overlayed on LMV
  • Restore Markups onto LMV overlay from SVG String
  • Change Z-order of Markups
  • Viewer zoom and pan camera operations

Remember to check MarkupsCore API for all details.

Getting started

Load extension

Make sure the extension gets loaded to the Viewer:

var config = {extensions: ["Autodesk.Viewing.MarkupsCore"]};
var viewer = new Autodesk.Viewing.Viewer3D(container, config);
viewer.loadModel("myModelPath");

// After model finishes loading (async)
var extension = viewer.getExtension("Autodesk.Viewing.MarkupsCore");

Enable User drawing

Users are only able to draw markups while Edit Mode is active.

// Enable user to start drawing markups over viewer
extension.enterEditMode();

// Remove markup drawing mode by calling leaveEditMode
extension.leaveEditMode();

Change drawing tool

Drawing tools are controlled through Edit Modes.
Each drawing tool is implemented as a separate Edit Mode.

// Set Arrow drawing tool by instantiating it's EditMode
var modeArrow = new Autodesk.Markups.Core.EditModeArrow(extension);
extension.changeEditMode(modeArrow);
// From now on, while in EditMode, the user will be drawing arrows.
//...
// Now let's switch into Text drawing tool:
var modeText = new Autodesk.Markups.Core.EditModeText(extension);
extension.changeEditMode(modeText);
// From now on, while in EditMode, the user will be drawing text boxes.

Customize a drawing tool

When drawing a markup, there are several visual attributes that can be customized, such as
stroke width, stroke color, fill color and transparency to name a few.

Developers are welcome to add additional customization values as long as they are supported
by the Svg data format.

// Create a style object using an Utility function.
// Using this function is not a requirement, developers can create compatible styleObjects.
var styleAttributes = ['stroke-width', 'stroke-color', 'stroke-opacity'];
var nsu = Autodesk.Viewing.Extensions.Markups.Core.Utils;
var styleObject = nsu.createStyle(styleAttributes, extension.viewer);

// At this point, feel free to edit the values within styleObject...

// By calling setStyle() we will be applying the characteristics to both the Edit Mode (so that 
// new markups will have the characteristics) and also to the currently selected markup.
extension.setStyle(styleObject);

Saving and loading markups

Markups extension does not provide any storage capability. However, it does provide functionality
to generate an Svg string that can be passed into the storage solution.

// After user has created markups, get the data for further storage.
var markupsStringData = extension.generateData();
// Erase all markups onscreen, then load markups back onto the view
extension.clear();
extension.enterViewMode(); // Very important!!
extension.loadMarkups(markupsStringData, "Layer_1");

Notice the usage of "Layer_1". This indicates that multiple saved markups can be loaded and overlaid
one another. With this, developers can create functionality to toggle their visibility.

extension.loadMarkups(myMarkupString2, "Layer_2");
extension.loadMarkups(myMarkupString3, "Layer_3");
// Hide Layer_2
extension.hideMarkups("Layer_2");
// Show Layer_2 again
extension.showMarkups("Layer_2");

hideMarkups()
and showMarkups()
only change the visibility of the markup svg.
To actually unload the svg and recover some memory, look into
unloadMarkups().

The Undo/Redo stack

All of the actions a user does while authoring markups are added to an action stack.
The action stack allows developers to implement UI to access
undo
/ redo functionality.

Advance concepts

Create a new drawing tool (a new EditMode)

Developers are encourage to implement drawing tools not included in the Markups extension.
Every drawing tool must have a set of classes to handle them. Let's say for example we are implementing a
Panda tool. For a Panda tool we would need to add the following files/classes:

  • MarkupPanda.js
  • EditModePanda.js
  • CreatePanda.js (Action)
  • DeletePanda.js (Action)
  • SetPanda.js (Action)

MarkupPanda.js would contain the class MarkupPanda which extends
Markup and provides the code to render the
markups as an Svg and in a href="http://www.w3.org/TR/2dcontext/">www.w3.org/TR/2dcontext/ canvas 2d context.

EditModePanda.js would contain the class EditModePanda which extends
EditMode and provides the code
to handle user-input for creating a MarkupPanda onscreen.

CreatePanda, DeletePanda and SetPanda are classes that extend
EditAction and provide mechanisms to
author markups of type MarkupPanda.
By encapsulating these operations in actions, the Markups extension is able to make sure
that the undo and redo system handles them gracefully.