jonobr1 / two.js

A renderer agnostic two-dimensional drawing api for the web.
https://two.js.org
MIT License
8.31k stars 455 forks source link

Simple polygon example? #144

Closed runemadsen closed 7 years ago

runemadsen commented 9 years ago

I've been messing around with Two.Polygon, trying to create a very simple shape with a bezier curve. I'm not sure exactly why this is not working, and I have a hard time finding documentation.

Here's the code:

var something = two.makePolygon([
    new Two.Anchor(100, 100),
    new Two.Anchor(200, 100, 100, 0, 200, 0, Two.Commands.curve),
    new Two.Anchor(200, 200),
    new Two.Anchor(100, 200)
  ]);

And here's the output:

screen shot 2015-07-20 at 9 25 18 am

And the SVG path itself:

<path transform="matrix(1 0 0 1 150 150)" d="M -50 -50 L 50 -50 L 50 50 L -50 50 Z " fill="red" stroke="#000" stroke-width="1" stroke-opacity="1" fill-opacity="1" visibility="visible" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" id="two_1"></path>

So, I can't get the bezier curve to even show up in the path info.

On top of that, here's a question. How open would you be to a nicer drawing API for polygons? I'm thinking that my code above would be much easier for my students with something like this:

var something = two.makePolygon()
   .moveTo(100, 100)
   .bezierTo(200, 100, 100, 0, 200, 0)
   .lineTo(200, 200)
   .lineTo(100, 200)
   .closeShape();
jonobr1 commented 9 years ago

Ah yes, unfortunately for this type of drawing (where you're mixing and matching straight lines and bezier curves) the API is incredibly verbose:

var something = new Two.Polygon([
    new Two.Anchor(100, 100, 0, 0, 0, 0, Two.Commands.move),
    new Two.Anchor(200, 100, -100, -100, 0, -100, Two.Commands.curve),
    new Two.Anchor(200, 200, 0, 0, 0, 0, Two.Commands.line),
    new Two.Anchor(100, 200, 0, 0, 0, 0, Two.Commands.line)
  ], true, false, true);
two.add(something);

All Two.Polygons have an automatic property which enables:

  1. Automated "commands" so you don't have to say moveTo, lineTo, etc..
  2. Automated bezier calculations based off of a catmull rom like curve so you can focus on other stuff.

The make commands enable this and execute the aforementioned functions when invoked. So, you wont' be able to use those commands. You have to instantiate the object yourself with new Two.Polygon(). The following boolean parameters refer to if the shape is closed, curved, or manual. If manual is true then that sets shape.automatic = false; and the prior 2 arguments are effectively ignored.

Since you're instantiating your own Two.Polygon you'll also have to add it to the scene a la two.add(something);.

Finally, when creating Two.Anchors and describing their handle coordinates remember that by default these numbers are relative to the Two.Anchors x and y position. So in the example you see there's a negative number to indicate that that control point is to the left of the Two.Anchors position. You can change this if you'd like by setting the relative property to false like so:

var a = new Two.Anchor(100, 100, 100, 100, 0, 0, Two.Commands.curve);
a.relative = false;

How open would you be to a nicer drawing API for polygons?

I'm open to easier APIs! But, I have to disagree with you that that API is easier. Let me explain myself. I've found that in my projects and experience I rarely ever create shapes that have both straight lines and curved lines programmatically or hand-scripted as in your example. The shape is either all curved or all straight and the Two.js API makes that as easy as possible.

There are certainly instances where I've imported a shape (namely SVGs) that is made up of both straight and curved lines and wanted to modify it. Two.js supports that as well. But I've never really constructed shapes like the one you're trying to make in code.

I'd love to see some more examples of shapes you're trying to draw and find an easier API to draw them.

r-pluss commented 7 years ago

@jonobr1

Any chance you could provide an updated example for this?

I'm assuming this probably worked correctly when you posted it, but running it under the current version of two.js throws an error Error: <path> attribute transform: Expected number, "matrix(NaN NaN NaN NaN …".

I have been beating my head against the wall trying to figure out how to add a curve to a path with this library. At this point, I'm guessing it may not be possible, as every anchor of the type Two.Commands.curve that is passed to the path constructor appears to be silently converted to a line anchor.

jonobr1 commented 7 years ago

As of v0.5.0 @r-pluss the Two.Polygon functionality moved to Two.Path. Two.Polygon is now an n-sided closed primitive, aka n-gon.

Here's the updated example: https://jsfiddle.net/jonobr1/qf6zeb8e/

jonobr1 commented 7 years ago

Closing out. For anyone interested in using an API similar to the one Rune is describing check out his self-titled library: https://github.com/runemadsen/rune.js 🥇