Tracer - a SVG based drag&drop UI allowing users to trace paths on top of an image (two.js or other, optionally React)

Job ID: 33360587

Budget: $30 – $250 USD

Tracer

The aim of this project is to offer a component that allows the user to edit paths to trace a single character. The project will be integrated into a React application (you can build in plain JS or use React). You can assume modern JS and can use any npm packages you find reasonable. Browser compatibility and UI is not a concern - your work will later be integrated into an existing admin site.

As a point of reference for Tracer, see https://codepen.io/jonobr1/pen/jOLQoov
This codepen shows the letter C made up of 1 path, which consists of 5 points.

A basic mockup/wireframe of what the finished project should look like: https://i.imgur.com/1HAOvS9.png

Pointers/requirements
1. Use two.js (we can consider other options, as long as we work within SVG). A very good starting point could be the codepen linked above. It captures most of the "core" functionality around editing a single path.
2. Tracer will receive a path to a local .ttf file and the character as parameters. The character should be displayed in grey, at a hardcoded size, "under" the paths. Optionally, an existing parameter will be passed, containing paths in the same format as the "save" function's output.
3. For all outputs, the return of a function (or console.log) is enough. Keep in mind Tracer will be integrated into an existing application.
4. For all inputs, use function/constructor arguments. They can be hardcoded in one place.
5. All SVG coordinates should be absolute (uppercase C, not c). This also applies to saving, loading and exporting.
6. It is up to you how paths are saved/loaded - this can be a svg string per path or an array of points, maybe there's a package for serialization. Whatever format you use for saving, will be passed when loading an existing character's paths.
7. Paths:
7.1. Paths should be listed outside of the SVG element in the DOM, stacked vertically.
7.2. Next to each path, there should be two buttons, to [Edit] and [Delete] the path.
7.3. Only one path can be edited at a time.
7.4. Below the list of paths, show a [New path] button that creates a new path and starts editing it.
7.5. The path that is being edited should change colour in the SVG.
8. Points & handles:
8.1. Only display points (and Bezier handles) on a path that is being edited.
8.2. Indicate the first point of the path (via colour or outline).
8.3. Use the provided codepen as an idea for dragging points and Bezier handles, with one exception: Handles should be visible for all points.
8.4. Points are added by ctrl-clicking on the SVG in an empty area. A new point is always added as the last one in the currently edited path.
8.5. Points are deleted by ctrl-clicking an existing point. This should be indicated by a color change when user hovers over a point with the ctrl key down.
8.6. Bezier handles cannot be deleted and should not react to ctrl-hover or -click. They should also be visually linked to their point like in the codepen. The first and last point should only display one bezier handle.
8.7. Use sensible defaults for initial positioning of the Bezier handles: When a new point is added, add an "outgoing" handle at 33% between the last point and the newest one, and an "incoming" handle at 66% of that distance. This results in a straight line.
9. Exporting: The export function should produce series of XY points on each path. There should be a resolution parameter that changes how far apart the points are. This should not be relative to the path's length or the number of points in the path. This is a one-way operation that should not modify the svg.
10. User should be able to pan and zoom the tracing area, so that bezier handles can be placed farther away.

If at any point you are unclear about the requirements, something doesn't make sense or takes a lot of effort, or have a suggestion on improvement, please don't hesitate and reach out! We're very open to adjustments as necessary and happy to consider better/simpler ways to get there!
Related categories: JavaScript CSS HTML5 React.js SVG