├── .gitignore
├── .DS_Store
├── Markup
├── core
│ ├── package-lock.json
│ ├── package.json
│ ├── MarkupTypes.js
│ ├── edit-actions
│ │ ├── DeleteStamp.js
│ │ ├── DeleteCloud.js
│ │ ├── SetStyle.js
│ │ ├── DeleteFreehand.js
│ │ ├── DeleteRectangle.js
│ │ ├── DeleteText.js
│ │ ├── DeleteHighlight.js
│ │ ├── DeletePolyline.js
│ │ ├── DeletePolycloud.js
│ │ ├── DeleteCallout.js
│ │ ├── DeleteArrow.js
│ │ ├── SetText.js
│ │ ├── CloneMarkup.js
│ │ ├── CreateStamp.js
│ │ ├── CreateCloud.js
│ │ ├── SetCallout.js
│ │ ├── DeleteDimension.js
│ │ ├── CreateText.js
│ │ ├── CreateRectangle.js
│ │ ├── CreateDimension.js
│ │ ├── CreateFreehand.js
│ │ ├── CreateHighlight.js
│ │ ├── CreateArrow.js
│ │ ├── SetRotation.js
│ │ ├── SetPosition.js
│ │ ├── CreatePolyline.js
│ │ ├── CreatePolycloud.js
│ │ ├── DeleteCircle.js
│ │ ├── CreateCallout.js
│ │ ├── SetPolyline.js
│ │ ├── SetPolycloud.js
│ │ ├── SetFreehand.js
│ │ ├── SetHighlight.js
│ │ ├── SetStamp.js
│ │ ├── SetSize.js
│ │ ├── CreateCircle.js
│ │ ├── SetCloud.js
│ │ ├── SetRectangle.js
│ │ ├── EditAction.js
│ │ ├── SetDimension.js
│ │ ├── SetArrow.js
│ │ ├── SetCircle.js
│ │ ├── EditActionGroup.js
│ │ └── EditActionManager.js
│ ├── MarkupFreehand.js
│ ├── MarkupHighlight.js
│ ├── EditModeManager.js
│ ├── edit-modes
│ │ ├── EditModeFreehand.js
│ │ ├── BuiltinEditModes.js
│ │ ├── EditModeHighlight.js
│ │ ├── EditModeStamp.js
│ │ ├── EditModeCloud.js
│ │ ├── EditModeCircle.js
│ │ ├── EditModeRectangle.js
│ │ ├── EditModeArrow.js
│ │ └── EditModePen.js
│ ├── edit-clipboard
│ │ └── Clipboard.js
│ ├── Markups.css
│ ├── DomElementStyle.js
│ ├── MarkupCircle.js
│ ├── MarkupRectangle.js
│ ├── MarkupEvents.js
│ ├── MarkupStamp.js
│ ├── MarkupPolyLine.js
│ ├── MarkupPen.js
│ └── StyleUtils.js
├── gui
│ └── MarkupsGui.css
└── Markup.js
├── Measure
├── EventTypes.js
├── res
│ └── icon-spinner-sm.svg
├── MagnifyingGlass.js
├── PolygonCentroid.js
└── MeasurementsManager.js
├── LICENSE
├── README.md
├── webpack.js
└── thirdparty
└── resize-observer-polyfill
└── ResizeObserver.min.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | build/Release
3 | node_modules/
4 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wallabyway/forge-markup-measure-extensions/HEAD/.DS_Store
--------------------------------------------------------------------------------
/Markup/core/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@adsk/markupscore",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1
5 | }
6 |
--------------------------------------------------------------------------------
/Measure/EventTypes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Fired to start or stop mouse tracking
3 | * the mouse tracker starts and stop a mousetracker used by an application
4 | * this can be used to support autoscrolling in an application
5 | * @event SET_MOUSE_TRACKING
6 | * @property {string} [mode] - 'start' or 'stop'
7 | */
8 | module.exports.SET_MOUSE_TRACKING = 'mouseTracking';
9 |
--------------------------------------------------------------------------------
/Markup/gui/MarkupsGui.css:
--------------------------------------------------------------------------------
1 |
2 | .adsk-icon-markup:before {
3 | content: "a";
4 | }
5 |
6 | .lmv-markup-gui-toolbar {
7 | position: absolute;
8 | top: 0;
9 | margin: 5px 5px;
10 | color: #000000;
11 | }
12 |
13 | .lmv-markup-gui-toolbar-content > * {
14 | margin: 0 2px;
15 | }
16 |
17 | .lmv-markup-gui-style-options {
18 | display: inline-block;
19 | }
--------------------------------------------------------------------------------
/Markup/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@adsk/markupscore",
3 | "version": "1.0.0",
4 | "description": "core library for Markup class",
5 | "main": "./MarkupsCore.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "peerDependencies": {
10 | "resize-observer-polyfill": "^1.5.1"
11 | },
12 | "private": true
13 | }
14 |
--------------------------------------------------------------------------------
/Measure/res/icon-spinner-sm.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Markup/core/MarkupTypes.js:
--------------------------------------------------------------------------------
1 |
2 | // These are all the supported markup types.
3 |
4 | export const MARKUP_TYPE_ARROW = "arrow";
5 | export const MARKUP_TYPE_TEXT = "label";
6 | export const MARKUP_TYPE_RECTANGLE = "rectangle";
7 | export const MARKUP_TYPE_CIRCLE = "ellipse";
8 | export const MARKUP_TYPE_CLOUD = "cloud";
9 | export const MARKUP_TYPE_FREEHAND = "freehand";
10 | export const MARKUP_TYPE_HIGHLIGHT = "highlight";
11 | export const MARKUP_TYPE_POLYLINE = "polyline";
12 | export const MARKUP_TYPE_POLYCLOUD = "polycloud";
13 | export const MARKUP_TYPE_CALLOUT = "callout";
14 | export const MARKUP_TYPE_DIMENSION = "dimension";
15 | export const MARKUP_TYPE_STAMP = "stamp";
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteStamp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateStamp } from './CreateStamp';
5 |
6 | export { DeleteStamp };
7 |
8 | class DeleteStamp extends EditAction {
9 | constructor(editor, stamp) {
10 | super(editor, 'DELETE-STAMP', stamp.id);
11 |
12 | this.createStamp = new CreateStamp(
13 | editor,
14 | stamp.id,
15 | stamp.position,
16 | stamp.size,
17 | stamp.rotation,
18 | stamp.getStyle()
19 | );
20 | }
21 |
22 | redo() {
23 | this.createStamp.undo();
24 | }
25 |
26 | undo() {
27 | this.createStamp.redo();
28 | }
29 | }
--------------------------------------------------------------------------------
/Markup/core/MarkupFreehand.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { MarkupPen } from './MarkupPen';
4 | import * as MarkupTypes from './MarkupTypes';
5 | import { EditModeFreehand } from './edit-modes/EditModeFreehand';
6 |
7 |
8 | /**
9 | *
10 | * @param id
11 | * @param editor
12 | * @constructor
13 | */
14 | export function MarkupFreehand(id, editor) {
15 |
16 | MarkupPen.call(this, id, editor);
17 | this.type = MarkupTypes.MARKUP_TYPE_FREEHAND;
18 | }
19 |
20 | MarkupFreehand.prototype = Object.create(MarkupPen.prototype);
21 | MarkupFreehand.prototype.constructor = MarkupFreehand;
22 |
23 | var proto = MarkupFreehand.prototype;
24 |
25 | proto.getEditMode = function() {
26 |
27 | return new EditModeFreehand(this.editor);
28 | };
29 |
30 |
--------------------------------------------------------------------------------
/Markup/core/MarkupHighlight.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { MarkupPen } from './MarkupPen';
4 | import * as MarkupTypes from './MarkupTypes';
5 | import { EditModeHighlight } from './edit-modes/EditModeHighlight';
6 |
7 | /**
8 | *
9 | * @param id
10 | * @param editor
11 | * @constructor
12 | */
13 | export function MarkupHighlight(id, editor) {
14 |
15 | MarkupPen.call(this, id, editor);
16 | this.type = MarkupTypes.MARKUP_TYPE_HIGHLIGHT;
17 | }
18 |
19 | MarkupHighlight.prototype = Object.create(MarkupPen.prototype);
20 | MarkupHighlight.prototype.constructor = MarkupHighlight;
21 |
22 | var proto = MarkupHighlight.prototype;
23 |
24 | proto.getEditMode = function() {
25 |
26 | return new EditModeHighlight(this.editor);
27 | };
28 |
29 |
--------------------------------------------------------------------------------
/Markup/core/EditModeManager.js:
--------------------------------------------------------------------------------
1 |
2 | // Maps EditMode id (string) into a contructor/class
3 | var _editModes = {};
4 |
5 | class EditModeManager {
6 | constructor(){
7 | // nothing //
8 | }
9 |
10 | register(id, clazz) {
11 | if (id in _editModes)
12 | throw new Error(`EditMode with id (${id}) already registered.`);
13 |
14 | _editModes[id] = clazz;
15 | }
16 |
17 | unregister(id) {
18 | if (id in _editModes)
19 | delete _editModes[id];
20 | }
21 |
22 | getClass(id) {
23 | return _editModes[id] || null;
24 | }
25 |
26 | getRegistered() {
27 | var ret = {};
28 | for (var id in _editModes) {
29 | if (Object.prototype.hasOwnProperty.call(_editModes, id)) {
30 | ret[id] = _editModes[id];
31 | }
32 | }
33 | return ret; // shallow copy.
34 | }
35 | }
36 |
37 |
38 | export var theEditModeManager = new EditModeManager();
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteCloud.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateCloud } from './CreateCloud';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param cloud
10 | * @constructor
11 | */
12 | export function DeleteCloud(editor, cloud) {
13 |
14 | EditAction.call(this, editor, 'DELETE-CLOUD', cloud.id);
15 | this.createCloud = new CreateCloud(
16 | editor,
17 | cloud.id,
18 | cloud.position,
19 | cloud.size,
20 | cloud.rotation,
21 | cloud.getStyle());
22 | }
23 |
24 | DeleteCloud.prototype = Object.create(EditAction.prototype);
25 | DeleteCloud.prototype.constructor = DeleteCloud;
26 |
27 | var proto = DeleteCloud.prototype;
28 |
29 | proto.redo = function() {
30 |
31 | this.createCloud.undo();
32 | };
33 |
34 | proto.undo = function() {
35 |
36 | this.createCloud.redo();
37 | };
38 |
39 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetStyle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { cloneStyle } from '../StyleUtils';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param markup
10 | * @param style
11 | * @constructor
12 | */
13 | export function SetStyle(editor, markup, style) {
14 |
15 | EditAction.call(this, editor, 'SET-STYLE', markup.id);
16 |
17 | this.newStyle = cloneStyle(style);
18 | this.oldStyle = markup.getStyle();
19 | }
20 |
21 | SetStyle.prototype = Object.create(EditAction.prototype);
22 | SetStyle.prototype.constructor = SetStyle;
23 |
24 | var proto = SetStyle.prototype;
25 |
26 | proto.redo = function() {
27 |
28 | var markup = this.editor.getMarkup(this.targetId);
29 | markup && markup.setStyle(this.newStyle);
30 | };
31 |
32 | proto.undo = function() {
33 |
34 | var markup = this.editor.getMarkup(this.targetId);
35 | markup && markup.setStyle(this.oldStyle);
36 | };
37 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteFreehand.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateFreehand } from './CreateFreehand';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param freehand
10 | * @constructor
11 | */
12 | export function DeleteFreehand(editor, freehand) {
13 | EditAction.call(this, editor, 'DELETE-FREEHAND', freehand.id);
14 | this.createFreehand = new CreateFreehand(
15 | editor,
16 | freehand.id,
17 | freehand.position,
18 | freehand.size,
19 | freehand.rotation,
20 | freehand.locations,
21 | freehand.getStyle());
22 | }
23 |
24 | DeleteFreehand.prototype = Object.create(EditAction.prototype);
25 | DeleteFreehand.prototype.constructor = DeleteFreehand;
26 |
27 | var proto = DeleteFreehand.prototype;
28 |
29 | proto.redo = function() {
30 |
31 | this.createFreehand.undo();
32 | };
33 |
34 | proto.undo = function() {
35 |
36 | this.createFreehand.redo();
37 | };
38 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteRectangle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateRectangle } from './CreateRectangle';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param rectangle
10 | * @constructor
11 | */
12 | export var DeleteRectangle = function(editor, rectangle) {
13 |
14 | EditAction.call(this, editor, 'DELETE-RECTANGLE', rectangle.id);
15 | this.createRectangle = new CreateRectangle(
16 | editor,
17 | rectangle.id,
18 | rectangle.position,
19 | rectangle.size,
20 | rectangle.rotation,
21 | rectangle.getStyle());
22 | };
23 |
24 | DeleteRectangle.prototype = Object.create(EditAction.prototype);
25 | DeleteRectangle.prototype.constructor = DeleteRectangle;
26 |
27 | var proto = DeleteRectangle.prototype;
28 |
29 | proto.redo = function() {
30 |
31 | this.createRectangle.undo();
32 | };
33 |
34 | proto.undo = function() {
35 |
36 | this.createRectangle.redo();
37 | };
38 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteText.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateText } from './CreateText';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param text
10 | * @constructor
11 | */
12 | export function DeleteText(editor, text) {
13 |
14 | EditAction.call(this, editor, 'DELETE-TEXT', text.id);
15 |
16 | var position = {x: text.position.x, y: text.position.y};
17 | var size = {x: text.size.x, y: text.size.y};
18 |
19 | this.createText = new CreateText(
20 | editor,
21 | text.id,
22 | position,
23 | size,
24 | text.getText(),
25 | text.getStyle());
26 | }
27 |
28 | DeleteText.prototype = Object.create(EditAction.prototype);
29 | DeleteText.prototype.constructor = DeleteText;
30 |
31 | var proto = DeleteText.prototype;
32 |
33 | proto.redo = function() {
34 |
35 | this.createText.undo();
36 | };
37 |
38 | proto.undo = function() {
39 |
40 | this.createText.redo();
41 | };
42 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteHighlight.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateHighlight } from './CreateHighlight';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param highlight
10 | * @constructor
11 | */
12 | export function DeleteHighlight(editor, highlight) {
13 | EditAction.call(this, editor, 'DELETE-HIGHLIGHT', highlight.id);
14 | this.createHighlight = new CreateHighlight(
15 | editor,
16 | highlight.id,
17 | highlight.position,
18 | highlight.size,
19 | highlight.rotation,
20 | highlight.locations,
21 | highlight.getStyle());
22 | }
23 |
24 | DeleteHighlight.prototype = Object.create(EditAction.prototype);
25 | DeleteHighlight.prototype.constructor = DeleteHighlight;
26 |
27 | var proto = DeleteHighlight.prototype;
28 |
29 | proto.redo = function() {
30 |
31 | this.createHighlight.undo();
32 | };
33 |
34 | proto.undo = function() {
35 |
36 | this.createHighlight.redo();
37 | };
38 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeletePolyline.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreatePolyline } from './CreatePolyline';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param polyline
10 | * @constructor
11 | */
12 | export function DeletePolyline(editor, polyline) {
13 |
14 | EditAction.call(this, editor, 'DELETE-POLYLINE', polyline.id);
15 | this.createPolyline = new CreatePolyline(
16 | editor,
17 | polyline.id,
18 | polyline.position,
19 | polyline.size,
20 | polyline.rotation,
21 | polyline.locations,
22 | polyline.getStyle(),
23 | polyline.closed);
24 | }
25 |
26 | DeletePolyline.prototype = Object.create(EditAction.prototype);
27 | DeletePolyline.prototype.constructor = DeletePolyline;
28 |
29 | var proto = DeletePolyline.prototype;
30 |
31 | proto.redo = function() {
32 |
33 | this.createPolyline.undo();
34 | };
35 |
36 | proto.undo = function() {
37 |
38 | this.createPolyline.redo();
39 | };
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 wallabyway
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeletePolycloud.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreatePolycloud } from './CreatePolycloud';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param polycloud
10 | * @constructor
11 | */
12 | export function DeletePolycloud(editor, polycloud) {
13 |
14 | EditAction.call(this, editor, 'DELETE-POLYCLOUD', polycloud.id);
15 | this.createPolycloud = new CreatePolycloud(
16 | editor,
17 | polycloud.id,
18 | polycloud.position,
19 | polycloud.size,
20 | polycloud.rotation,
21 | polycloud.locations,
22 | polycloud.getStyle(),
23 | polycloud.closed);
24 | }
25 |
26 | DeletePolycloud.prototype = Object.create(EditAction.prototype);
27 | DeletePolycloud.prototype.constructor = DeletePolycloud;
28 |
29 | var proto = DeletePolycloud.prototype;
30 |
31 | proto.redo = function() {
32 |
33 | this.createPolycloud.undo();
34 | };
35 |
36 | proto.undo = function() {
37 |
38 | this.createPolycloud.redo();
39 | };
40 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteCallout.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateCallout } from './CreateCallout';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param text
10 | * @constructor
11 | */
12 | export function DeleteCallout(editor, callout) {
13 |
14 | EditAction.call(this, editor, 'DELETE-CALLOUT', callout.id);
15 |
16 | var position = {x: callout.position.x, y: callout.position.y};
17 | var size = {x: callout.size.x, y: callout.size.y};
18 |
19 | this.createCallout = new CreateCallout(
20 | editor,
21 | callout.id,
22 | position,
23 | size,
24 | callout.getText(),
25 | callout.getStyle(),
26 | callout.isFrameUsed);
27 | }
28 |
29 | DeleteCallout.prototype = Object.create(EditAction.prototype);
30 | DeleteCallout.prototype.constructor = DeleteCallout;
31 |
32 | var proto = DeleteCallout.prototype;
33 |
34 | proto.redo = function() {
35 |
36 | this.createCallout.undo();
37 | };
38 |
39 | proto.undo = function() {
40 |
41 | this.createCallout.redo();
42 | };
43 |
44 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteArrow.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateArrow } from './CreateArrow';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param arrow
10 | * @constructor
11 | */
12 | export function DeleteArrow(editor, arrow) {
13 |
14 | // Confusing naming here. Arrow.tail is the starting point of the arrow,
15 | // and arrow.head is the final point. In CreateArrow the head argument
16 | // is the first point of the arrow and the tail argument is the second
17 | // point of the argument. So construct CreateArrow with the tail before
18 | // the head.
19 | EditAction.call(this, editor, 'DELETE-ARROW', arrow.id);
20 | this.createArrow = new CreateArrow(
21 | editor,
22 | arrow.id,
23 | arrow.tail,
24 | arrow.head,
25 | arrow.getStyle());
26 | }
27 |
28 | DeleteArrow.prototype = Object.create(EditAction.prototype);
29 | DeleteArrow.prototype.constructor = DeleteArrow;
30 |
31 | var proto = DeleteArrow.prototype;
32 |
33 | proto.redo = function() {
34 |
35 | this.createArrow.undo();
36 | };
37 |
38 | proto.undo = function() {
39 |
40 | this.createArrow.redo();
41 | };
42 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetText.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param markup
9 | * @param position
10 | * @param size
11 | * @param text
12 | * @constructor
13 | */
14 | export function SetText(editor, markup, position, size, text) {
15 |
16 | EditAction.call(this, editor, 'SET-TEXT', markup.id);
17 |
18 | this.newPosition = {x: position.x, y: position.y};
19 | this.oldPosition = {x: markup.position.x, y: markup.position.y};
20 | this.newSize = {x: size.x, y: size.y};
21 | this.oldSize = {x: markup.size.x, y: markup.size.y};
22 | this.newText = text;
23 | this.oldText = markup.getText();
24 | }
25 |
26 | SetText.prototype = Object.create(EditAction.prototype);
27 | SetText.prototype.constructor = SetText;
28 |
29 | var proto = SetText.prototype;
30 |
31 | proto.redo = function() {
32 |
33 | var text = this.editor.getMarkup(this.targetId);
34 | text && text.set(this.newPosition, this.newSize, this.newText);
35 | };
36 |
37 | proto.undo = function() {
38 |
39 | var text = this.editor.getMarkup(this.targetId);
40 | text && text.set(this.oldPosition, this.oldSize, this.oldText);
41 | };
42 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CloneMarkup.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param id
9 | * @param markup
10 | * @param position
11 | * @constructor
12 | */
13 | export function CloneMarkup(editor, id, markup, position) {
14 |
15 | EditAction.call(this, editor, 'CLONE-MARKUP', id);
16 |
17 | this.clone = markup.clone();
18 | this.clone.id = id;
19 | this.position = {x: position.x, y: position.y};
20 | }
21 |
22 | CloneMarkup.prototype = Object.create(EditAction.prototype);
23 | CloneMarkup.prototype.constructor = CloneMarkup;
24 |
25 | var proto = CloneMarkup.prototype;
26 |
27 | proto.redo = function() {
28 |
29 | var editor = this.editor;
30 | var clone = this.clone;
31 | var position = this.position;
32 |
33 | if (editor.getMarkup(this.targetId)) {
34 | return;
35 | }
36 |
37 | var markup = clone.clone();
38 | markup.setPosition(position.x, position.y);
39 |
40 | editor.addMarkup(markup);
41 | };
42 |
43 | proto.undo = function() {
44 |
45 | var markup = this.editor.getMarkup(this.targetId);
46 | markup && this.editor.removeMarkup(markup);
47 | };
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateStamp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupStamp } from '../MarkupStamp';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | export { CreateStamp };
8 |
9 | /**
10 | * @constructor
11 | *
12 | * @param editor
13 | * @param id
14 | * @param position
15 | * @param size
16 | * @param style
17 | * @param {string} svg
18 | */
19 |
20 | class CreateStamp extends EditAction {
21 | constructor(editor, id, position, size, rotation, style, svgData) {
22 | super(editor, 'CREATE-STAMP', id);
23 |
24 | this.selectOnExecution = false;
25 | this.position = {x: position.x, y: position.y};
26 | this.size = {x: size.x, y: size.y};
27 | this.rotation = rotation;
28 | this.style = cloneStyle(style);
29 | this.svgData = svgData;
30 | }
31 |
32 | redo() {
33 | const stamp = new MarkupStamp(this.targetId, this.editor, this.svgData);
34 |
35 | this.editor.addMarkup(stamp);
36 |
37 | stamp.setSize(this.position, this.size.x, this.size.y);
38 | stamp.setRotation(this.rotation);
39 | stamp.setStyle(this.style);
40 | }
41 |
42 | undo() {
43 | const markup = this.editor.getMarkup(this.targetId);
44 | this.editor.removeMarkup(markup);
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateCloud.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupCloud } from '../MarkupCloud';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param rotation
14 | * @param style
15 | * @constructor
16 | */
17 | export function CreateCloud(editor, id, position, size, rotation, style) {
18 |
19 | EditAction.call(this, editor, 'CREATE-CLOUD', id);
20 |
21 | this.selectOnExecution = false;
22 | this.position = {x: position.x, y: position.y};
23 | this.size = {x: size.x, y: size.y};
24 | this.rotation = rotation;
25 | this.style = cloneStyle(style);
26 | }
27 |
28 | CreateCloud.prototype = Object.create(EditAction.prototype);
29 | CreateCloud.prototype.constructor = CreateCloud;
30 |
31 | var proto = CreateCloud.prototype;
32 |
33 | proto.redo = function() {
34 |
35 | var editor = this.editor;
36 | var cloud = new MarkupCloud(this.targetId, editor);
37 |
38 | editor.addMarkup(cloud);
39 |
40 | cloud.set(this.position, this.size);
41 | cloud.setRotation(this.rotation);
42 | cloud.setStyle(this.style);
43 | };
44 |
45 | proto.undo = function() {
46 |
47 | var markup = this.editor.getMarkup(this.targetId);
48 | markup && this.editor.removeMarkup(markup);
49 | };
50 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetCallout.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param markup
9 | * @param position
10 | * @param size
11 | * @param text
12 | * @constructor
13 | */
14 | export function SetCallout(editor, markup, position, size, text, isFrameUsed) {
15 |
16 | EditAction.call(this, editor, 'SET-CALLOUT', markup.id);
17 |
18 | this.newPosition = {x: position.x, y: position.y};
19 | this.oldPosition = {x: markup.position.x, y: markup.position.y};
20 | this.newSize = {x: size.x, y: size.y};
21 | this.oldSize = {x: markup.size.x, y: markup.size.y};
22 | this.newText = text;
23 | this.oldText = markup.getText();
24 | this.newIsFrameUsed = isFrameUsed;
25 | this.oldIsFrameUsed = markup.isFrameUsed;
26 | }
27 |
28 | SetCallout.prototype = Object.create(EditAction.prototype);
29 | SetCallout.prototype.constructor = SetCallout;
30 |
31 | var proto = SetCallout.prototype;
32 |
33 | proto.redo = function() {
34 |
35 | var callout = this.editor.getMarkup(this.targetId);
36 | callout && callout.set(this.newPosition, this.newSize, this.newText, this.newIsFrameUsed);
37 | };
38 |
39 | proto.undo = function() {
40 |
41 | var callout = this.editor.getMarkup(this.targetId);
42 | callout && callout.set(this.oldPosition, this.oldSize, this.oldText, this.oldIsFrameUsed);
43 | };
44 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteDimension.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateDimension } from './CreateDimension';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @param dimension
10 | * @constructor
11 | */
12 | export function DeleteDimension(editor, dimension) {
13 |
14 | // Confusing naming here. Dimension.secondAnchor is the starting point of the dimension,
15 | // and dimension.firstAnchor is the final point. In CreateDimension the firstAnchor argument
16 | // is the first point of the dimension and the secondAnchor argument is the second
17 | // point of the argument. So construct CreateDimension with the secondAnchor before
18 | // the firstAnchor.
19 | EditAction.call(this, editor, 'DELETE-DIMENSION', dimension.id);
20 | this.createDimension = new CreateDimension(
21 | editor,
22 | dimension.id,
23 | dimension.secondAnchor,
24 | dimension.firstAnchor,
25 | dimension.currentText,
26 | dimension.getStyle());
27 | }
28 |
29 | DeleteDimension.prototype = Object.create(EditAction.prototype);
30 | DeleteDimension.prototype.constructor = DeleteDimension;
31 |
32 | var proto = DeleteDimension.prototype;
33 |
34 | proto.redo = function() {
35 |
36 | this.createDimension.undo();
37 | };
38 |
39 | proto.undo = function() {
40 |
41 | this.createDimension.redo();
42 | };
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateText.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupText } from '../MarkupText';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param text
14 | * @param style
15 | * @constructor
16 | */
17 | export function CreateText(editor, id, position, size, text, style ) {
18 |
19 | EditAction.call(this, editor, 'CREATE-TEXT', id);
20 |
21 | this.text = text;
22 | this.position = {x: position.x, y: position.y};
23 | this.size = {x: size.x, y: size.y};
24 | this.style = cloneStyle(style);
25 | }
26 |
27 | CreateText.prototype = Object.create(EditAction.prototype);
28 | CreateText.prototype.constructor = CreateText;
29 |
30 | var proto = CreateText.prototype;
31 |
32 | proto.redo = function () {
33 |
34 | var editor = this.editor;
35 | var position = this.position;
36 | var size = this.size;
37 |
38 | var text = new MarkupText(this.targetId, editor, size);
39 |
40 | editor.addMarkup(text);
41 |
42 | text.set(position, size, this.text);
43 | text.setStyle(this.style);
44 | };
45 |
46 | proto.undo = function () {
47 |
48 | var markup = this.editor.getMarkup(this.targetId);
49 | if (markup) {
50 | this.editor.removeMarkup(markup);
51 | markup.destroy();
52 | }
53 | };
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateRectangle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupRectangle } from '../MarkupRectangle';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param rotation
14 | * @param style
15 | * @constructor
16 | */
17 | export function CreateRectangle(editor, id, position, size, rotation, style) {
18 |
19 | EditAction.call(this, editor, 'CREATE-RECTANGLE', id);
20 |
21 | this.selectOnExecution = false;
22 | this.position = {x: position.x, y: position.y};
23 | this.size = {x: size.x, y: size.y};
24 | this.rotation = rotation;
25 | this.style = cloneStyle(style);
26 | }
27 |
28 | CreateRectangle.prototype = Object.create(EditAction.prototype);
29 | CreateRectangle.prototype.constructor = CreateRectangle;
30 |
31 | var proto = CreateRectangle.prototype;
32 |
33 | proto.redo = function() {
34 |
35 | var editor = this.editor;
36 | var rectangle = new MarkupRectangle(this.targetId, editor);
37 |
38 | editor.addMarkup(rectangle);
39 |
40 | rectangle.set(this.position, this.size);
41 | rectangle.setRotation(this.rotation);
42 | rectangle.setStyle(this.style);
43 | };
44 |
45 | proto.undo = function() {
46 |
47 | var markup = this.editor.getMarkup(this.targetId);
48 | markup && this.editor.removeMarkup(markup);
49 | };
50 |
51 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateDimension.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupDimension } from '../MarkupDimension';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | * @constructor
9 | */
10 | export function CreateDimension(editor, id, firstAnchor, secondAnchor, text, style) {
11 |
12 | EditAction.call(this, editor, 'CREATE-DIMENSION', id);
13 |
14 | this.selectOnExecution = false;
15 | this.secondAnchor = secondAnchor;
16 | this.firstAnchor = firstAnchor;
17 | this.text = text;
18 | this.style = cloneStyle(style);
19 | }
20 |
21 | CreateDimension.prototype = Object.create(EditAction.prototype);
22 | CreateDimension.prototype.constructor = CreateDimension;
23 |
24 | var proto = CreateDimension.prototype;
25 |
26 | proto.redo = function() {
27 |
28 | var editor = this.editor;
29 | var dimension = new MarkupDimension(this.targetId, editor);
30 |
31 | editor.addMarkup(dimension);
32 |
33 | // Don't display the dimension markup when there is only one Anchor (First click, before mouse move).
34 | if (this.secondAnchor) {
35 | dimension.set(this.firstAnchor.x, this.firstAnchor.y, this.secondAnchor.x, this.secondAnchor.y, this.text);
36 | dimension.setStyle(this.style);
37 | }
38 | };
39 |
40 | proto.undo = function() {
41 |
42 | var markup = this.editor.getMarkup(this.targetId);
43 | markup && this.editor.removeMarkup(markup);
44 | };
45 |
46 |
47 |
--------------------------------------------------------------------------------
/Markup/core/edit-modes/EditModeFreehand.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditModePen } from './EditModePen';
4 | import { DeleteFreehand } from '../edit-actions/DeleteFreehand';
5 | import { CreateFreehand } from '../edit-actions/CreateFreehand';
6 | import { SetFreehand } from '../edit-actions/SetFreehand';
7 | import * as MarkupTypes from '../MarkupTypes';
8 |
9 | /**
10 | *
11 | * @param editor
12 | * @constructor
13 | */
14 | export function EditModeFreehand(editor) {
15 |
16 | var styleAttributes = ['stroke-width', 'stroke-color', 'stroke-opacity'];
17 | EditModePen.call(this, editor, MarkupTypes.MARKUP_TYPE_FREEHAND, styleAttributes);
18 | }
19 |
20 | EditModeFreehand.prototype = Object.create(EditModePen.prototype);
21 | EditModeFreehand.prototype.constructor = EditModeFreehand;
22 |
23 | var proto = EditModeFreehand.prototype;
24 |
25 | proto.createPen = function(markupId, position, size, rotation, locations) {
26 | return new CreateFreehand(this.editor,
27 | markupId,
28 | position,
29 | size,
30 | rotation,
31 | locations,
32 | this.style);
33 | };
34 |
35 | proto.deletePen = function(markup) {
36 | return new DeleteFreehand(this.editor, markup);
37 | };
38 |
39 | proto.setPen = function(position, size, locations, isAbsoluteCoords) {
40 | return new SetFreehand(this.editor,
41 | this.selectedMarkup,
42 | position,
43 | size,
44 | locations,
45 | isAbsoluteCoords);
46 | };
47 |
48 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateFreehand.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupFreehand } from '../MarkupFreehand';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param rotation
14 | * @param locations
15 | * @param style
16 | * @constructor
17 | */
18 | export function CreateFreehand(editor, id, position, size, rotation, locations, style) {
19 |
20 | EditAction.call(this, editor, 'CREATE-FREEHAND', id);
21 |
22 | this.selectOnExecution = false;
23 | this.position = position;
24 | this.size = size;
25 | this.rotation = rotation;
26 | this.movements = locations.slice(0);
27 | this.style = cloneStyle(style);
28 | }
29 |
30 | CreateFreehand.prototype = Object.create(EditAction.prototype);
31 | CreateFreehand.prototype.constructor = CreateFreehand;
32 |
33 | var proto = CreateFreehand.prototype;
34 |
35 | proto.redo = function() {
36 |
37 | var editor = this.editor;
38 | var freehand = new MarkupFreehand(this.targetId, editor);
39 |
40 | editor.addMarkup(freehand);
41 |
42 | freehand.set(this.position, this.size, this.movements, false);
43 | freehand.setRotation(this.rotation);
44 | freehand.setStyle(this.style);
45 | };
46 |
47 | proto.undo = function() {
48 |
49 | var markup = this.editor.getMarkup(this.targetId);
50 | markup && this.editor.removeMarkup(markup);
51 | };
52 |
53 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateHighlight.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupHighlight } from '../MarkupHighlight';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param rotation
14 | * @param locations
15 | * @param style
16 | * @constructor
17 | */
18 | export function CreateHighlight(editor, id, position, size, rotation, locations, style) {
19 |
20 | EditAction.call(this, editor, 'CREATE-HIGHLIGHT', id);
21 |
22 | this.selectOnExecution = false;
23 | this.position = position;
24 | this.size = size;
25 | this.rotation = rotation;
26 | this.movements = locations.slice(0);
27 | this.style = cloneStyle(style);
28 | }
29 |
30 | CreateHighlight.prototype = Object.create(EditAction.prototype);
31 | CreateHighlight.prototype.constructor = CreateHighlight;
32 |
33 | var proto = CreateHighlight.prototype;
34 |
35 | proto.redo = function() {
36 |
37 | var editor = this.editor;
38 | var highlight = new MarkupHighlight(this.targetId, editor);
39 |
40 | editor.addMarkup(highlight);
41 |
42 | highlight.set(this.position, this.size, this.movements, false);
43 | highlight.setRotation(this.rotation);
44 | highlight.setStyle(this.style);
45 | };
46 |
47 | proto.undo = function() {
48 |
49 | var markup = this.editor.getMarkup(this.targetId);
50 | markup && this.editor.removeMarkup(markup);
51 | };
52 |
53 |
54 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateArrow.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupArrow } from '../MarkupArrow';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | * @constructor
9 | */
10 | export function CreateArrow(editor, id, head, tail, style) {
11 |
12 | EditAction.call(this, editor, 'CREATE-ARROW', id);
13 |
14 | this.selectOnExecution = false;
15 | this.tail = tail;
16 | this.head = head;
17 | this.style = cloneStyle(style);
18 | }
19 |
20 | CreateArrow.prototype = Object.create(EditAction.prototype);
21 | CreateArrow.prototype.constructor = CreateArrow;
22 |
23 | var proto = CreateArrow.prototype;
24 |
25 | proto.redo = function() {
26 |
27 | var editor = this.editor;
28 | var arrow = new MarkupArrow(this.targetId, editor);
29 |
30 | editor.addMarkup(arrow);
31 |
32 | // Confusing naming here. in arrow.set the first two numbers are
33 | // the point you drag from and the second two are the point you
34 | // drag to. So the head point is actually where the tail of the
35 | // arrow is positioned and the tail point is the head is positioned.
36 |
37 | //TODO: In MarkupArrow "set" function has tail x, tail y, head x, head y but used here in the opposite way
38 | arrow.set(this.head.x, this.head.y, this.tail.x, this.tail.y);
39 | arrow.setStyle(this.style);
40 | };
41 |
42 | proto.undo = function() {
43 |
44 | var markup = this.editor.getMarkup(this.targetId);
45 | markup && this.editor.removeMarkup(markup);
46 | };
47 |
48 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetRotation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param markup
9 | * @param angle
10 | * @constructor
11 | */
12 | export function SetRotation(editor, markup, angle) {
13 |
14 | EditAction.call(this, editor, 'SET-ROTATION', markup.id);
15 |
16 | var curAngle = markup.getRotation();
17 |
18 | this.newRotation = {angle: angle};
19 | this.oldRotation = {angle: curAngle};
20 | }
21 |
22 | SetRotation.prototype = Object.create(EditAction.prototype);
23 | SetRotation.prototype.constructor = SetRotation;
24 |
25 | var proto = SetRotation.prototype;
26 |
27 | proto.redo = function() {
28 |
29 | var markup = this.editor.getMarkup(this.targetId);
30 | markup && markup.setRotation(this.newRotation.angle);
31 | };
32 |
33 | proto.undo = function() {
34 |
35 | var markup = this.editor.getMarkup(this.targetId);
36 | markup && markup.setRotation(this.oldRotation.angle);
37 | };
38 |
39 | /**
40 | *
41 | * @param action
42 | * @returns {boolean}
43 | */
44 | proto.merge = function(action) {
45 |
46 | if (this.targetId === action.targetId &&
47 | this.type === action.type) {
48 |
49 | this.newRotation = action.newRotation;
50 | return true;
51 | }
52 | return false;
53 | };
54 |
55 | /**
56 | * @returns {boolean}
57 | */
58 | proto.isIdentity = function() {
59 |
60 | return this.newRotation.angle === this.oldRotation.angle;
61 | };
62 |
63 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetPosition.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | export function SetPosition(editor, markup, position) {
6 |
7 | EditAction.call(this, editor, 'SET-POSITION', markup.id);
8 |
9 | this.newPosition = {x: position.x, y: position.y};
10 | this.oldPosition = {x: markup.position.x, y: markup.position.y};
11 | }
12 |
13 | SetPosition.prototype = Object.create(EditAction.prototype);
14 | SetPosition.prototype.constructor = SetPosition;
15 |
16 | var proto = SetPosition.prototype;
17 |
18 | proto.redo = function() {
19 |
20 | var markup = this.editor.getMarkup(this.targetId);
21 | markup && markup.setPosition(this.newPosition.x, this.newPosition.y);
22 | };
23 |
24 | proto.undo = function() {
25 |
26 | var markup = this.editor.getMarkup(this.targetId);
27 | markup && markup.setPosition(this.oldPosition.x, this.oldPosition.y);
28 | };
29 |
30 | /**
31 | *
32 | * @param action
33 | * @returns {boolean}
34 | */
35 | proto.merge = function(action) {
36 |
37 | if (this.targetId === action.targetId &&
38 | this.type === action.type) {
39 |
40 | this.newPosition = action.newPosition;
41 | return true;
42 | }
43 | return false;
44 | };
45 |
46 | /**
47 | * @returns {boolean}
48 | */
49 | proto.isIdentity = function() {
50 |
51 | var newPosition = this.newPosition;
52 | var oldPosition = this.oldPosition;
53 |
54 | return newPosition.x === oldPosition.x && newPosition.y === oldPosition.y;
55 | };
56 |
57 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreatePolyline.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupPolyline } from '../MarkupPolyLine';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param rotation
14 | * @param locations
15 | * @param closed
16 | * @param style
17 | * @constructor
18 | */
19 | export function CreatePolyline(editor, id, position, size, rotation, locations, style, closed) {
20 |
21 | EditAction.call(this, editor, 'CREATE-POLYLINE', id);
22 |
23 | this.selectOnExecution = false;
24 | this.position = position;
25 | this.size = size;
26 | this.rotation = rotation;
27 | this.movements = locations.concat();
28 | this.closed = closed;
29 | this.style = cloneStyle(style);
30 | }
31 |
32 | CreatePolyline.prototype = Object.create(EditAction.prototype);
33 | CreatePolyline.prototype.constructor = CreatePolyline;
34 |
35 | var proto = CreatePolyline.prototype;
36 |
37 | proto.redo = function() {
38 |
39 | var editor = this.editor;
40 | var polyline = new MarkupPolyline(this.targetId, editor);
41 |
42 | editor.addMarkup(polyline);
43 |
44 | polyline.set(this.position, this.size, this.movements, this.closed);
45 | polyline.setRotation(this.rotation);
46 | polyline.setStyle(this.style);
47 | };
48 |
49 | proto.undo = function() {
50 |
51 | var markup = this.editor.getMarkup(this.targetId);
52 | markup && this.editor.removeMarkup(markup);
53 | };
54 |
55 |
--------------------------------------------------------------------------------
/Markup/core/edit-clipboard/Clipboard.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { CloneMarkup } from '../edit-actions/CloneMarkup';
4 | import { addTraitEventDispatcher } from '../MarkupsCoreUtils';
5 |
6 | /**
7 | *
8 | * @param editor
9 | * @constructor
10 | */
11 | export function Clipboard(editor) {
12 |
13 | this.editor = editor;
14 | this.content = null;
15 | this.pastePosition = {x:0, y: 0};
16 |
17 | addTraitEventDispatcher(this);
18 | }
19 |
20 | var proto = Clipboard.prototype;
21 |
22 | proto.copy = function() {
23 |
24 | var selectedMarkup = this.editor.getSelection();
25 | if(!selectedMarkup) {
26 | return;
27 | }
28 |
29 | this.content = selectedMarkup.clone();
30 | this.pastePosition.x = selectedMarkup.position.x;
31 | this.pastePosition.y = selectedMarkup.position.y;
32 | };
33 |
34 | proto.cut = function() {
35 |
36 | var selectedMarkup = this.editor.getSelection();
37 | if(!selectedMarkup) {
38 | return;
39 | }
40 |
41 | this.copy();
42 | this.editor.deleteMarkup(selectedMarkup);
43 | };
44 |
45 | proto.paste = function() {
46 |
47 | var content = this.content;
48 | if(!content) {
49 | return;
50 | }
51 |
52 | var editor = this.editor;
53 | var position = this.pastePosition;
54 | var delta = editor.sizeFromClientToMarkups(20, 20);
55 |
56 | position.x += delta.x;
57 | position.y -= delta.y;
58 |
59 | var cloneMarkup = new CloneMarkup(editor, editor.getId(), content, position);
60 | cloneMarkup.execute();
61 | };
62 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreatePolycloud.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupPolycloud } from '../MarkupPolycloud';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param rotation
14 | * @param locations
15 | * @param closed
16 | * @param style
17 | * @constructor
18 | */
19 | export function CreatePolycloud(editor, id, position, size, rotation, locations, style, closed) {
20 |
21 | EditAction.call(this, editor, 'CREATE-POLYCLOUD', id);
22 |
23 | this.selectOnExecution = false;
24 | this.position = position;
25 | this.size = size;
26 | this.rotation = rotation;
27 | this.movements = locations.concat();
28 | this.style = cloneStyle(style);
29 | this.closed = closed;
30 | }
31 |
32 | CreatePolycloud.prototype = Object.create(EditAction.prototype);
33 | CreatePolycloud.prototype.constructor = CreatePolycloud;
34 |
35 | var proto = CreatePolycloud.prototype;
36 |
37 | proto.redo = function() {
38 |
39 | var editor = this.editor;
40 | var polyline = new MarkupPolycloud(this.targetId, editor);
41 |
42 | editor.addMarkup(polyline);
43 |
44 | polyline.set(this.position, this.size, this.movements, this.closed);
45 | polyline.setRotation(this.rotation);
46 | polyline.setStyle(this.style);
47 | };
48 |
49 | proto.undo = function() {
50 |
51 | var markup = this.editor.getMarkup(this.targetId);
52 | markup && this.editor.removeMarkup(markup);
53 | };
54 |
55 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/DeleteCircle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { CreateCircle } from './CreateCircle';
5 |
6 | /**
7 | * Markup delete circle action.
8 | *
9 | * Implements an {@link Autodesk.Viewing.Extensions.Markups.Core.EditAction|EditAction}
10 | * for deleting a Circle {@link Autodesk.Viewing.Extensions.Markups.Core.Markup|Markup}.
11 | * Included in documentation as an example of how to create
12 | * a specific EditAction that deals with Markup deletion.
13 | * Developers are encourage to look into this class's source code and copy
14 | * as much code as they need. Find link to source code below.
15 | *
16 | * @tutorial feature_markup
17 | * @constructor
18 | * @memberof Autodesk.Viewing.Extensions.Markups.Core
19 | * @extends Autodesk.Viewing.Extensions.Markups.Core.EditAction
20 | *
21 | * @param editor
22 | * @param circle
23 | */
24 | export function DeleteCircle(editor, circle) {
25 |
26 | EditAction.call(this, editor, 'DELETE-CIRCLE', circle.id);
27 | this.createCircle = new CreateCircle(
28 | editor,
29 | circle.id,
30 | circle.position,
31 | circle.size,
32 | circle.rotation,
33 | circle.getStyle());
34 | }
35 |
36 | DeleteCircle.prototype = Object.create(EditAction.prototype);
37 | DeleteCircle.prototype.constructor = DeleteCircle;
38 |
39 | var proto = DeleteCircle.prototype;
40 |
41 | proto.redo = function() {
42 |
43 | this.createCircle.undo();
44 | };
45 |
46 | proto.undo = function() {
47 |
48 | this.createCircle.redo();
49 | };
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateCallout.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupCallout } from '../MarkupCallout';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | *
9 | * @param editor
10 | * @param id
11 | * @param position
12 | * @param size
13 | * @param text
14 | * @param style
15 | * @constructor
16 | */
17 | export function CreateCallout(editor, id, position, size, text, style, isFrameUsed) {
18 |
19 | EditAction.call(this, editor, 'CREATE-CALLOUT', id);
20 |
21 | this.text = text;
22 | this.position = {x: position.x, y: position.y};
23 | this.size = {x: size.x, y: size.y};
24 | this.style = cloneStyle(style);
25 | this.isFrameUsed = isFrameUsed;
26 | }
27 |
28 | CreateCallout.prototype = Object.create(EditAction.prototype);
29 | CreateCallout.prototype.constructor = CreateCallout;
30 |
31 | var proto = CreateCallout.prototype;
32 |
33 | proto.redo = function () {
34 |
35 | var editor = this.editor;
36 | var position = this.position;
37 | var size = this.size;
38 |
39 | var callout = new MarkupCallout(this.targetId, editor, size);
40 |
41 | editor.addMarkup(callout);
42 |
43 | callout.setIsFilledFrameUsed(this.isFrameUsed);
44 | callout.setText(this.text);
45 | callout.setSize(position, size.x, size.y);
46 | callout.setStyle(this.style);
47 | };
48 |
49 | proto.undo = function () {
50 |
51 | var markup = this.editor.getMarkup(this.targetId);
52 | if (markup) {
53 | this.editor.removeMarkup(markup);
54 | markup.destroy();
55 | }
56 | };
57 |
58 |
--------------------------------------------------------------------------------
/Markup/core/edit-modes/BuiltinEditModes.js:
--------------------------------------------------------------------------------
1 |
2 | import { theEditModeManager } from '../EditModeManager';
3 | import * as MarkupTypes from '../MarkupTypes';
4 |
5 | import { EditModeArrow } from './EditModeArrow';
6 | import { EditModeText } from './EditModeText';
7 | import { EditModeRectangle } from './EditModeRectangle';
8 | import { EditModeCircle } from './EditModeCircle';
9 | import { EditModeCloud } from './EditModeCloud';
10 | import { EditModeFreehand } from './EditModeFreehand';
11 | import { EditModeHighlight } from './EditModeHighlight';
12 | import { EditModePolyline } from './EditModePolyline';
13 | import { EditModePolycloud } from './EditModePolycloud';
14 | import { EditModeCallout } from './EditModeCallout';
15 | import { EditModeDimension } from './EditModeDimension';
16 | import { EditModeStamp } from './EditModeStamp';
17 |
18 |
19 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_ARROW, EditModeArrow);
20 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_TEXT, EditModeText);
21 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_RECTANGLE, EditModeRectangle);
22 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_CIRCLE, EditModeCircle);
23 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_CLOUD, EditModeCloud);
24 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_FREEHAND, EditModeFreehand);
25 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_HIGHLIGHT, EditModeHighlight);
26 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_POLYLINE, EditModePolyline);
27 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_POLYCLOUD, EditModePolycloud);
28 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_CALLOUT, EditModeCallout);
29 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_DIMENSION, EditModeDimension);
30 | theEditModeManager.register(MarkupTypes.MARKUP_TYPE_STAMP, EditModeStamp);
31 |
32 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetPolyline.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param polyline
9 | * @param position
10 | * @param size
11 | * @param locations
12 | * @param closed
13 | * @constructor
14 | */
15 | export function SetPolyline(editor, polyline, position, size, locations, closed) {
16 |
17 | EditAction.call(this, editor, 'SET-POLYLINE', polyline.id);
18 |
19 | this.position = position;
20 | this.size = size;
21 | this.locations = locations.concat();
22 | this.closed = closed;
23 |
24 | // No need to save old data
25 | }
26 |
27 | SetPolyline.prototype = Object.create(EditAction.prototype);
28 | SetPolyline.prototype.constructor = SetPolyline;
29 |
30 | var proto = SetPolyline.prototype;
31 |
32 | proto.redo = function() {
33 |
34 | var polyline = this.editor.getMarkup(this.targetId);
35 | if(!polyline) {
36 | return;
37 | }
38 |
39 | polyline.set(this.position, this.size, this.locations, this.closed);
40 | };
41 |
42 | proto.undo = function() {
43 | // No need for undo.
44 | };
45 |
46 | proto.merge = function(action) {
47 |
48 | if (this.targetId === action.targetId &&
49 | this.type === action.type) {
50 |
51 | this.locations = action.locations.concat();
52 | this.position = action.position;
53 | this.size = action.size;
54 | this.closed = action.closed;
55 | return true;
56 | }
57 | return false;
58 | };
59 |
60 | /**
61 | * @returns {boolean}
62 | */
63 | proto.isIdentity = function() {
64 |
65 | return false; // No need to optimize, always false.
66 | };
67 |
68 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetPolycloud.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param polycloud
9 | * @param position
10 | * @param size
11 | * @param locations
12 | * @param closed
13 | * @constructor
14 | */
15 | export function SetPolycloud(editor, polycloud, position, size, locations, closed) {
16 |
17 | EditAction.call(this, editor, 'SET-POLYCLOUD', polycloud.id);
18 |
19 | this.position = position;
20 | this.size = size;
21 | this.locations = locations.concat();
22 | this.closed = closed;
23 |
24 | // No need to save old data
25 | }
26 |
27 | SetPolycloud.prototype = Object.create(EditAction.prototype);
28 | SetPolycloud.prototype.constructor = SetPolycloud;
29 |
30 | var proto = SetPolycloud.prototype;
31 |
32 | proto.redo = function() {
33 |
34 | var polycloud = this.editor.getMarkup(this.targetId);
35 | if(!polycloud) {
36 | return;
37 | }
38 |
39 | polycloud.set(this.position, this.size, this.locations, this.closed);
40 | };
41 |
42 | proto.undo = function() {
43 | // No need for undo.
44 | };
45 |
46 | proto.merge = function(action) {
47 |
48 | if (this.targetId === action.targetId &&
49 | this.type === action.type) {
50 |
51 | this.locations = action.locations.concat();
52 | this.position = action.position;
53 | this.size = action.size;
54 | this.closed = action.closed;
55 | return true;
56 | }
57 | return false;
58 | };
59 |
60 | /**
61 | * @returns {boolean}
62 | */
63 | proto.isIdentity = function() {
64 |
65 | return false; // No need to optimize, always false.
66 | };
67 |
68 |
--------------------------------------------------------------------------------
/Markup/core/edit-modes/EditModeHighlight.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditModePen } from './EditModePen';
4 | import { DeleteHighlight } from '../edit-actions/DeleteHighlight';
5 | import { CreateHighlight } from '../edit-actions/CreateHighlight';
6 | import { SetHighlight } from '../edit-actions/SetHighlight';
7 | import * as MarkupTypes from '../MarkupTypes';
8 |
9 | /**
10 | *
11 | * @param editor
12 | * @constructor
13 | */
14 | export function EditModeHighlight(editor) {
15 |
16 | var styleAttributes = ['stroke-width', 'stroke-color', 'stroke-opacity'];
17 | EditModePen.call(this, editor, MarkupTypes.MARKUP_TYPE_HIGHLIGHT, styleAttributes);
18 |
19 | var normaStrokeWidth = editor.getStrokeWidth();
20 | this.style['stroke-opacity'] = 0.50;
21 | this.style['stroke-color'] = '#ffff00';
22 | this.style['stroke-width'] = 4 * normaStrokeWidth; // Very Thick
23 | }
24 |
25 | EditModeHighlight.prototype = Object.create(EditModePen.prototype);
26 | EditModeHighlight.prototype.constructor = EditModeHighlight;
27 |
28 | var proto = EditModeHighlight.prototype;
29 |
30 | proto.createPen = function(markupId, position, size, rotation, locations) {
31 | return new CreateHighlight(this.editor,
32 | markupId,
33 | position,
34 | size,
35 | rotation,
36 | locations,
37 | this.style);
38 | };
39 |
40 | proto.deletePen = function(markup) {
41 | return new DeleteHighlight(this.editor, markup);
42 | };
43 |
44 | proto.setPen = function(position, size, locations, isAbsoluteCoords) {
45 | return new SetHighlight(this.editor,
46 | this.selectedMarkup,
47 | position,
48 | size,
49 | locations,
50 | isAbsoluteCoords);
51 | };
52 |
53 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetFreehand.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param freehand
9 | * @param position
10 | * @param size
11 | * @param locations
12 | * @constructor
13 | */
14 | export function SetFreehand(editor, freehand, position, size, locations, isAbsoluteCoords) {
15 |
16 | EditAction.call(this, editor, 'SET-FREEHAND', freehand.id);
17 |
18 | this.position = position;
19 | this.size = size;
20 | this.locations = isAbsoluteCoords ? locations : locations.slice(0);
21 | this.isAbsoluteCoords = isAbsoluteCoords;
22 |
23 | // No need to save old data
24 | }
25 |
26 | SetFreehand.prototype = Object.create(EditAction.prototype);
27 | SetFreehand.prototype.constructor = SetFreehand;
28 |
29 | var proto = SetFreehand.prototype;
30 |
31 | proto.redo = function() {
32 |
33 | var freehand = this.editor.getMarkup(this.targetId);
34 | if (!freehand) {
35 | return;
36 | }
37 |
38 | freehand.set(this.position, this.size, this.locations, this.isAbsoluteCoords);
39 | };
40 |
41 | proto.undo = function() {
42 | // No need for undo.
43 | };
44 |
45 | proto.merge = function(action) {
46 |
47 | if (this.targetId === action.targetId &&
48 | this.type === action.type) {
49 |
50 | this.locations = action.isAbsoluteCoords ? action.locations : action.locations.slice(0);
51 | this.position = action.position;
52 | this.size = action.size;
53 | this.isAbsoluteCoords = action.isAbsoluteCoords;
54 | return true;
55 | }
56 | return false;
57 | };
58 |
59 | /**
60 | * @returns {boolean}
61 | */
62 | proto.isIdentity = function() {
63 |
64 | return false; // No need to optimize, always false.
65 | };
66 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetHighlight.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param highlight
9 | * @param position
10 | * @param size
11 | * @param locations
12 | * @constructor
13 | */
14 | export function SetHighlight(editor, highlight, position, size, locations, isAbsoluteCoords) {
15 |
16 | EditAction.call(this, editor, 'SET-HIGHLIGHT', highlight.id);
17 |
18 | this.position = position;
19 | this.size = size;
20 | this.locations = isAbsoluteCoords ? locations : locations.slice(0);
21 | this.isAbsoluteCoords = isAbsoluteCoords;
22 |
23 | // No need to save old data
24 | }
25 |
26 | SetHighlight.prototype = Object.create(EditAction.prototype);
27 | SetHighlight.prototype.constructor = SetHighlight;
28 |
29 | var proto = SetHighlight.prototype;
30 |
31 | proto.redo = function() {
32 |
33 | var highlight = this.editor.getMarkup(this.targetId);
34 | if (!highlight) {
35 | return;
36 | }
37 |
38 | highlight.set(this.position, this.size, this.locations, this.isAbsoluteCoords);
39 | };
40 |
41 | proto.undo = function() {
42 | // No need for undo.
43 | };
44 |
45 | proto.merge = function(action) {
46 |
47 | if (this.targetId === action.targetId &&
48 | this.type === action.type) {
49 |
50 | this.locations = action.isAbsoluteCoords ? action.locations : action.locations.slice(0);
51 | this.position = action.position;
52 | this.size = action.size;
53 | this.isAbsoluteCoords = action.isAbsoluteCoords;
54 | return true;
55 | }
56 | return false;
57 | };
58 |
59 | /**
60 | * @returns {boolean}
61 | */
62 | proto.isIdentity = function() {
63 |
64 | return false; // No need to optimize, always false.
65 | };
66 |
67 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetStamp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | export { SetStamp };
6 |
7 | class SetStamp extends EditAction {
8 | constructor(editor, stamp, position, size) {
9 | super(editor, 'SET-STAMP', stamp.id);
10 |
11 | this.newPosition = {x: position.x, y: position.y};
12 | this.newSize = {x: size.x, y: size.y};
13 | this.oldPosition = {x: stamp.position.x, y: stamp.position.y};
14 | this.oldSize = {x: stamp.size.x, y: stamp.size.y};
15 | }
16 |
17 | redo() {
18 | this.applyState(this.targetId, this.newPosition, this.newSize);
19 | }
20 |
21 | undo() {
22 | this.applyState(this.targetId, this.oldPosition, this.oldSize);
23 | }
24 |
25 | merge(action) {
26 | if (this.targetId === action.targetId && this.type === action.type) {
27 | this.newPosition = action.newPosition;
28 | this.newSize = action.newSize;
29 | return true;
30 | }
31 |
32 | return false;
33 | }
34 |
35 | applyState(targetId, position, size) {
36 | const stamp = this.editor.getMarkup(targetId);
37 | if (!stamp) {
38 | return;
39 | }
40 |
41 | // Different stroke widths make positions differ at sub-pixel level.
42 | const epsilon = 0.0001;
43 | if (
44 | Math.abs(stamp.position.x - position.x) > epsilon
45 | || Math.abs(stamp.position.y - position.y) > epsilon
46 | || Math.abs(stamp.size.x - size.x) > epsilon
47 | || Math.abs(stamp.size.y - size.y) > epsilon
48 | ) {
49 | stamp.set(position, size);
50 | }
51 | }
52 |
53 | isIdentity() {
54 | return (
55 | this.newPosition.x === this.oldPosition.x
56 | && this.newPosition.y === this.oldPosition.y
57 | && this.newSize.x === this.oldSize.x
58 | && this.newSize.y === this.newSize.y
59 | );
60 | }
61 | }
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetSize.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param markup
9 | * @param position
10 | * @param width
11 | * @param height
12 | * @constructor
13 | */
14 | export function SetSize(editor, markup, position, width, height) {
15 |
16 | EditAction.call(this, editor, 'SET-SIZE', markup.id);
17 |
18 | this.newPosition = {x: position.x, y: position.y};
19 | this.oldPosition = {x: markup.position.x, y: markup.position.y};
20 | this.newWidth = width;
21 | this.oldWidth = markup.size.x;
22 | this.newHeight = height;
23 | this.oldHeight = markup.size.y;
24 | }
25 |
26 | SetSize.prototype = Object.create(EditAction.prototype);
27 | SetSize.prototype.constructor = SetSize;
28 |
29 | var proto = SetSize.prototype;
30 |
31 | proto.redo = function() {
32 |
33 | var markup = this.editor.getMarkup(this.targetId);
34 | markup && markup.setSize(this.newPosition, this.newWidth, this.newHeight);
35 | };
36 |
37 | proto.undo = function() {
38 |
39 | var markup = this.editor.getMarkup(this.targetId);
40 | markup && markup.setSize(this.oldPosition, this.oldWidth, this.oldHeight);
41 | };
42 |
43 | proto.merge = function(action) {
44 |
45 | if (this.targetId === action.targetId &&
46 | this.type === action.type) {
47 |
48 | this.newPosition = action.newPosition;
49 | this.newWidth = action.newWidth;
50 | this.newHeight = action.newHeight;
51 | return true;
52 | }
53 | return false;
54 | };
55 |
56 | /**
57 | * @returns {boolean}
58 | */
59 | proto.isIdentity = function() {
60 |
61 | var identity =
62 | this.newPosition.x === this.oldPosition.x &&
63 | this.newPosition.y === this.oldPosition.y &&
64 | this.newWidth === this.oldWidth &&
65 | this.newHeight === this.oldHeight;
66 |
67 | return identity;
68 | };
69 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/CreateCircle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 | import { MarkupCircle } from '../MarkupCircle';
5 | import { cloneStyle } from '../StyleUtils';
6 |
7 | /**
8 | * Markup create circle action.
9 | *
10 | * Implements an {@link Autodesk.Viewing.Extensions.Markups.Core.EditAction|EditAction}
11 | * for creating a Circle {@link Autodesk.Viewing.Extensions.Markups.Core.Markup|Markup}.
12 | * Included in documentation as an example of how to create
13 | * a specific EditAction that deals with Markup creation.
14 | * Developers are encourage to look into this class's source code and copy
15 | * as much code as they need. Find link to source code below.
16 | *
17 | * @tutorial feature_markup
18 | * @constructor
19 | * @memberof Autodesk.Viewing.Extensions.Markups.Core
20 | * @extends Autodesk.Viewing.Extensions.Markups.Core.EditAction
21 | *
22 | * @param editor
23 | * @param id
24 | * @param position
25 | * @param size
26 | * @param rotation
27 | * @param style
28 | */
29 | export function CreateCircle(editor, id, position, size, rotation, style) {
30 |
31 | EditAction.call(this, editor, 'CREATE-CIRCLE', id);
32 |
33 | this.selectOnExecution = false;
34 | this.position = {x: position.x, y: position.y};
35 | this.size = {x: size.x, y: size.y};
36 | this.rotation = rotation;
37 | this.style = cloneStyle(style);
38 | }
39 |
40 | CreateCircle.prototype = Object.create(EditAction.prototype);
41 | CreateCircle.prototype.constructor = CreateCircle;
42 |
43 | var proto = CreateCircle.prototype;
44 |
45 | proto.redo = function() {
46 |
47 | var editor = this.editor;
48 | var circle = new MarkupCircle(this.targetId, editor);
49 |
50 | editor.addMarkup(circle);
51 |
52 | circle.setSize(this.position, this.size.x, this.size.y);
53 | circle.setRotation(this.rotation);
54 | circle.setStyle(this.style);
55 | };
56 |
57 | proto.undo = function() {
58 |
59 | var markup = this.editor.getMarkup(this.targetId);
60 | markup && this.editor.removeMarkup(markup);
61 | };
62 |
63 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Building Measure/Markup extensions
2 |
3 | This is a public 'mirror' version of forge viewer markup and measure extensions. Use webpack to build these extensions locally, then modify as desired.
4 |
5 | **Motivation:**
6 | Forge customers can customize markup and measure tool
7 |
8 | Here's a blog post on how to use the built-in features: https://forge.autodesk.com/blog/using-autodeskviewingmarkupscore-extension
9 |
10 | 
11 |
12 | Source: https://forge.autodesk.com/blog/viewing-large-ocrterrain-images-forge-viewer
13 |
14 | But these APIs are limited. Sometimes you have to hack the viewer3d.js file, in order to achieve the behavior you want. For example, creating an SVG stamp tool (see examples below). It's not really possible without overriding large amounts of code with prototypes.
15 |
16 | Instead, what if you could modify the existing markup and measure extensions, without touching viewer3d.js ? Well, here's how...
17 |
18 | Use this mirror code, to build these extensions seperately. Then modify the extensions code as you need, seperate from the viewer3d.js file.
19 |
20 |
21 |
22 | #### Customization blog posts:
23 |
24 | - to save/restore measurements to a database (save/restore): https://forge.autodesk.com/blog/area-planning-tool-forge-viewer-and-mysql
25 | - create an SVG 'stamp' for markup tool: https://forge.autodesk.com/blog/fast-pdf-viewingmarkup-inside-forge-viewer
26 |
27 | ## Setup
28 |
29 | 1. install cmd line...
30 |
31 | ```
32 | npm install webpack
33 | npm install css-loader --save-dev
34 | npm install style-loader --save-dev
35 | npm install svg-url-loader --save-dev
36 | ```
37 |
38 |
39 | ## Compile
40 | `webpack --config=webpack.js --env.BUILD_TASK=lmv-extensions --env.BUILD_PROD=true`
41 |
42 | this will create minified files under `build/extensions/`:
43 |
44 | ```
45 | Measure/Measure.min.js
46 | Markup/Markup.min.js
47 | ```
48 |
49 | ## Run
50 | which you can include in your index.html file, like this:
51 |
52 | ```
53 |
54 |
55 | ```
56 |
57 | ## Alternatives
58 |
59 | Edit2D extension: https://forge.autodesk.com/en/docs/viewer/v7/developers_guide/advanced_options/edit2d-use/
60 |
61 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetCloud.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param cloud
9 | * @param position
10 | * @param size
11 | * @constructor
12 | */
13 | export function SetCloud(editor, cloud, position, size) {
14 |
15 | EditAction.call(this, editor, 'SET-CLOUD', cloud.id);
16 |
17 | this.newPosition = {x: position.x, y: position.y};
18 | this.newSize = {x: size.x, y: size.y};
19 | this.oldPosition = {x: cloud.position.x, y: cloud.position.y};
20 | this.oldSize = {x: cloud.size.x, y: cloud.size.y};
21 | }
22 |
23 | SetCloud.prototype = Object.create(EditAction.prototype);
24 | SetCloud.prototype.constructor = SetCloud;
25 |
26 | var proto = SetCloud.prototype;
27 |
28 | proto.redo = function() {
29 |
30 | this.applyState(this.targetId, this.newPosition, this.newSize, this.newStrokeWidth, this.newColor);
31 | };
32 |
33 | proto.undo = function() {
34 |
35 | this.applyState(this.targetId, this.oldPosition, this.oldSize, this.oldStrokeWidth, this.oldColor);
36 | };
37 |
38 | proto.merge = function(action) {
39 |
40 | if (this.targetId === action.targetId &&
41 | this.type === action.type) {
42 |
43 | this.newPosition = action.newPosition;
44 | this.newSize = action.newSize;
45 | return true;
46 | }
47 | return false;
48 | };
49 |
50 | /**
51 | *
52 | * @private
53 | */
54 | proto.applyState = function(targetId, position, size) {
55 |
56 | var cloud = this.editor.getMarkup(targetId);
57 | if(!cloud) {
58 | return;
59 | }
60 |
61 | // Different stroke widths make positions differ at sub-pixel level.
62 | var epsilon = 0.0001;
63 |
64 | if (Math.abs(cloud.position.x - position.x) > epsilon || Math.abs(cloud.size.y - size.y) > epsilon ||
65 | Math.abs(cloud.position.y - position.y) > epsilon || Math.abs(cloud.size.y - size.y) > epsilon) {
66 |
67 | cloud.set(position, size);
68 | }
69 | };
70 |
71 | /**
72 | * @returns {boolean}
73 | */
74 | proto.isIdentity = function() {
75 |
76 | return (
77 | this.newPosition.x === this.oldPosition.x &&
78 | this.newPosition.y === this.oldPosition.y &&
79 | this.newSize.x === this.oldSize.x &&
80 | this.newSize.y === this.oldSize.y);
81 | };
82 |
83 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetRectangle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param rectangle
9 | * @param position
10 | * @param size
11 | * @constructor
12 | */
13 | export function SetRectangle(editor, rectangle, position, size) {
14 |
15 | EditAction.call(this, editor, 'SET-RECTANGLE', rectangle.id);
16 |
17 | this.newPosition = {x: position.x, y: position.y};
18 | this.newSize = {x: size.x, y: size.y};
19 | this.oldPosition = {x: rectangle.position.x, y: rectangle.position.y};
20 | this.oldSize = {x: rectangle.size.x, y: rectangle.size.y};
21 | }
22 |
23 | SetRectangle.prototype = Object.create(EditAction.prototype);
24 | SetRectangle.prototype.constructor = SetRectangle;
25 |
26 | var proto = SetRectangle.prototype;
27 |
28 | proto.redo = function() {
29 |
30 | this.applyState(this.targetId, this.newPosition, this.newSize);
31 | };
32 |
33 | proto.undo = function() {
34 |
35 | this.applyState(this.targetId, this.oldPosition, this.oldSize);
36 | };
37 |
38 | proto.merge = function(action) {
39 |
40 | if (this.targetId === action.targetId &&
41 | this.type === action.type) {
42 |
43 | this.newPosition = action.newPosition;
44 | this.newSize = action.newSize;
45 | return true;
46 | }
47 | return false;
48 | };
49 |
50 | /**
51 | *
52 | * @private
53 | */
54 | proto.applyState = function(targetId, position, size) {
55 |
56 | var rectangle = this.editor.getMarkup(targetId);
57 | if(!rectangle) {
58 | return;
59 | }
60 |
61 | // Different stroke widths make positions differ at sub-pixel level.
62 | var epsilon = 0.0001;
63 |
64 | if (Math.abs(rectangle.position.x - position.x) > epsilon || Math.abs(rectangle.size.y - size.y) > epsilon ||
65 | Math.abs(rectangle.position.y - position.y) > epsilon || Math.abs(rectangle.size.y - size.y) > epsilon) {
66 |
67 | rectangle.set(position, size);
68 | }
69 | };
70 |
71 | /**
72 | * @returns {boolean}
73 | */
74 | proto.isIdentity = function() {
75 |
76 | return(
77 | this.newPosition.x === this.oldPosition.x &&
78 | this.newPosition.y === this.oldPosition.y &&
79 | this.newSize.x === this.oldSize.x &&
80 | this.newSize.y === this.oldSize.y);
81 | };
82 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/EditAction.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Base class for all markup edit actions.
5 | *
6 | * EditActions encapsulate {@link Autodesk.Viewing.Extensions.Markups.Core.Markup|Markup}
7 | * operations (such as creation, edition and deletion) that hook into the undo/redo system.
8 | *
9 | * The minimum set of methods to implement on an EditAction extension are:
10 | * - execute()
11 | * - undo()
12 | * - redo()
13 | *
14 | * A good set of classes to check their implementation are:
15 | * {@link Autodesk.Viewing.Extensions.Markups.Core.CreateCircle|CreateCircle}.
16 | * {@link Autodesk.Viewing.Extensions.Markups.Core.DeleteCircle|DeleteCircle}.
17 | * {@link Autodesk.Viewing.Extensions.Markups.Core.SetCircle|SetCircle}.
18 | *
19 | * @tutorial feature_markup
20 | * @constructor
21 | * @memberof Autodesk.Viewing.Extensions.Markups.Core
22 | *
23 | * @param {Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore} editor
24 | * @param {String} type - An identifier for the EditAction.
25 | * @param {number} targetId - The id of the markup being affected.
26 | */
27 | export function EditAction(editor, type, targetId) {
28 |
29 | this.type = type;
30 | this.editor = editor;
31 | this.targetId = targetId;
32 | this.addToHistory = true;
33 | this.selectOnExecution = true;
34 | }
35 |
36 | /**
37 | * Performs the action.
38 | */
39 | EditAction.prototype.execute = function() {
40 |
41 | this.editor.actionManager.execute(this);
42 | };
43 |
44 | /**
45 | * @abstract
46 | */
47 | EditAction.prototype.redo = function() {
48 |
49 | };
50 |
51 | /**
52 | * @abstract
53 | */
54 | EditAction.prototype.undo = function() {
55 |
56 | };
57 |
58 | /**
59 | * Provides a mechanism to merge consecutive actions of the same type.
60 | * @param {Autodesk.Viewing.Extensions.Markups.Core.EditAction} action - Action to check if it can be merged with 'this'.
61 | * @returns {boolean} Returns true if merge has been applied. Parameter will be discarded.
62 | */
63 | EditAction.prototype.merge = function(action) {
64 |
65 | return false;
66 | };
67 |
68 | /**
69 | * Provides a mechanism to check whether the action yields no results.
70 | * @returns {boolean} Returns true if no changes happen with this action.
71 | */
72 | EditAction.prototype.isIdentity = function() {
73 |
74 | return false;
75 | };
76 |
77 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetDimension.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param dimension
9 | * @param firstAnchor
10 | * @param secondAnchor
11 | * @constructor
12 | */
13 | export function SetDimension(editor, dimension, firstAnchor, secondAnchor, text) {
14 |
15 | EditAction.call(this, editor, 'SET-DIMENSION', dimension.id);
16 |
17 | this.newFirstAnchor = {x: firstAnchor.x, y: firstAnchor.y};
18 | this.newSecondAnchor = {x: secondAnchor.x, y: secondAnchor.y};
19 | this.oldFirstAnchor = {x: dimension.firstAnchor.x, y: dimension.firstAnchor.y};
20 | this.oldSecondAnchor = {x: dimension.secondAnchor.x, y: dimension.secondAnchor.y};
21 | this.newText = text;
22 | this.oldText = dimension.currentText;
23 | }
24 |
25 | SetDimension.prototype = Object.create(EditAction.prototype);
26 | SetDimension.prototype.constructor = SetDimension;
27 |
28 | var proto = SetDimension.prototype;
29 |
30 | proto.redo = function() {
31 |
32 | this.applyState(this.newFirstAnchor, this.newSecondAnchor, this.newText);
33 |
34 | };
35 |
36 | proto.undo = function() {
37 |
38 | this.applyState(this.oldFirstAnchor, this.oldSecondAnchor, this.oldText);
39 |
40 | };
41 |
42 | proto.merge = function(action) {
43 |
44 | if (this.targetId === action.targetId &&
45 | this.type === action.type) {
46 |
47 | this.newFirstAnchor = action.newFirstAnchor;
48 | this.newSecondAnchor = action.newSecondAnchor;
49 | this.newText = action.newText;
50 | return true;
51 | }
52 | return false;
53 | };
54 |
55 | /**
56 | *
57 | * @private
58 | */
59 | proto.applyState = function(firstAnchor, secondAnchor, text) {
60 |
61 | var dimension = this.editor.getMarkup(this.targetId);
62 |
63 | if(!dimension) {
64 | return;
65 | }
66 |
67 | dimension.set(firstAnchor.x, firstAnchor.y, secondAnchor.x, secondAnchor.y, text);
68 |
69 | };
70 |
71 | /**
72 | * @returns {boolean}
73 | */
74 | proto.isIdentity = function() {
75 |
76 | return ((this.newText === this.oldText) && (
77 | !this.newFirstAnchor || !this.newSecondAnchor ||
78 | this.newFirstAnchor.x === this.oldFirstAnchor.x &&
79 | this.newFirstAnchor.y === this.oldFirstAnchor.y &&
80 | this.newSecondAnchor.x === this.oldSecondAnchor.x &&
81 | this.newSecondAnchor.y === this.oldSecondAnchor.y));
82 | };
83 |
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetArrow.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | *
7 | * @param editor
8 | * @param arrow
9 | * @param head
10 | * @param tail
11 | * @constructor
12 | */
13 | export function SetArrow(editor, arrow, head, tail) {
14 |
15 | EditAction.call(this, editor, 'SET-ARROW', arrow.id);
16 |
17 | this.newHead = {x: head.x, y: head.y};
18 | this.newTail = {x: tail.x, y: tail.y};
19 | this.oldHead = {x: arrow.head.x, y: arrow.head.y};
20 | this.oldTail = {x: arrow.tail.x, y: arrow.tail.y};
21 | }
22 |
23 | SetArrow.prototype = Object.create(EditAction.prototype);
24 | SetArrow.prototype.constructor = SetArrow;
25 |
26 | var proto = SetArrow.prototype;
27 |
28 | proto.redo = function() {
29 |
30 | this.applyState(this.targetId, this.newHead, this.newTail);
31 | };
32 |
33 | proto.undo = function() {
34 |
35 | this.applyState(this.targetId, this.oldHead, this.oldTail);
36 | };
37 |
38 | proto.merge = function(action) {
39 |
40 | if (this.targetId === action.targetId &&
41 | this.type === action.type) {
42 |
43 | this.newHead = action.newHead;
44 | this.newTail = action.newTail;
45 | return true;
46 | }
47 | return false;
48 | };
49 |
50 | /**
51 | *
52 | * @private
53 | */
54 | proto.applyState = function(targetId, head, tail) {
55 |
56 | var arrow = this.editor.getMarkup(targetId);
57 | if(!arrow) {
58 | return;
59 | }
60 |
61 | // Different stroke widths make positions differ at sub-pixel level.
62 | var epsilon = 0.0001;
63 |
64 | if (Math.abs(arrow.head.x - head.x) >= epsilon || Math.abs(arrow.head.y - head.y) >= epsilon ||
65 | Math.abs(arrow.tail.x - tail.x) >= epsilon || Math.abs(arrow.tail.y - tail.y) >= epsilon) {
66 |
67 | // Confusing naming here. in arrow.set the first two numbers are
68 | // the point you drag from and the second two are the point you
69 | // drag to. So the head point is actually where the tail of the
70 | // arrow is positioned and the tail point is the head is positioned.
71 | arrow.set(head.x, head.y, tail.x, tail.y);
72 | }
73 | };
74 |
75 | /**
76 | * @returns {boolean}
77 | */
78 | proto.isIdentity = function() {
79 |
80 | return (
81 | this.newHead.x === this.oldHead.x &&
82 | this.newHead.y === this.oldHead.y &&
83 | this.newTail.x === this.oldTail.x &&
84 | this.newTail.y === this.oldTail.y);
85 | };
86 |
87 |
--------------------------------------------------------------------------------
/Markup/core/edit-modes/EditModeStamp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditMode } from './EditMode';
4 | import { DeleteStamp } from '../edit-actions/DeleteStamp';
5 | import { CreateStamp } from '../edit-actions/CreateStamp';
6 | import { SetStamp } from '../edit-actions/SetStamp';
7 | import * as MarkupTypes from '../MarkupTypes';
8 |
9 | export { EditModeStamp };
10 |
11 | class EditModeStamp extends EditMode {
12 | constructor(editor, svgData) {
13 | var styleAttributes = [
14 | 'text-data'
15 | ];
16 | super(editor, MarkupTypes.MARKUP_TYPE_STAMP, styleAttributes);
17 | this.svgData = svgData;
18 | }
19 |
20 | deleteMarkup(markup, cantUndo) {
21 | markup = markup || this.selectedMarkup;
22 | if (markup && markup.type == this.type) {
23 | var deleteStamp = new DeleteStamp(this.editor, markup);
24 | deleteStamp.addToHistory = !cantUndo;
25 | deleteStamp.execute();
26 | return true;
27 | }
28 | return false;
29 | }
30 |
31 | onMouseMove(event) {
32 | if (!EditMode.prototype.onMouseMove.call( this, event )) {
33 | return false;
34 | }
35 |
36 | const { selectedMarkup, editor } = this;
37 |
38 | let final = this.getFinalMouseDraggingPosition();
39 | final = editor.clientToMarkups(final.x, final.y);
40 | let position = {
41 | x: (this.firstPosition.x + final.x) / 2,
42 | y: (this.firstPosition.y + final.y) / 2
43 | };
44 | let size = this.size = {
45 | x: Math.abs(final.x - this.firstPosition.x),
46 | y: Math.abs(final.y - this.firstPosition.y)
47 | };
48 |
49 | const action = new SetStamp(editor, selectedMarkup, position, size);
50 | action.execute();
51 | return true;
52 | }
53 |
54 | onMouseDown() {
55 | EditMode.prototype.onMouseDown.call(this);
56 |
57 | if (this.selectedMarkup) {
58 | return;
59 | }
60 |
61 | const editor = this.editor;
62 | let mousePosition = editor.getMousePosition();
63 |
64 | this.initialX = mousePosition.x;
65 | this.initialY = mousePosition.y;
66 | this.firstPosition = editor.clientToMarkups(this.initialX, this.initialY);
67 | this.size = editor.sizeFromClientToMarkups(1, 1);
68 |
69 | editor.beginActionGroup();
70 | const markupId = editor.getId();
71 | const action = new CreateStamp(editor, markupId, this.firstPosition, this.size, 0, this.style, this.svgData);
72 | action.execute();
73 |
74 | // maybe this isn't being called right, that would explain it
75 | this.selectedMarkup = editor.getMarkup(markupId);
76 | this.creationBegin();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Markup/core/Markups.css:
--------------------------------------------------------------------------------
1 | .adsk-viewing-viewer .autodesk-markups-extension-core-make-me-bigger:after {
2 | content: "";
3 | position: absolute;
4 | top: -15px;
5 | bottom: -15px;
6 | left: -15px;
7 | right: -15px;
8 | }
9 |
10 | .adsk-viewing-viewer .autodesk-markups-extension-core-make-me-bigger.rotation-bridge:after {
11 | top: 0;
12 | bottom: 0px;
13 | }
14 |
15 | .adsk-viewing-viewer .selector-box {
16 | position: absolute;
17 | border: 1px dashed #0696D7;
18 | background: rgba(6, 150, 215, 0.05);
19 | z-index: 1;
20 | cursor: move;
21 | box-sizing: border-box;
22 | }
23 |
24 | .adsk-viewing-viewer .selector-drag-point,
25 | .adsk-viewing-viewer .selector-rotate-point {
26 | position: absolute;
27 | height: 8px;
28 | width: 8px;
29 | border-radius: 8px; /*HANDLE_SIZE*/
30 | background: #FFFFFF; /*HANDLE_BACKGROUND_COLOR*/
31 | border-color: rgba(107,120,127,0.7); /* HANDLE_BORDER_COLOR; */
32 | border-width: 1px; /* BORDER_WIDTH */
33 | border-style: solid;
34 | }
35 |
36 | .adsk-viewing-viewer .selector-rotate-point {
37 | top: calc(100% + 22px); /* 30 - 8 = 22 */
38 | left: calc(50% + 1px);
39 | transform: translate3d(-50%, 0px, 0px);
40 | }
41 |
42 | .adsk-viewing-viewer .selector-drag-point.selected,
43 | .adsk-viewing-viewer .selector-rotate-point.selected:not(.rotation-bridge) {
44 | background: #0696D7;
45 | border-color: #0696D7;
46 | }
47 |
48 | .adsk-viewing-viewer .rotation-bridge {
49 | position: absolute;
50 | background-color: rgba(0,0,0,0);
51 | height: 30px;
52 | width: 0px;
53 | top: 100%;
54 | left: calc(50% + 1px);
55 | border: unset;
56 | border-left: 1px dashed #0696D7;
57 | }
58 | /*var placementOffset = -6;*/
59 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-n {
60 | top: -6px;
61 | left: calc(50% - 4px);
62 | position: relative;
63 | }
64 |
65 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-s {
66 | top: calc(100% - 14px);
67 | left: calc(50% - 4px);
68 | position: relative;
69 | }
70 |
71 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-w {
72 | left: -6px;
73 | top: 50%;
74 | transform: translate3d(0, -50%, 0);
75 | }
76 |
77 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-e {
78 | right: -6px;
79 | top: 50%;
80 | transform: translate3d(0, -50%, 0);
81 | }
82 |
83 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-nw {
84 | top: -6px;
85 | left: -6px;
86 | }
87 |
88 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-ne {
89 | top: -6px;
90 | right: -6px;
91 | }
92 |
93 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-sw {
94 | bottom: -6px;
95 | left: -6px;
96 | }
97 |
98 | .adsk-viewing-viewer .selector-drag-point.sdp-handle-se {
99 | bottom: -6px;
100 | right: -6px;
101 | }
--------------------------------------------------------------------------------
/Markup/core/edit-actions/SetCircle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditAction } from './EditAction';
4 |
5 | /**
6 | * Markup set circle action.
7 | *
8 | * Implements an {@link Autodesk.Viewing.Extensions.Markups.Core.EditAction|EditAction}
9 | * for editing properties of a Circle {@link Autodesk.Viewing.Extensions.Markups.Core.Markup|Markup}.
10 | * Included in documentation as an example of how to create
11 | * a specific EditAction that deals with Markup edition.
12 | * Developers are encourage to look into this class's source code and copy
13 | * as much code as they need. Find link to source code below.
14 | *
15 | * @tutorial feature_markup
16 | * @constructor
17 | * @memberof Autodesk.Viewing.Extensions.Markups.Core
18 | * @extends Autodesk.Viewing.Extensions.Markups.Core.EditAction
19 | *
20 | * @param editor
21 | * @param circle
22 | * @param position
23 | * @param size
24 | */
25 | export function SetCircle(editor, circle, position, size) {
26 |
27 | EditAction.call(this, editor, 'SET-CIRCLE', circle.id);
28 |
29 | this.newPosition = {x: position.x, y: position.y};
30 | this.newSize = {x: size.x, y: size.y};
31 | this.oldPosition = {x: circle.position.x, y: circle.position.y};
32 | this.oldSize = {x: circle.size.x, y: circle.size.y};
33 | }
34 |
35 | SetCircle.prototype = Object.create(EditAction.prototype);
36 | SetCircle.prototype.constructor = SetCircle;
37 |
38 | var proto = SetCircle.prototype;
39 |
40 | proto.redo = function() {
41 |
42 | this.applyState(this.targetId, this.newPosition, this.newSize);
43 | };
44 |
45 | proto.undo = function() {
46 |
47 | this.applyState(this.targetId, this.oldPosition, this.oldSize);
48 | };
49 |
50 | proto.merge = function(action) {
51 |
52 | if (this.targetId === action.targetId &&
53 | this.type === action.type) {
54 |
55 | this.newPosition = action.newPosition;
56 | this.newSize = action.newSize;
57 | return true;
58 | }
59 | return false;
60 | };
61 |
62 | /**
63 | *
64 | * @private
65 | */
66 | proto.applyState = function(targetId, position, size) {
67 |
68 | var circle = this.editor.getMarkup(targetId);
69 | if(!circle) {
70 | return;
71 | }
72 |
73 | // Different stroke widths make positions differ at sub-pixel level.
74 | var epsilon = 0.0001;
75 |
76 | if (Math.abs(circle.position.x - position.x) > epsilon || Math.abs(circle.size.y - size.y) > epsilon ||
77 | Math.abs(circle.position.y - position.y) > epsilon || Math.abs(circle.size.y - size.y) > epsilon) {
78 |
79 | circle.set(position, size);
80 | }
81 | };
82 |
83 | /**
84 | * @returns {boolean}
85 | */
86 | proto.isIdentity = function() {
87 |
88 | return (
89 | this.newPosition.x === this.oldPosition.x &&
90 | this.newPosition.y === this.oldPosition.y &&
91 | this.newSize.x === this.oldSize.x &&
92 | this.newSize.y === this.oldSize.y);
93 | };
94 |
95 |
--------------------------------------------------------------------------------
/Markup/core/DomElementStyle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Curring object which generate a string that can be used
5 | * as a Dom element's 'style' value.
6 | *
7 | * @constructor
8 | */
9 | export function DomElementStyle() {
10 |
11 | this.reset();
12 | }
13 |
14 | /*
15 | * Constants
16 | */
17 | var BROWSER_PREFIXES = ['-ms-', '-webkit-', '-moz-', '-o-'];
18 |
19 | var proto = DomElementStyle.prototype;
20 |
21 | proto.reset = function() {
22 |
23 | this.attributes = {};
24 | this.dirty = false;
25 | this.styleString = '';
26 |
27 | return this;
28 | };
29 |
30 | /**
31 | *
32 | * @param {String} key
33 | * @param {*} value
34 | * @param {Object} [options]
35 | * @param {Boolean} [options.allBrowsers] - Whether to add browser prefix to key
36 | * @returns {Autodesk.Viewing.Extensions.Markups.Core.Utils.DomeElemStyle}
37 | */
38 | proto.setAttribute = function(key, value, options) {
39 |
40 | this.attributes[key] = value;
41 |
42 | if (options && options.allBrowsers) {
43 | var that = this;
44 | BROWSER_PREFIXES.forEach(function(prefix){
45 | that.attributes[(prefix+key)] = value;
46 | });
47 | }
48 | this.dirty = true; // Could be optimized
49 | return this;
50 | };
51 |
52 | /**
53 | * Removes one or more attributes
54 | * @param {String|Array} key - Key or Keys to be removed
55 | * @returns {Autodesk.Viewing.Extensions.Markups.Core.Utils.DomElemStyle} this
56 | */
57 | proto.removeAttribute = function(key) {
58 |
59 | if (!Array.isArray(key)) {
60 | key = [key];
61 | }
62 |
63 | var self = this;
64 | key.forEach(function(k) {
65 | if (k in self.attributes) {
66 | delete self.attributes[k];
67 | self.dirty = true;
68 | }
69 | });
70 | return this;
71 | };
72 |
73 | /**
74 | * Gets the String representation of this style object
75 | * @returns {string}
76 | */
77 | proto.getStyleString = function() {
78 |
79 | if (this.dirty) {
80 | this.styleString = generateStyle(this.attributes);
81 | this.dirty = false;
82 | }
83 | return this.styleString;
84 | };
85 |
86 | /**
87 | * Clones the current Object
88 | *
89 | * @returns {Autodesk.Viewing.Extensions.Markups.Core.Utils.DomElemStyle}
90 | */
91 | proto.clone = function() {
92 |
93 | var clone = new DomElementStyle();
94 | var attributes = this.attributes;
95 |
96 | for (var key in attributes) {
97 | clone.setAttribute(key, attributes[key]);
98 | }
99 | return clone;
100 | };
101 |
102 | /**
103 | * Generates the style value string. Non mutable function.
104 | *
105 | * @param {Object} attributes
106 | * @private
107 | */
108 | function generateStyle(attributes) {
109 |
110 | var elements = [];
111 | for (var key in attributes) {
112 | var val = attributes[key];
113 | elements.push(key);
114 | elements.push(':');
115 | elements.push(val);
116 | elements.push('; ');
117 | }
118 | return elements.join('');
119 | }
120 |
--------------------------------------------------------------------------------
/Markup/core/MarkupCircle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { Markup } from './Markup';
4 | import * as MarkupTypes from './MarkupTypes';
5 | import { createMarkupPathSvg, composeRGBAString, setAttributeToMarkupSvg,
6 | updateMarkupPathSvgHitarea, addMarkupMetadata, createEllipsePath } from './MarkupsCoreUtils';
7 | import { cloneStyle } from './StyleUtils';
8 | import { EditModeCircle } from './edit-modes/EditModeCircle';
9 |
10 | /**
11 | *
12 | * @param id
13 | * @param editor
14 | * @constructor
15 | */
16 | export function MarkupCircle(id, editor) {
17 |
18 | var styleAttributes = ['stroke-width', 'stroke-color', 'stroke-opacity', 'fill-color', 'fill-opacity'];
19 | Markup.call(this, id, editor, styleAttributes);
20 |
21 | // bind to this to pass this.globalManager
22 | this.addMarkupMetadata = addMarkupMetadata.bind(this);
23 |
24 | this.type = MarkupTypes.MARKUP_TYPE_CIRCLE;
25 | this.shape = createMarkupPathSvg();
26 |
27 | this.bindDomEvents();
28 | }
29 |
30 | MarkupCircle.prototype = Object.create(Markup.prototype);
31 | MarkupCircle.prototype.constructor = MarkupCircle;
32 |
33 | var proto = MarkupCircle.prototype;
34 |
35 | proto.getEditMode = function() {
36 |
37 | return new EditModeCircle(this.editor);
38 | };
39 |
40 | proto.set = function(position, size) {
41 |
42 | this.setSize(position, size.x, size.y);
43 | };
44 |
45 | /**
46 | * Applies data values into DOM element style/attribute(s)
47 | *
48 | */
49 | proto.updateStyle = function() {
50 |
51 | var style = this.style;
52 | var shape = this.shape;
53 | var path = this.getPath().join(' ');
54 |
55 | var strokeWidth = this.style['stroke-width'];
56 | var strokeColor = this.highlighted ? this.highlightColor : composeRGBAString(style['stroke-color'], style['stroke-opacity']);
57 | var fillColor = composeRGBAString(style['fill-color'], style['fill-opacity']);
58 | var transform = this.getTransform();
59 |
60 | setAttributeToMarkupSvg(shape, 'd', path);
61 | setAttributeToMarkupSvg(shape, 'stroke-width', strokeWidth);
62 | setAttributeToMarkupSvg(shape, 'stroke', strokeColor);
63 | setAttributeToMarkupSvg(shape, 'fill', fillColor);
64 | setAttributeToMarkupSvg(shape, 'transform', transform);
65 | updateMarkupPathSvgHitarea(shape, this.editor);
66 | };
67 |
68 | proto.setMetadata = function() {
69 |
70 | var metadata = cloneStyle(this.style);
71 |
72 | metadata.type = this.type;
73 | metadata.position = [this.position.x, this.position.y].join(" ");
74 | metadata.size = [this.size.x, this.size.y].join(" ");
75 | metadata.rotation = String(this.rotation);
76 |
77 | return this.addMarkupMetadata(this.shape, metadata);
78 | };
79 |
80 | proto.getPath = function() {
81 |
82 | var size = this.size;
83 | if (size.x === 1 || size.y === 1) {
84 | return [''];
85 | }
86 |
87 | var strokeWidth = this.style['stroke-width'];
88 |
89 | var ellipseW = size.x - strokeWidth;
90 | var ellipseH = size.y - strokeWidth;
91 |
92 | var ellipseX = -0.5*ellipseW;
93 | var ellipseY = 0;
94 |
95 | var path = [];
96 | createEllipsePath(ellipseX, ellipseY, ellipseW, ellipseH, false, path);
97 |
98 | return path;
99 | };
100 |
--------------------------------------------------------------------------------
/Markup/core/edit-modes/EditModeCloud.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditMode } from './EditMode';
4 | import { DeleteCloud } from '../edit-actions/DeleteCloud';
5 | import { CreateCloud } from '../edit-actions/CreateCloud';
6 | import { SetCloud } from '../edit-actions/SetCloud';
7 | import * as MarkupTypes from '../MarkupTypes';
8 |
9 | /**
10 | *
11 | * @param editor
12 | * @constructor
13 | */
14 | export function EditModeCloud(editor) {
15 |
16 | var styleAttributes = ['stroke-width', 'stroke-color', 'stroke-opacity', 'fill-color', 'fill-opacity'];
17 | EditMode.call(this, editor, MarkupTypes.MARKUP_TYPE_CLOUD, styleAttributes);
18 | }
19 |
20 | EditModeCloud.prototype = Object.create(EditMode.prototype);
21 | EditModeCloud.prototype.constructor = EditModeCloud;
22 |
23 | var proto = EditModeCloud.prototype;
24 |
25 | proto.deleteMarkup = function(markup, cantUndo) {
26 |
27 | markup = markup || this.selectedMarkup;
28 | if (markup && markup.type == this.type) {
29 | var deleteCloud = new DeleteCloud(this.editor, markup);
30 | deleteCloud.addToHistory = !cantUndo;
31 | deleteCloud.execute();
32 | return true;
33 | }
34 | return false;
35 | };
36 |
37 | /**
38 | * Handler to mouse move events, used to create markups.
39 | * @param {MouseEvent} event Mouse event.
40 | * @private
41 | */
42 | proto.onMouseMove = function(event) {
43 |
44 | if (!EditMode.prototype.onMouseMove.call( this, event )) {
45 | return false;
46 | }
47 |
48 | var selectedMarkup = this.selectedMarkup;
49 |
50 | var editor = this.editor;
51 |
52 | var pos = this.getFinalMouseDraggingPosition();
53 | var final = editor.clientToMarkups(pos.x, pos.y);
54 | var position = { x: (this.firstPosition.x + final.x) / 2, y: (this.firstPosition.y + final.y) / 2 };
55 | var size = this.size = { x: Math.abs(final.x - this.firstPosition.x), y: Math.abs(final.y - this.firstPosition.y) };
56 | var setCloud = new SetCloud(
57 | editor,
58 | selectedMarkup,
59 | position,
60 | size);
61 |
62 | setCloud.execute();
63 | return true;
64 | };
65 |
66 | /**
67 | * Handler to mouse down events, used to start markups creation.
68 | * @private
69 | */
70 | proto.onMouseDown = function() {
71 |
72 | EditMode.prototype.onMouseDown.call(this);
73 |
74 | if (this.selectedMarkup) {
75 | return;
76 | }
77 |
78 | var editor = this.editor;
79 | var mousePosition = editor.getMousePosition();
80 |
81 | this.initialX = mousePosition.x;
82 | this.initialY = mousePosition.y;
83 |
84 | // Calculate center and size.
85 | var position = this.firstPosition = editor.clientToMarkups(this.initialX, this.initialY);
86 | var size = this.size = editor.sizeFromClientToMarkups(1, 1);
87 |
88 | // Create Cloud.
89 | editor.beginActionGroup();
90 |
91 | var markupId = editor.getId();
92 | var create = new CreateCloud(
93 | editor,
94 | markupId,
95 | position,
96 | size,
97 | 0,
98 | this.style);
99 |
100 | create.execute();
101 |
102 | this.selectedMarkup = editor.getMarkup(markupId);
103 | this.creationBegin();
104 | };
105 |
106 |
--------------------------------------------------------------------------------
/Markup/core/edit-modes/EditModeCircle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { EditMode } from './EditMode';
4 | import { DeleteCircle } from '../edit-actions/DeleteCircle';
5 | import { CreateCircle } from '../edit-actions/CreateCircle';
6 | import { SetCircle } from '../edit-actions/SetCircle';
7 | import * as MarkupTypes from '../MarkupTypes';
8 |
9 | /**
10 | * Markup circle edit mode.
11 | *
12 | * Implements a Circle {@link Autodesk.Viewing.Extensions.Markups.Core.EditMode|EditMode}.
13 | * Included in documentation as an example of how to create
14 | * an EditMode for a specific markup type. Developers are encourage to look into this class's source code and copy
15 | * as much code as they need. Find link to source code below.
16 | *
17 | * @tutorial feature_markup
18 | * @constructor
19 | * @memberof Autodesk.Viewing.Extensions.Markups.Core
20 | * @extends Autodesk.Viewing.Extensions.Markups.Core.EditMode
21 | * @param {Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore} editor
22 | */
23 | export function EditModeCircle(editor) {
24 |
25 | var styleAttributes = ['stroke-width', 'stroke-color', 'stroke-opacity', 'fill-color', 'fill-opacity'];
26 | EditMode.call(this, editor, MarkupTypes.MARKUP_TYPE_CIRCLE, styleAttributes);
27 | }
28 |
29 | EditModeCircle.prototype = Object.create(EditMode.prototype);
30 | EditModeCircle.prototype.constructor = EditModeCircle;
31 |
32 | var proto = EditModeCircle.prototype;
33 |
34 | proto.deleteMarkup = function(markup, cantUndo) {
35 |
36 | markup = markup || this.selectedMarkup;
37 | if (markup && markup.type == this.type) {
38 | var deleteCircle = new DeleteCircle(this.editor, markup);
39 | deleteCircle.addToHistory = !cantUndo;
40 | deleteCircle.execute();
41 | return true;
42 | }
43 | return false;
44 | };
45 |
46 | /**
47 | * Handler to mouse move events, used to create markups.
48 | * @param {MouseEvent} event Mouse event.
49 | * @private
50 | */
51 | proto.onMouseMove = function(event) {
52 |
53 | if (!EditMode.prototype.onMouseMove.call( this, event )) {
54 | return false;
55 | }
56 |
57 | var selectedMarkup = this.selectedMarkup;
58 |
59 | var editor = this.editor;
60 |
61 | var final = this.getFinalMouseDraggingPosition();
62 | final = editor.clientToMarkups(final.x, final.y);
63 |
64 | var sizeX = Math.abs(this.firstPosition.x - final.x);
65 | var sizeY = Math.abs(this.firstPosition.y - final.y);
66 |
67 | var position = {x: (this.firstPosition.x + final.x) * 0.5, y: (this.firstPosition.y + final.y) * 0.5};
68 | var size = this.size = {x: sizeX, y: sizeY};
69 |
70 | var setCircle = new SetCircle(
71 | editor,
72 | selectedMarkup,
73 | position,
74 | size);
75 |
76 | setCircle.execute();
77 | return true;
78 | };
79 |
80 | /**
81 | * Handler to mouse down events, used to start markups creation.
82 | * @private
83 | */
84 | proto.onMouseDown = function() {
85 |
86 | EditMode.prototype.onMouseDown.call(this);
87 |
88 | if (this.selectedMarkup) {
89 | return;
90 | }
91 |
92 | var editor = this.editor;
93 | var mousePosition = editor.getMousePosition();
94 |
95 | this.initialX = mousePosition.x;
96 | this.initialY = mousePosition.y;
97 |
98 | // Calculate center and size.
99 | var position = this.firstPosition = editor.clientToMarkups(this.initialX, this.initialY);
100 | var size = this.size = editor.sizeFromClientToMarkups(1, 1);
101 |
102 | // Create circle.
103 | editor.beginActionGroup();
104 |
105 | var markupId = editor.getId();
106 | var create = new CreateCircle(
107 | editor,
108 | markupId,
109 | position,
110 | size,
111 | 0,
112 | this.style);
113 | create.execute();
114 |
115 | this.selectedMarkup = editor.getMarkup(markupId);
116 | this.creationBegin();
117 | };
118 |
--------------------------------------------------------------------------------
/Markup/core/MarkupRectangle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { Markup } from './Markup';
4 | import * as MarkupTypes from './MarkupTypes';
5 | import { createMarkupPathSvg, composeRGBAString, createRectanglePath,
6 | setAttributeToMarkupSvg, updateMarkupPathSvgHitarea, addMarkupMetadata } from './MarkupsCoreUtils';
7 | import { cloneStyle } from './StyleUtils';
8 | import { EditModeRectangle } from './edit-modes/EditModeRectangle';
9 |
10 | /**
11 | * Rectangle markup.
12 | *
13 | * Implements a Rectangle {@link Autodesk.Viewing.Extensions.Markups.Core.Markup|Markup}.
14 | * Included in documentation as an example of how to create
15 | * a specific markup type. Developers are encourage to look into this class's source code and copy
16 | * as much code as they need. Find link to source code below.
17 | *
18 | * @tutorial feature_markup
19 | * @constructor
20 | * @memberof Autodesk.Viewing.Extensions.Markups.Core
21 | * @extends Autodesk.Viewing.Extensions.Markups.Core.Markup
22 | *
23 | * @param {number} id
24 | * @param {Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore} editor
25 | * @constructor
26 | */
27 | export function MarkupRectangle(id, editor) {
28 |
29 | var styleAttributes = ['stroke-width', 'stroke-color', 'stroke-opacity', 'fill-color', 'fill-opacity'];
30 | Markup.call(this, id, editor, styleAttributes);
31 |
32 | // Bind to this to pass this.globalManager
33 | this.addMarkupMetadata = addMarkupMetadata.bind(this);
34 |
35 | this.type = MarkupTypes.MARKUP_TYPE_RECTANGLE;
36 | this.shape = createMarkupPathSvg();
37 |
38 | this.bindDomEvents();
39 | }
40 |
41 | MarkupRectangle.prototype = Object.create(Markup.prototype);
42 | MarkupRectangle.prototype.constructor = MarkupRectangle;
43 |
44 | var proto = MarkupRectangle.prototype;
45 |
46 | proto.getEditMode = function() {
47 |
48 | return new EditModeRectangle(this.editor);
49 | };
50 |
51 | /**
52 | * Sets position and size in markup space coordinates
53 | * @param {Object} position
54 | * @param {Object} size
55 | */
56 | proto.set = function(position, size) {
57 |
58 | this.position.x = position.x;
59 | this.position.y = position.y;
60 | this.size.x = size.x;
61 | this.size.y = size.y;
62 |
63 | this.updateStyle();
64 | };
65 |
66 | /**
67 | * Applies data values into DOM element style/attribute(s)
68 | *
69 | */
70 | proto.updateStyle = function() {
71 |
72 | var style = this.style;
73 | var shape = this.shape;
74 | var path = this.getPath().join(' ');
75 |
76 | var strokeWidth = this.style['stroke-width'];
77 | var strokeColor = this.highlighted ? this.highlightColor : composeRGBAString(style['stroke-color'], style['stroke-opacity']);
78 | var fillColor = composeRGBAString(style['fill-color'], style['fill-opacity']);
79 | var transform = this.getTransform();
80 |
81 | setAttributeToMarkupSvg(shape, 'd', path);
82 | setAttributeToMarkupSvg(shape, 'stroke-width', strokeWidth);
83 | setAttributeToMarkupSvg(shape, 'stroke', strokeColor);
84 | setAttributeToMarkupSvg(shape, 'fill', fillColor);
85 | setAttributeToMarkupSvg(shape, 'transform', transform);
86 | updateMarkupPathSvgHitarea(shape, this.editor);
87 | };
88 |
89 | proto.setMetadata = function() {
90 |
91 | var metadata = cloneStyle(this.style);
92 |
93 | metadata.type = this.type;
94 | metadata.position = [this.position.x, this.position.y].join(" ");
95 | metadata.size = [this.size.x, this.size.y].join(" ");
96 | metadata.rotation = String(this.rotation);
97 |
98 | return this.addMarkupMetadata(this.shape, metadata);
99 | };
100 |
101 | proto.getPath = function() {
102 |
103 | var strokeWidth = this.style['stroke-width'];
104 |
105 | var w = this.size.x - strokeWidth;
106 | var h = this.size.y - strokeWidth;
107 | var x =-w * 0.5;
108 | var y =-h * 0.5;
109 |
110 | var path = [];
111 | createRectanglePath(x, y, w, h, false, path);
112 |
113 | return path;
114 | };
115 |
--------------------------------------------------------------------------------
/Markup/core/MarkupEvents.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Fired whenever the drawing tool changes. For example, when the Arrow drawing
5 | * tool changes into the Rectangle drawing tool.
6 | * See {@link Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore/#changeEditMode|MarkupsCore.changeEditMode()}
7 | * for a list of all supported drawing tools (EditModes).
8 | *
9 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_EDITMODE_CHANGED
10 | * @type {string}
11 | */
12 | export const EVENT_EDITMODE_CHANGED = "EVENT_EDITMODE_CHANGED";
13 |
14 | /**
15 | * Fired when Edit mode has been enabled, which allows the end user to start
16 | * drawing markups over the Viewer canvas.
17 | * See also {@link Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore/#enterEditMode|MarkupsCore.enterEditMode()}.
18 | *
19 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_EDITMODE_ENTER
20 | * @type {string}
21 | */
22 | export const EVENT_EDITMODE_ENTER = "EVENT_EDITMODE_ENTER";
23 |
24 | /**
25 | * Fired when Edit mode has been disabled, preventing the end user from
26 | * drawing markups over the Viewer canvas.
27 | * See also {@link Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore/#leaveEditMode|MarkupsCore.leaveEditMode()}.
28 | *
29 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_EDITMODE_LEAVE
30 | * @type {string}
31 | */
32 | export const EVENT_EDITMODE_LEAVE = "EVENT_EDITMODE_LEAVE";
33 |
34 | /**
35 | * Fired when a drawn markup has been selected by the end user with a click command.
36 | *
37 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_MARKUP_SELECTED
38 | * @type {string}
39 | */
40 | export const EVENT_MARKUP_SELECTED = "EVENT_MARKUP_SELECTED";
41 |
42 | /**
43 | * Fired when a drawn markup is being dragged over the Viewer canvas.
44 | *
45 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_MARKUP_DRAGGING
46 | * @type {string}
47 | */
48 | export const EVENT_MARKUP_DRAGGING = "EVENT_MARKUP_DRAGGING";
49 |
50 | /**
51 | * Internal usage only.
52 | *
53 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_MARKUP_ENTER_EDITION
54 | * @type {string}
55 | * @private
56 | */
57 | export const EVENT_MARKUP_ENTER_EDITION = "EVENT_MARKUP_ENTER_EDITION";
58 |
59 | /**
60 | * Internal usage only.
61 | *
62 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_MARKUP_CANCEL_EDITION
63 | * @type {string}
64 | * @private
65 | */
66 | export const EVENT_MARKUP_CANCEL_EDITION = "EVENT_MARKUP_CANCEL_EDITION";
67 |
68 | /**
69 | * Internal usage only.
70 | *
71 | * @event Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore#EVENT_MARKUP_DELETE_EDITION
72 | * @type {string}
73 | * @private
74 | */
75 | export const EVENT_MARKUP_DELETE_EDITION = "EVENT_MARKUP_DELETE_EDITION";
76 |
77 |
78 | /**
79 | * Fired whenever a new undo or redo action is available.
80 | */
81 | export const EVENT_HISTORY_CHANGED = "EVENT_HISTORY_CHANGED";
82 |
83 | /**
84 | * Fired when a markup creation begins.
85 | * For example, as soon as the user starts dragging with the mouse
86 | * to draw an arrow on the screen.
87 | */
88 | export const EVENT_EDITMODE_CREATION_BEGIN = "EVENT_EDITMODE_CREATION_BEGIN";
89 |
90 | /**
91 | * Fired when a markup has been created.
92 | * For example, as soon as the user stops dragging and releases the
93 | * mouse button to finish drawing an arrow on the screen
94 | */
95 | export const EVENT_EDITMODE_CREATION_END = "EVENT_EDITMODE_CREATION_END";
96 |
97 | /**
98 | * Fired when a markup is no longer selected.
99 | */
100 | export const EVENT_MARKUP_DESELECT = "EVENT_MARKUP_DESELECT";
101 |
102 | /**
103 | * The selected markup is being modified
104 | */
105 | export const EVENT_EDITFRAME_EDITION_START = "EVENT_EDITFRAME_EDITION_START";
106 |
107 | /**
108 | * The selected markup is no longer being modified
109 | */
110 | export const EVENT_EDITFRAME_EDITION_END = "EVENT_EDITFRAME_EDITION_END";
--------------------------------------------------------------------------------
/Markup/core/edit-actions/EditActionGroup.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * This class will group actions edit actions that should be executed as a whole.
5 | * When a group is open actions can be added to it, similar actions will be merged into one during this process.
6 | * This class is not intended to be used by users, it's a helper class of EditActionManager.
7 | * @constructor
8 | */
9 | export function EditActionGroup() {
10 |
11 | this.actions = [];
12 | this.closed = true;
13 | }
14 |
15 | var proto = EditActionGroup.prototype;
16 |
17 | /**
18 | *
19 | * @returns {boolean}
20 | */
21 | proto.open = function() {
22 |
23 | if(!this.closed) {
24 | return false;
25 | }
26 |
27 | this.closed = false;
28 | return true;
29 | };
30 |
31 | /**
32 | *
33 | * @returns {boolean}
34 | */
35 | proto.close = function() {
36 |
37 | if (this.closed) {
38 | return false;
39 | }
40 |
41 | this.closed = true;
42 | return true;
43 | };
44 |
45 | /**
46 | *
47 | * @returns {number} targetId
48 | */
49 | proto.undo = function() {
50 |
51 | var actions = this.actions;
52 | var actionsMaxIndex = actions.length - 1;
53 |
54 | var targetId = -1;
55 | for(var i = actionsMaxIndex; i >= 0; --i) {
56 |
57 | var action = actions[i];
58 | action.undo();
59 |
60 | if (action.targetId !== -1) {
61 | targetId = action.targetId;
62 | }
63 | }
64 |
65 | return targetId;
66 | };
67 |
68 | /**
69 | *
70 | * @returns {number} targetId
71 | */
72 | proto.redo = function() {
73 |
74 | var actions = this.actions;
75 | var actionsCount = actions.length;
76 |
77 | var targetId = -1;
78 | for(var i = 0; i < actionsCount; ++i) {
79 |
80 | var action = actions[i];
81 | action.redo();
82 |
83 | if (action.targetId !== -1) {
84 | targetId = action.targetId;
85 | }
86 | }
87 |
88 | return targetId;
89 | };
90 |
91 | /**
92 | *
93 | * @returns {boolean}
94 | */
95 | proto.isOpen = function() {
96 |
97 | return !this.closed;
98 | };
99 |
100 | /**
101 | *
102 | * @returns {boolean}
103 | */
104 | proto.isClosed = function() {
105 |
106 | return this.closed;
107 | };
108 |
109 | /**
110 | *
111 | * @returns {boolean}
112 | */
113 | proto.isEmpty = function() {
114 |
115 | return this.actions.length === 0;
116 | };
117 |
118 | /**
119 | *
120 | * @param {EditAction} action
121 | */
122 | proto.addAction = function(action) {
123 |
124 | if (this.closed) {
125 | return false;
126 | }
127 |
128 | this.actions.push(action);
129 | this.compact();
130 |
131 | return true;
132 | };
133 |
134 | /**
135 | * @private
136 | */
137 | proto.compact = function() {
138 |
139 | var actions = this.actions;
140 | var actionsCount = actions.length;
141 |
142 | for(var i = 0; i < actionsCount; ++i) {
143 |
144 | // If an action does nothing, remove it.
145 | var actionA = actions[i];
146 | if (actionA.isIdentity()) {
147 | actions.splice(i, 1);
148 | --actionsCount;
149 | --i;
150 | continue;
151 | }
152 |
153 | // If an action can be merged, merge it.
154 | for (var j = i + 1; j < actionsCount; ++j) {
155 |
156 | var actionB = actions[j];
157 | if (actionA.type === actionB.type &&
158 | actionA.merge(actionB)) {
159 | actions.splice(j, 1);
160 | --actionsCount;
161 | --i;
162 | break;
163 | }
164 | }
165 | }
166 | };
167 |
168 | proto.getTargetId = function() {
169 | var actions = this.actions;
170 | var actionsCount = actions.length;
171 | var targetId = -1;
172 | for(var i = 0; i < actionsCount; ++i) {
173 | var action = actions[i];
174 | if (action.targetId !== -1) {
175 | targetId = action.targetId;
176 | }
177 | }
178 | return targetId;
179 | };
--------------------------------------------------------------------------------
/Markup/core/MarkupStamp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { Markup } from './Markup';
4 | import * as MarkupTypes from './MarkupTypes';
5 | import { composeRGBAString, addMarkupMetadata,
6 | stringToSvgNode, createSvgElement} from './MarkupsCoreUtils';
7 | import { cloneStyle, copyStyle, isStyleEqual } from './StyleUtils';
8 | import { EditModeStamp } from './edit-modes/EditModeStamp';
9 |
10 | export { MarkupStamp };
11 |
12 | class MarkupStamp extends Markup {
13 | /**
14 | * @param {number} id
15 | * @param {Autodesk.Viewing.Extensions.Markups.Core.MarkupsCore} editor
16 | */
17 | constructor(id, editor, svgData) {
18 | const styleAttributes = [
19 | 'text-data'
20 | ];
21 | super(id, editor, styleAttributes);
22 | this.type = MarkupTypes.MARKUP_TYPE_STAMP;
23 | this.addMarkupMetadata = addMarkupMetadata.bind(this);
24 |
25 | this.createShapeGroup();
26 |
27 | this.scriptSvgData = svgData;
28 | this.loadSvgData();
29 |
30 | this.bindDomEvents();
31 | }
32 |
33 | createShapeGroup() {
34 | /*
35 | * shape
36 | * group
37 | * customSvg
38 | * hitarea (aka markup)
39 | */
40 | this.shape = createSvgElement('g');
41 | this.shape.group = createSvgElement('g');
42 | this.shape.appendChild(this.shape.group);
43 |
44 | let hitarea = createSvgElement('path');
45 | hitarea.setAttribute('id', "hitarea");
46 | hitarea.setAttribute('fill', "none");
47 | this.shape.appendChild(hitarea);
48 |
49 | this.shape.hitarea = hitarea;
50 | this.shape.markup = hitarea;
51 | }
52 |
53 | loadSvgData() {
54 | let svgString = this.scriptSvgData || this.style['text-data'];
55 | let svgNode = stringToSvgNode(svgString);
56 |
57 | // null if parsing fails, so exit
58 | if (svgNode === null) {
59 | console.warn("SVG data " + svgString + " is invalid, skipping shape update");
60 | return;
61 | }
62 |
63 | let [width, height] = this.getDimensions(svgNode);
64 |
65 | // update the bounding box when the SVG is changed
66 | let path = `M 0 0 l ${width} 0 l 0 ${height} l ${-width} 0 z`;
67 | this.shape.hitarea.setAttribute('d', path);
68 |
69 | this.shape.group.innerHTML = svgNode.innerHTML;
70 |
71 | // This is to standardize things:
72 | // width and height are 1 unit
73 | // position is in the centre
74 | // have to flip things because of y axis going upwards
75 | this.shape.group.setAttribute('transform', `translate( -0.5 , 0.5 ) scale( ${1/width} , ${-1/height} )`);
76 | // then copy to the hitarea because it's outside the SVG
77 | this.shape.hitarea.setAttribute('transform', this.shape.group.getAttribute('transform'));
78 | }
79 |
80 | getEditMode() {
81 | return new EditModeStamp(this.editor);
82 | }
83 |
84 | set(position, size) {
85 | this.setSize(position, size.x, size.y);
86 | this.updateStyle();
87 | }
88 |
89 | updateStyle(styleChanged) {
90 | const strokeColor = this.highlighted ? this.highlightColor : composeRGBAString(this.style['stroke-color'], this.style['stroke-opacity']);
91 | this.shape.hitarea.setAttribute('stroke', strokeColor);
92 |
93 | // This only provides translation and rotation, not scale
94 | const transform = this.getTransform() + ` scale( ${this.size.x} , ${this.size.y} )`;
95 | this.shape.setAttribute('transform', transform);
96 |
97 | if (styleChanged) {
98 | this.loadSvgData();
99 | }
100 | }
101 |
102 | getDimensions(customSvg) {
103 | let vb = customSvg.getAttribute('viewBox');
104 | if (!vb) {
105 | // if no viewbox is specified, check for width and height
106 | let width = customSvg.getAttribute('width') || 100;
107 | let height = customSvg.getAttribute('height') || 100;
108 | return [width, height];
109 | }
110 | let strings = vb.split(' ');
111 | let width = parseInt(strings[2]);
112 | let height = parseInt(strings[3]);
113 |
114 | return [width, height];
115 | }
116 |
117 | setMetadata() {
118 |
119 | var metadata = cloneStyle(this.style);
120 |
121 | metadata.type = this.type;
122 | metadata.position = [this.position.x, this.position.y].join(" ");
123 | metadata.size = [this.size.x, this.size.y].join(" ");
124 | metadata.rotation = String(this.rotation);
125 |
126 | return this.addMarkupMetadata(this.shape, metadata);
127 | }
128 |
129 | setStyle(style) {
130 | let stylesEqual = isStyleEqual(style, this.style);
131 | if (!stylesEqual) {
132 | copyStyle(style, this.style);
133 | }
134 |
135 | this.updateStyle(!stylesEqual);
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/webpack.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var fs = require('fs');
3 | var path = require('path');
4 |
5 | function NullPlugin() {
6 | this.apply = function(){};
7 | }
8 |
9 | // Give process a more descriptive name than just "npm"
10 | process.title = 'lmv-webpack';
11 |
12 | /**
13 | * Exports a function that returns an array of webpack configurations to run in parallel.
14 | *
15 | * @param {object} env - Object containing command-line supplied variables
16 | */
17 | module.exports = function(env) {
18 |
19 | const PROD_BUILD = env.BUILD_PROD;
20 |
21 | // Defaults for local developer builds
22 | var build_version = env.BUILD_VERSION;
23 | var build_type = env.BUILD_TYPE || 'local';
24 |
25 | /**
26 | *
27 | * @param {boolean} [extractCss=false] - Whether a CSS file will get generated (true) or not (false)
28 | */
29 | function getModuleConfig(extractCss) {
30 | var moduleConfig = {
31 | rules: [
32 | {
33 | test: /\.js$/,
34 | include: [
35 | path.resolve(__dirname, "../extensions"),
36 | ],
37 | exclude: [/\.min.js$/], //the min.js is for zlib pre-built modules
38 | use: {
39 | loader: 'babel-loader',
40 | options: {
41 | cacheDirectory: '.babel',
42 | presets: ['@babel/preset-env'],
43 | compact: false,
44 | retainLines: true
45 | }
46 | }
47 | },
48 | {
49 | test: /\.svg$/,
50 | loader: 'svg-url-loader'
51 | }
52 | ],
53 | noParse: [
54 | /\.min.js$/
55 | ]
56 | };
57 |
58 | if (extractCss) {
59 | } else {
60 | // CSS styles will be included into the HTML by inserting