whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.16k stars 2.69k forks source link

Extensions to Canvas 2D context and the Path2D object #1612

Open ghost opened 8 years ago

ghost commented 8 years ago

I would like to propose the following extensions to the CanvasRenderingContext2D as well as the Path2D object:

It involves a new, lets call it for example SubPath object representing each internal sub-path on the main path on a Path2D or an CanvasRenderingContext2D instance.

For example:

SubPath.length -> [read-only property returning unsigned long]
SubPath.prototype.pointAt() -> Return point object holding x/y properties as unsigned long
SubPath.prototype.getBoundingPathRect() -> rectangle representing a sub-path's bounds

The object could be created on the fly when the following suggested method would be called, to wrap or point to the internal sub-path data:

CanvasRenderingContext2D.prototype.getSubPaths() -> Array holding SubPath objects
Path2D.prototype.getSubPaths()

Return an array holding each sub-path as a separate SubPath object. This would allow for obtaining information not readily available to the developer as of now (as one would have to replicate the process of generating simple, complex and combined paths manually, as well as transformations - or to avoid going via SVG):

subPath.length

obtains the length of current sub-path in pixels.

And to utilize the path data via:

subPath.pointAtT(t)

or

subPath.pointAt(p)

represents the key-feature in this proposal - gets (X,Y) point on path given normalized t [0,1] as argument (1 of course representing length) or a 1D pixel position p. This would allow for tracing/animating on the path(s) as well as [roughly] serialize the path itself.

CanvasRenderingContext2D.prototype.getBoundingPathRect()
Path2D.prototype.getBoundingPathRect()
SubPath.prototype.getBoundingPathRect()

returning a rectangle object representing a bound that can hold entire path (ala getBoundingClientRect()). For CanvasRenderingContext2D and Path2D it would of course include all sub-paths.

And finally allow addPath() to take a SubPath object.

If this has already been suggested, or it conflicts with existing plans, please ignore. In any case, thank you for reading.

zcorpan commented 8 years ago

Hello @epistemex 🙂

Can you elaborate on what underlying problem you are trying to solve?

Can you point to existing sites/apps that are working around the lack of the feature you are proposing, or would benefit from it?

Is there interest from implementors to solve this problem?

Please see https://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F

ghost commented 8 years ago

Hi @zcorpan, I can't point to specific libraries but I know it's a frequent question at stackoverflow (I'm the top user in the canvas tags there). In particular with Bezier's and how to move along its path for animation purposes and plotting. I will go through the linked FAQ too, thanks.

zcorpan commented 8 years ago

cc @junov

tabatkins commented 8 years ago

This is similar to the APIs on SVG's <path> element - https://svgwg.org/svg2-draft/types.html#InterfaceSVGGeometryElement defines getTotalLength() and getPointAtLength() methods on all geometry objects.

junov commented 8 years ago

I don't see why it is necessary to create a new SubPath interface. We could just have CanvasPath.getSubPaths() that returns an array of Path2D objects. And the other suggested APIs could all hang off of the CanvasPath interface IMHO. I see no problem in evaluatin length on a path composed of many sub-paths

I really think this proposal ought to be split into 3 simple orthogonal proposals (assuming we don't need SubPath):

This would allow each sub feature's merit and design to be discussed and tweaked independently of each other in neat little threads.