microsoft / maker.js

📐⚙ 2D vector line drawing and shape modeling for CNC and laser cutters.
http://maker.js.org
Apache License 2.0
1.74k stars 264 forks source link

Adding custom attributes or class to path element #548

Closed Gautam2010 closed 1 year ago

Gautam2010 commented 1 year ago

Is there any way I can add class or custom attributes to path?

Current output is: <svg> <path id="p1" d="..."/> <path id="p1" d="..."/> <path id="p1" d="..."/> </svg>

expected I am looking for <svg> <path class="custom-lines" data-module-color="ABC" id="p1" d="..."/> <path class="custom-lines" id="p1" d="..."/> <path class="custom-lines" id="p1" d="..."/> </svg>

Code for the model and export is as below var modelSD: IModel = { models: { polygon: shape, lines: { paths: { line1: new paths.Line([0, 10], [15, 30]), line2: new paths.Line([50, 40], [90, 120]), }, layer:'lines-id' }, }, }; const svg = exporter.toSVG(modelSD, { annotate: true })

danmarshall commented 1 year ago

Hello, it may be possible to expose the internal XmlTag implementation. Can you for now workaround with a string search & replace on '<path '?

Gautam2010 commented 1 year ago

Hi @danmarshall replace could work but I have requirements classes are different at different path. i.e <svg> <path class="custom-lines run-1" data-module-color="ABC" id="p1" d="..."/> <path class="custom-lines run-2" id="p1" d="..."/> <path class="custom-lines" id="p1" d="..."/> </svg>

danmarshall commented 1 year ago

Have you tried using layers as a way of isolating your paths? You might then be able to correlate the <path>s outputted. When you export with .toSvg(), you can pass layerOptions.

Gautam2010 commented 1 year ago

@danmarshall I don't see any option for classnames in layeroptions

image
danmarshall commented 1 year ago

@Gautam2010 classNames could be a good feature addition. Fow now, you can identify your paths as layers - in the svg, each path gets an id attribute with the layer value:

var makerjs = require('makerjs');

function dogbonePolygon() {
  var polygon = new makerjs.models.Polygon(6, 100);
  var chain = makerjs.model.findSingleChain(polygon);
  var bones = makerjs.chain.dogbone(chain, 20);

  this.models = {
    polygon: polygon,
    bones: bones
  };

  polygon.layer = 'red';
  bones.layer = 'myId';
}

module.exports = dogbonePolygon;
image

svg output:

<svg width="200" height="178.5641" viewBox="0 0 200 178.5641" xmlns="http://www.w3.org/2000/svg">
  <g id="svgGroup" stroke-linecap="round" fill-rule="evenodd" font-size="9pt" stroke="#000" stroke-width="0.25mm" fill="none" style="stroke:#000;stroke-width:0.25mm;fill:none">
    <path id="red" stroke="red" style="stroke:red" vector-effect="non-scaling-stroke" d="M 190 71.9615 160 20 M 130 2.6795 70 2.6795 M 40 20 10 71.9615 M 10 106.6025 40 158.5641 M 70 175.8846 130 175.8846 M 160 158.5641 190 106.6025"/>
    <path id="myId" vector-effect="non-scaling-stroke" d="M 130 2.6795 A 20 20 0 0 1 160 20 M 40 20 A 20 20 0 0 1 70 2.6795 M 10 106.6025 A 20 20 0 0 1 10 71.9615 M 70 175.8846 A 20 20 0 0 1 40 158.5641 M 160 158.5641 A 20 20 0 0 1 130 175.8846 M 190 71.9615 A 20 20 0 0 1 190 106.6025"/>
  </g>
</svg>

Side note: when a layer is a DXF color name, the stroke will be that color.

Gautam2010 commented 1 year ago

@danmarshall I have utilized id for the uniqueness, classname can be used to group the certain path at UI. If we can allow classname in layer option it would be very helpful.

danmarshall commented 1 year ago

Thanks for diving into the source code! 🤝