Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to export DXF file by canvas info #579

Closed
tranthaihoang opened this issue Oct 30, 2023 · 2 comments
Closed

How to export DXF file by canvas info #579

tranthaihoang opened this issue Oct 30, 2023 · 2 comments

Comments

@tranthaihoang
Copy link

I have technical drawing parameters drawn through the HTML5 canvas function, is there a way to quickly convert these parameters so that they can be exported to a DXF file?
I saw a similar issue but it doesn't seem to have resolved the issue in question.
#447

I hope someone has solved it and provided guidance.
A sample code:

<canvas id="canvas" width="1000" height="1000" style="border:1px solid #ccc"></canvas>
    <script>
        let canvas = document.getElementById('canvas');
        let ctx = canvas.getContext('2d');

        var scale = 3
        var r_val1 = 30 * scale;
        var r_val2 = 60 * scale;
        var r_val3 = 30 * scale;
        ctx.save();

        var x1 = 200;
        var y1 = 150;
        var x4 = 200 + r_val1;
        var y4 = 150
        var x5 = 200;
        var y5 = 150 + r_val2;

        var a = Math.atan(r_val1 / r_val2);
        var b = (Math.PI - a) / 2;
        var c = r_val3 * (1 / Math.tan(b));
        var x2 = 200 + r_val1 + c;
        var y2 = 150;
        var x3 = 200;
        var y3 = 150 + r_val2 + c;

        ctx.globalCompositeOperation = "source-over";
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(x2, y2);
        ctx.arcTo(x4, y4, x5, y5, r_val3);
        ctx.arcTo(x5, y5, x3, y3, r_val3);
        ctx.lineTo(x3, y3);
        ctx.stroke();

        ctx.restore();
    </script>
@danmarshall
Copy link
Contributor

Hi @tranthaihoang,

The quick answer:

  1. Use d3.path to convert Canvas comands to SVG path data
  2. Use Maker.js to import the SVG path data as a model.
  3. Use Maker.js to export the model as DXF

To show this in action, I've put this together in an Observable notebook: HTML Canvas to DXF. So please check that out - it even has your sample code above.

The long answer:

If one wanted to do this in Maker.js, there would be some refactoring involved. First, check out the documentation. The main concept that is different than Canvas is that Maker.js does not have a "turtle". Instead, you draw in discrete segments (path objects) that do not need to be contiguous as you create them.

Aside: after you've created a drawing, there is a contiguous concept called a chain - but that is something "found" in your drawing. The reason for this is that you might have combined multiple chains and ended up with only one. So, the originals could have been broken up.

The next thing is that one might not need to do so much math as in your example. The API documentation shows a wealth of functions to do math for you. So you can focus on the ideas from a more declarative level.

Conversion from Canvas to Maker.js

Use the control points of the Canvas commands to create a series of lines:

  var line1 = new makerjs.paths.Line([x2, y2], [x4, y4]);
  var line2 = new makerjs.paths.Line([x4, y4], [x5, y5]);
  var line3 = new makerjs.paths.Line([x5, y5], [x3, y3]);

The arcTo canvas command can be replaced by the Maker.js fillet function:

  var fillet1 = makerjs.path.fillet(line1, line2, r_val3);
  var fillet2 = makerjs.path.fillet(line2, line3, r_val3);

The fillet function will trim the line's endpoints to match the arc.

Note there is a behavior difference when the radius of the arc is larger than the wedge defined by the control points:

  • In Canvas, the result of a large radius will add an extra line on the endpoints.
  • In the Maker.js fillet function, the fillet will be null. Also - in the case that a fillet trims a line to become a zero length, the function will return null. The line can be extremely small but not zero.

Hope that helps!

@tranthaihoang
Copy link
Author

tranthaihoang commented Oct 31, 2023

Hi @danmarshall
OMG!
Thank you very much for your quick, accurate and very complete reply.
I tried it and it worked!

Link codepen: https://codepen.io/thaihoangtran/pen/WNPwooO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants