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

[Feature]: toSvg() method for Geometry2d #3080

Open
1 task done
lorenzolewis opened this issue Mar 6, 2024 · 1 comment
Open
1 task done

[Feature]: toSvg() method for Geometry2d #3080

lorenzolewis opened this issue Mar 6, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@lorenzolewis
Copy link
Contributor

What's the feature?

If storing custom shape data as Geometry2d you will most likely need to render this out at some point. You can see a lot of this custom rendering happening internally already (examples below for brevity). I would suggest adding an abstract method to Geometry2d such as toSvg(shape: Geometry2d, props?: SVGProps<SVGSVGElement>): JSX.Element. By using props that would allow passing common attributes to customise such as color, stroke-width, etc.

External Usage

By exposing such a function as toSvg() to developers it will give them the option to define their geometry using the Geometry2d classes and easily render them. Of course, some developers may have much more custom use cases, but this provides a standard baseline for someone to start with.

I'm not exactly sure what the plans are for Geometry2d other than for basic debugging, indicators, and path collision checking, but adding this as a potential use case seems like a win to me.

Internal Cleanup

Some of this rendering functionality already exists in some of the internal Geo shapes. These are all using different approaches to create the path strings but are ultimately resulting in the same output. By centralising this in a single place it could help clean this up a bit (and also make it much easier to add additional shapes in the future, either internally or by 3rd-party devs).

There could be some difficulty for the drawn styles as some jitter is applied to those paths.

export function cloudSvgPath(

const d = `M${cx - rx},${cy}a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`

export function getOvalIndicatorPath(w: number, h: number) {

let path = 'M' + outline[0] + 'L' + outline.slice(1) + 'Z'

? `M${leftPoint.x},${leftPoint.y}A${radius},${radius},0,0,1,${rightPoint.x},${rightPoint.y}`
: `M${leftPoint.x},${leftPoint.y}L${rightPoint.x},${rightPoint.y}`

const d = `M${cx - rx},${cy}a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`

const innerPath = 'M' + outline[0] + 'L' + outline.slice(1) + 'Z'

export function inkyCloudSvgPath(

https://github.com/tldraw/tldraw/blob/main/packages/tldraw/src/lib/shapes/geo/components/DrawStylePolygon.tsx#L30

There are a few other places as well but I figure this gives enough examples

Implementation

There are a few different ways I could see implementing this (although if this is something that wants to be investigated I would love to hear feedback!):

  1. Using a single <path d="complex path data here" /> and returning that from the function
  2. Using any relevant SVG elements such as rect, ellipse, polyline, etc. Some of the more complex Geometry2d classes (such as Stadium2d) may need to fall back to a custom <path /> element. This would return the relevant path for each.

Barriers to implementation

Looking at Arc2d as an example, using an elliptical arc curve we would need attributes such as large-arc-flag sweep-flag which as indeed used in the constructor of Arc2d, but aren't saved internally. This might need to be saved to help with rendering the relevant SVG element.

Additional notes

I would be happy to help out with a PR if desired with the guidance of the team.

May impact/be impacted by #3020


Hope this makes sense and thank you all for an awesome project!

Contact Details

tldraw Discord: lorenzolewis

Code of Conduct

  • I agree to follow this project's Code of Conduct
@lorenzolewis lorenzolewis added the enhancement New feature or request label Mar 6, 2024
Copy link

linear bot commented Mar 6, 2024

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

No branches or pull requests

1 participant