70002405 Support custom objects with grips and custom osnaps

Article 70002405
Type Wish
Product WebJS
Version 1004
Date Added 9/14/2023 12:00:00 AM
Fixed 10.1005.0.1 (9/18/2023 12:00:00 AM)
Submitted by Ferhat Altun

Summary

Support custom objects with grips and custom osnaps

Solution

In version 1005.0.1 the following event was added to vdraw canvas object
OnCustomGetOsnaps additionally with article 70002386
see following example of how to use them
It creates three kind of custom objects,
a Line with arrow at the end
a double polyline
and a custom object represented as cross

var vdcanvas;
function vdrawInitPageLoad() {//Intiallize theweb control inside this function.It must be called inside onload event of this page
            vdcanvas = vdmanager.AttachCanvas("canvas"); //create a new web control andattch it to the canvas elemement
            //additional requaired properties and methods calls (see web examples)
            //Follow Initialze events for custom objects
             vdcanvas.OnCustomDraw = OnCustomDraw;
             vdcanvas.OnIsCustom = OnIsCustom;
             vdcanvas.OnCustomGetGrips = OnCustomGetGrips;
             vdcanvas.OnCustomMovegrips = OnCustomMovegrips;
             vdcanvas.OnCustomGetOsnaps = OnCustomGetOsnaps;
        }
        //method that starts a user command to draw a new line with arrow custom object
        //call this method from a button in your html page to begin a user action that draws a custom line with arrow
        function CustomLineWithArrowCommand() {
             vdcanvas.ActiveAction().cancel();
             vdcanvas.GetUserPoint(Action_Arrow);
         }
        //method that starts a user command to draw a new double polyline custom object
        //call this method from a button in your html page to begin a user action that draws a custom doublepolyline entity
        function CustomDoublePolyLineCommand() {
             vdcanvas.ActiveAction().cancel();
             vdcanvas.GetUserPoint(Action_Line);
         }

        //method that starts a user command to draw a new cross custom object
        //call this method from a button in your html page to begin a user action that draws a cross entity
        function CustomCrossCommand() {
             vdcanvas.ActiveAction().cancel();
             vdcanvas.GetUserPoint(Action_Cross);
         }

         function OnCustomGetOsnaps(args) {
             var fig = args.entity;
             var ret = [];
             if (fig._t === 1000) {//if figure is doublepolyline
                 args.innerosnaps.length = 0; //remove existing sub entities osnaps.NOTE:If not then keep them and add additionals as follow
                 //add the object NODE osnap
                 if ((args.osnapmode & vdConst.OsnapMode_END)) {
                     for (var i = 0; i < fig.pts.length; i++) {
                         var pt = fig.pts[i];
                         ret.push([pt[X], pt[Y], pt[Z], vdConst.OsnapMode_END]);
                     }
                 }
             } else if (fig._t === 1001) {//if figure is line with arrow
                 args.innerosnaps.length = 0; //remove existing sub entities osnaps.NOTE:If not then keep them and add additionals as follow
                 //add the object NODE osnap
                 if ((args.osnapmode & vdConst.OsnapMode_END)) {
                     ret.push([fig.StartPoint[X], fig.StartPoint[Y], fig.StartPoint[Z], vdConst.OsnapMode_END]);
                     ret.push([fig.EndPoint[X], fig.EndPoint[Y], fig.EndPoint[Z], vdConst.OsnapMode_END]);

                 }
                 if ((args.osnapmode & vdConst.OsnapMode_MID)) {
                     var pt = vdgeo.MidPoint(fig.StartPoint, fig.EndPoint);
                     ret.push([pt[X], pt[Y], pt[Z], vdConst.OsnapMode_MID]);
                 }

             }else if (fig._t === 1002) {//if figure is cross
                 args.innerosnaps.length = 0; //remove existing sub entities osnaps.NOTE:If not then keep them and add additionals as follow
                 //add the object NODE osnap
                 if ((args.osnapmode & vdConst.OsnapMode_NODE)) {
                     ret.push([fig.center[X], fig.center[Y], fig.center[Z], vdConst.OsnapMode_NODE]);
                 }
             }
             return ret;
         }
         //event that implement how the grips of each of custom figure are moved
         function OnCustomMovegrips(args) {
             var fig = args.entity;
             var indexes = args.indexes;
             var offset = args.offset;
             var vdraw = args.sender;
             if (fig._t === 1000) {//if figure is doublepolyline
                 var ret = false;
                 for (var i = 0; i < indexes.length; i++) {
                     fig.pts[indexes[i]][X] += offset[X];
                     fig.pts[indexes[i]][Y] += offset[Y];
                     fig.pts[indexes[i]][Z] += offset[Z];
                     ret = true;
                 }

             }
             else if (fig._t === 1001) {//if figure is line with arrow
                 for (var i = 0; i < indexes.length; i++) {
                     if (indexes[i] == 0) {
                         fig.StartPoint[X] += offset[X];
                         fig.StartPoint[Y] += offset[Y];
                         fig.StartPoint[Z] += offset[Z];
                     } else {
                         fig.EndPoint[X] += offset[X];
                         fig.EndPoint[Y] += offset[Y];
                         fig.EndPoint[Z] += offset[Z];
                     }
                     ret = true;
                 }
             } else if (fig._t === 1002) {//if figure is cross
                 var ret = true;
                 fig.center[X] += offset[X];
                 fig.center[Y] += offset[Y];
                 fig.center[Z] += offset[Z];
             }
             if (ret) vdraw.UpdateFig(fig, true);
             return ret;
         }

         //event that defines the grips of each of custom objects
         //the grips are seted to the fig.grips property collection
         function OnCustomGetGrips(args) {
             var fig = args.entity;
             if (fig._t === 1000) {//if figure is doublepolyline
                 if (fig.grips === undefined) {
                     fig.grips = [];
                     for (var i = 0; i < fig.pts.length; i++) {
                         fig.grips.push(fig.pts[i]);
                     }
                 }
             } else if (fig._t === 1001) {//if figure is line with arrow
                 if (fig.grips === undefined) {
                     fig.grips = [fig.StartPoint, fig.EndPoint];
                 }
             } else if (fig._t === 1002) {//if figure is cross
                 if (fig.grips === undefined) {
                     fig.grips = [fig.center];
                 }
             }
             return fig.grips;
         }
         //event that check the figures that are customized by the user code
         function OnIsCustom(args) {
             var fig = args.entity;
             return fig._t === 1000 || fig._t === 1001 || fig._t === 1002;
         }
         //event that is called for each custom entity draw
         //note:user must add drawing primitives entities to the fig.Explode property as follow
         function OnCustomDraw(args) {
             var fig = args.entity;
             var vdraw = args.sender;
             if (fig._t === 1000) {//if figure is doublepolyline
                 var pl = vdraw.AddPolyline(fig.pts, false, {});
                 pl.PenColor = vdConst.colorFromString("byblock");
                 pl.LineWeight = vdConst.LW_BYBLOCK;
                 pl.LineType = 'h_' + vdraw.FindLineType("byblock").HandleId.toString();
                 pl.Widths = { Items: [] };
                 for (var i = 0; i < fig.pts.length; i++) {
                     pl.Widths.Items.push(0.2);
                     pl.Widths.Items.push(0.2);
                 }
                 pl.PLineDrawFlag = 2;
                 fig.Explode = { Items: [pl] };
             } else if (fig._t === 1001) {//if figure is line with arrow

                 var arrowsize = 0.2;
                 var l = vdraw.AddLine(fig.StartPoint, fig.EndPoint, false, {});
                 var angle = vdgeo.GetAngle(fig.StartPoint, fig.EndPoint);
                 var pt = vdgeo.pointPolar(fig.EndPoint, angle + vdgeo.PI, arrowsize);

                 var pts = [fig.EndPoint, vdgeo.pointPolar(pt, angle + vdgeo.HALF_PI, arrowsize), vdgeo.pointPolar(pt, angle - vdgeo.HALF_PI, arrowsize)];
                 var pl = vdraw.AddPolyline(pts, false, {});
                 pl.PenColor = vdConst.colorFromString("byblock");
                 pl.LineWeight = vdConst.LW_BYBLOCK;
                 pl.LineType = 'h_' + vdraw.FindLineType("byblock").HandleId.toString();
                 pl.HatchProperties = vdraw.createNewHatchProperties('solid', vdConst.colorFromString("byblock"), vdConst.colorFromString("byblock"));
                 fig.Explode = { Items: [l, pl] };
             } else if (fig._t === 1002) {//if figure is a cross
                 var l1 = vdraw.AddLine(vdgeo.pointPolar(fig.center, vdgeo.HALF_PI, -fig.size), vdgeo.pointPolar(fig.center, vdgeo.HALF_PI, fig.size), false, {});
                 l1.PenColor = vdConst.colorFromString("byblock");
                 l1.LineWeight = vdConst.LW_BYBLOCK;
                 l1.LineType = 'h_' + vdraw.FindLineType("byblock").HandleId.toString();
                 var l2 = vdraw.AddLine(vdgeo.pointPolar(fig.center, vdgeo.PI, -fig.size), vdgeo.pointPolar(fig.center, vdgeo.PI, fig.size), false, {});
                 l2.PenColor = vdConst.colorFromString("byblock");
                 l2.LineWeight = vdConst.LW_BYBLOCK;
                 l2.LineType = 'h_' + vdraw.FindLineType("byblock").HandleId.toString();
                 fig.Explode = { Items: [l1, l2] };

             }
         }

         //utilty method to create a custom object with all needed common properties
         function create_custom_fig(vdrawobj, typeid, typename) {
             var layout = vdrawobj.GetActiveLayout();
             if (layout == null) return null;
             var vddoc = vdrawobj.GetDocument();
             var customentity = { _t: typeid, CustomType: typename };
             customentity.LineType = vddoc.ActiveLineType;
             customentity.Layer = vddoc.ActiveLayer;
             customentity.PenColor = vdConst.cloneEntity(vdrawobj.GetActivePenColor());
             customentity.PenWidth = vddoc.ActivePenWidth;
             customentity.LineWeight = vddoc.ActiveLineWeight;
             if (vddoc.ActiveLineTypeScale) customentity.LineTypeScale = vddoc.ActiveLineTypeScale;
             return customentity;

         }

         //method that begins a user action for custom double polyline object
         function Action_Line(action, status) {

             var vdrawObj = action.vdrawOwner();
             if (!action.customMode) action.customMode = 'StartPoint';
             if (action.customMode == "StartPoint") {
                 if (status == 'start') {
                     vdrawObj.Prompt("Pick start point:");
                 }
                 else if (status == 'end') {
                     vdrawObj.Prompt('');
                     if (!action.IsCanceled()) {
                         var pt = action.SelectedPoint();
                         action.Figure = create_custom_fig(vdrawObj, 1000, "vds.customLine");
                         action.Figure.pts = [pt];

                         action.customMode = 'EndPoint';
                         vdrawObj.GetUserLine(Action_Line, pt);
                     }
                     else {
                         action.customMode = null;
                         action.Figure = null;
                     }
                 }
             }
             else if (action.customMode == 'EndPoint') {
                 if (status == 'start') {
                     vdrawObj.Prompt('Pick end Point:');
                 }
                 else if (status == 'end') {
                     vdrawObj.Prompt('');
                     if (!action.IsCanceled()) {
                         var pt = action.SelectedPoint();
                         action.Figure.pts.push(pt);

                         vdrawObj.UpdateFig(action.Figure);

                         vdrawObj.ActionDrawEntities([action.Figure]);
                         if (!action.Figure.HandleId)
                             vdrawObj.scriptCommand.RegisterFigure(action.Figure);
                         vdrawObj.GetUserLine(Action_Line, pt);

                     } else {
                         vdrawObj.DrawEntity(action.Figure);
                         vdrawObj.Refresh();
                         action.customMode = null;
                         action.Figure = null;
                     }
                 }
                 else if (status == 'draw') {
                     if (action.Figure) {
                         var render = action.render;
                         action.Figure.pts.push(action.DrawPoint());
                         vdrawObj.UpdateFig(action.Figure);
                         vdrawObj.DrawEntity(action.Figure, render);
                         action.Figure.pts.pop();
                         vdrawObj.UpdateFig(action.Figure);
                     }
                 }
             }
         }
         //method that begins a user action for custom line with arrow object
         function Action_Arrow(action, status) {

             var vdrawObj = action.vdrawOwner();
             if (!action.customMode) action.customMode = 'StartPoint';
             if (action.customMode == "StartPoint") {
                 if (status == 'start') {
                     vdrawObj.Prompt("Pick start point:");
                 }
                 else if (status == 'end') {
                     vdrawObj.Prompt('');
                     if (!action.IsCanceled()) {
                         var pt = action.SelectedPoint();
                         action.Figure = create_custom_fig(vdrawObj, 1001, "vds.customArrow");
                         action.Figure.StartPoint = pt;

                         action.customMode = 'EndPoint';
                         vdrawObj.GetUserLine(Action_Arrow, pt);
                     }
                     else {
                         action.customMode = null;
                         action.Figure = null;
                     }
                 }
             }
             else if (action.customMode == 'EndPoint') {
                 if (status == 'start') {
                     vdrawObj.Prompt('Pick end Point:');
                 }
                 else if (status == 'end') {
                     vdrawObj.Prompt('');
                     if (!action.IsCanceled()) {
                         var pt = action.SelectedPoint();
                         action.Figure.EndPoint = pt;

                         vdrawObj.UpdateFig(action.Figure);
                         if (!action.Figure.HandleId)
                             vdrawObj.scriptCommand.RegisterFigure(action.Figure);
                         vdrawObj.DrawEntity(action.Figure);
                         vdrawObj.Refresh();
                     }
                     action.customMode = null;
                     action.Figure = null;
                 }
                 else if (status == 'draw') {
                     if (action.Figure) {
                         var render = action.render;
                         action.Figure.EndPoint = action.DrawPoint();
                         vdrawObj.UpdateFig(action.Figure);
                         vdrawObj.DrawEntity(action.Figure, render);

                     }
                 }
             }
         }
         //method that begins a user action for custom cross object
         function Action_Cross(action, status) {

             var vdrawObj = action.vdrawOwner();
             if (!action.customMode) action.customMode = 'centerpoint';
             if (action.customMode == "centerpoint") {
                 if (status == 'start') {
                     vdrawObj.Prompt("Pick center point:");
                 }
                 else if (status == 'end') {
                     vdrawObj.Prompt('');
                     if (!action.IsCanceled()) {
                         var pt = action.SelectedPoint();
                         action.Figure = create_custom_fig(vdrawObj, 1002, "vds.customCross");
                         action.Figure.center = pt;

                         action.customMode = 'size';
                         vdrawObj.GetUserLine(Action_Cross, pt);
                     }
                     else {
                         action.customMode = null;
                         action.Figure = null;
                     }
                 }
             }
             else if (action.customMode == 'size') {
                 if (status == 'start') {
                     vdrawObj.Prompt('Pick end Point of size:');
                 }
                 else if (status == 'end') {
                     vdrawObj.Prompt('');
                     if (!action.IsCanceled()) {
                         var pt = action.SelectedPoint();
                         action.Figure.size = vdgeo.Distance2D(action.SelectedPoint(), action.Figure.center);

                         vdrawObj.UpdateFig(action.Figure);

                         vdrawObj.ActionDrawEntities([action.Figure]);
                         if (!action.Figure.HandleId)
                             vdrawObj.scriptCommand.RegisterFigure(action.Figure);


                     }
                     vdrawObj.DrawEntity(action.Figure);
                     vdrawObj.Refresh();
                     action.customMode = null;
                     action.Figure = null;

                 }
                 else if (status == 'draw') {
                     if (action.Figure) {
                         var render = action.render;
                         action.Figure.size = vdgeo.Distance2D(action.DrawPoint(), action.Figure.center);
                         vdrawObj.UpdateFig(action.Figure);
                         vdrawObj.DrawEntity(action.Figure, render);
                         vdrawObj.UpdateFig(action.Figure);
                     }
                 }
             }
         }
         

Send comments on this topic.