Skip to content

Broke out a piece of a larger app to try to tackle some SwiftUI challenges.

Notifications You must be signed in to change notification settings

JetForMe/SplineEditor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Attempting to implement, in SwiftUI, a spline curve editor for non-linear scaling (e.g. animation curves, terrain generation, etc.).

The green line is the x,y = f(t) curve drawn using SwiftUI Path (using addCurve(to:control1:control2:)). The black line is y = f(x) drawn as piecewise linear segments (also using Path).

I’m struggling with a few major concerns, and some influence others:

  • The most appropriate View factoring and organization. Should the axes be collected into their own view? Should the X- and Y-axes be two separate views? They need to connect and overlap nicely at the origin, and it’s probably best to stroke both paths at the same time (which I’m not even doing now).

    I think I’ve settled on having an Axes container view that ZStacks a GeometryReader (for drawing the axes) with the contents provided to it. The contents are each curve, and the control points’ handles (this part isn't implemented yet; they’re all in the same ZStack in Curves).

  • Transforms. The curves are computed in a normalized space over [0.0, 1.0]. So I need to get the current dimensions of the graph area and scale the values appropriately to draw them. I also need to do the inverse when dragging control points or tracking mouse movement. I also need to invert the y-axis because the graph origin is near the bottom of the view.

  • Tracking mouse movement. I want to be able to show input and output values as the user hovers over the curve. I’m using SwiftUI Lab’s excellent approach that uses NSView and NSTrackingArea.

    A serious issue arises when I enable the tracking view: the scaling/translation of the contained views changes dramatically.

  • Drawing control points. I’ve been able to draw control points using Path, but it seems a more idiomatic SwiftUI approach is to use the Circle shape. But I don’t understand scaling and translating a View or Shape very well (e.g. using .offset() and .scale(). You can toggle between Path drawing and Circle() drawing with the checkbox in the corner.

  • Dragging control points. The few examples in the docs and online generally attach a drag gesture handler to the View to be dragged. I tried this and it didn't work (but also my shapes are not drawn in the right place because I don't have the transforms correct).

  • Drawing text along the axes tick marks. I can try using Text views, but is that best way to do it? In the past I would have used Core Graphics to draw the text directly, rather than try to sprinkle NSTextFields in there.

About

Broke out a piece of a larger app to try to tackle some SwiftUI challenges.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages