Makie integration
FlyThroughPaths.jl is integrated with Makie.jl LScenes, which are  the standard axis for 3-D plots.
Orbiting a point
Here's a simple example:
using GLMakie, FlyThroughPaths
fig, ax, plt = surface(-8..8, -8..8, Makie.peaks())
Now, we can use FlyThroughPaths to orbit the camera around the  current lookat point, by changing the eye position.
Extracting the view
First, we extract the initial view state from the axis ax.
view0 = capture_view(ax)ViewState{Float32}(eyeposition=[27.010298, 26.64446, 26.17957], lookat=[1.5949945, 1.2291565, 0.76426506], upvector=[-0.4082483, -0.4082483, 0.8164966], fov=45.0)Note that this ViewState is a Float32 object, since that's the space Makie cameras work in.  If you want this to be Float64, you can  simply convert(ViewState{Float64}, view0).
Creating a path
Next, we create a Path with this initial state.
path = Path(view0)Path{Float32}(ViewState{Float32}(eyeposition=[27.010298, 26.64446, 26.17957], lookat=[1.5949945, 1.2291565, 0.76426506], upvector=[-0.4082483, -0.4082483, 0.8164966], fov=45.0), FlyThroughPaths.PathChange{Float32}[])We've now created a Path object with an initial state view0.   Paths contain instructions for how to move the camera in time, and  you can add to a path by path * new_component.
path = path * ConstrainedMove(
    5,          # the amount of time the move should take
    ViewState(eyeposition = [0, 0, 46]), # the final state of the camera
    :rotation,  # the rotation constraint (can also be `:none`)
    :constant   # the type of interpolation (can also be `:sinusoidal`)
)Path{Float32}(ViewState{Float32}(eyeposition=[27.010298, 26.64446, 26.17957], lookat=[1.5949945, 1.2291565, 0.76426506], upvector=[-0.4082483, -0.4082483, 0.8164966], fov=45.0), FlyThroughPaths.PathChange{Float32}[ConstrainedMove{Float32}(5.0f0, ViewState{Float32}(eyeposition=[0.0, 0.0, 46.0]), :rotation, :constant, nothing)])Here, we've added a ConstrainedMove to the path, which moves the  camera to the point [0, 0, 46] in 5 seconds.
The reasons I chose these particular coordinates was to preserve the  norm (norm(view0.eyeposition) ≈ 46, norm(new) ≈ 46), so that the  rotation looks as elliptical as it can.
Animating the camera
Now, we can use Makie's record function to record an animation with  this:
record(fig, "path.mp4", LinRange(0, 5, 150); framerate = 30) do t
    set_view!(ax, path(t))
end"path.mp4"Zooming
We can also zoom in by changing the field of view, fov:
path = path * ConstrainedMove(5, ViewState(; fov = 10), :none, :sinusoidal)Path{Float32}(ViewState{Float32}(eyeposition=[27.010298, 26.64446, 26.17957], lookat=[1.5949945, 1.2291565, 0.76426506], upvector=[-0.4082483, -0.4082483, 0.8164966], fov=45.0), FlyThroughPaths.PathChange{Float32}[ConstrainedMove{Float32}(5.0f0, ViewState{Float32}(eyeposition=[0.0, 0.0, 46.0]), :rotation, :constant, nothing), ConstrainedMove{Float32}(5.0f0, ViewState{Float32}(fov=10.0), :none, :sinusoidal, nothing)])In this case, we chose sinusoidal interpolation to get a smooth zoom.
record(fig, "path_zoom.mp4", LinRange(5, 10, 150); framerate = 30) do t
    set_view!(ax, path(t))
end"path_zoom.mp4"Visualizing the camera's path
f2, a2, p2 = surface(-8..8, -8..8, Makie.peaks())
pathplot = FlyThroughPaths.plotcamerapath!(a2, path, 7)
Makie.rotate_cam!(a2.scene, 0, pi/4, 0)
f2
We can also animate the path to understand it more:
record(f2, "camera_path.mp4", LinRange(0, 5, 150); framerate = 30, update = false) do t
    pathplot.time[] = t
end"camera_path.mp4"Visualizing the viewing frustum
using Makie.GeometryBasics
# Initialize a rectangle that covers all of clip space in the initial Scene
frustum_clip_rect = Rect3d(Point3d(-1), Point3d(2))
# Convert that rectangle to a mesh
frustum_clip_mesh = lift(ax.scene.camera.projectionview) do _
    fcm = normal_mesh(frustum_clip_rect)
    # Project the mesh to `ax.scene`'s data space (which is shared with `a2.scene)
    frustum_world_points = Makie.project.(ax.scene, :clip, :data, fcm.position)
    # Reassign the projected points to the mesh positions
    fcm.position .= frustum_world_points
    return fcm
end
mesh!(a2.scene, frustum_clip_mesh; color = (:blue, 0.3), shading = Makie.MultiLightShading, xautolimits = false, yautolimits = false, zautolimits = false, transparency = false,)
wireframe!(a2.scene, frustum_clip_mesh; color = (:blue, 0.3), linewidth = 1, xautolimits = false)
f2
Since the frustum mesh is an Observable linked to the first Scene's camera, we can animate it at no extra cost!
record(f2, "camera_path_frustum.mp4", LinRange(0, 10, 300); framerate = 30, update = false) do t
    set_view!(ax, path(t))
    pathplot.time[] = t
end"camera_path_frustum.mp4"