no-wrap option; pivoted exponential zoom
This commit is contained in:
+37
-10
@@ -21,6 +21,10 @@ type RenderOptions struct {
|
||||
Style *RenderStyle
|
||||
// Incremental controls incremental pan behavior. If nil, defaults are used.
|
||||
Incremental *IncrementalPolicy
|
||||
// DisableWrapScroll controls whether the world is treated as a torus (false)
|
||||
// or as a bounded plane without wrap (true).
|
||||
// Default is false.
|
||||
DisableWrapScroll bool
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -66,7 +70,7 @@ func (p RenderParams) CanvasHeightPx() int { return p.ViewportHeightPx + 2*p.Mar
|
||||
|
||||
// CameraZoomFp converts the UI-facing zoom value into the package fixed-point form.
|
||||
func (p RenderParams) CameraZoomFp() (int, error) {
|
||||
return cameraZoomToWorldFixed(p.CameraZoom)
|
||||
return CameraZoomToWorldFixed(p.CameraZoom)
|
||||
}
|
||||
|
||||
// ExpandedCanvasWorldRect returns the world-space half-open rectangle covered by
|
||||
@@ -210,6 +214,8 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
|
||||
layers = params.Options.Layers
|
||||
}
|
||||
|
||||
allowWrap := params.Options == nil || !params.Options.DisableWrapScroll
|
||||
|
||||
// --- Try incremental path first when state is initialized and geometry matches ---
|
||||
dxPx, dyPx, derr := w.ComputePanShiftPx(params)
|
||||
if derr == nil {
|
||||
@@ -246,13 +252,13 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
|
||||
switch layer {
|
||||
case RenderLayerPoints:
|
||||
applyPointStyle(drawer, style)
|
||||
drawPointsFromPlanWithRadius(drawer, catchUpPlan, w.W, w.H, style.PointRadiusPx)
|
||||
drawPointsFromPlanWithRadius(drawer, catchUpPlan, w.W, w.H, style.PointRadiusPx, allowWrap)
|
||||
case RenderLayerCircles:
|
||||
applyCircleStyle(drawer, style)
|
||||
drawCirclesFromPlan(drawer, catchUpPlan, w.W, w.H)
|
||||
drawCirclesFromPlan(drawer, catchUpPlan, w.W, w.H, allowWrap)
|
||||
case RenderLayerLines:
|
||||
applyLineStyle(drawer, style)
|
||||
drawLinesFromPlan(drawer, catchUpPlan, w.W, w.H)
|
||||
drawLinesFromPlan(drawer, catchUpPlan, w.W, w.H, allowWrap)
|
||||
default:
|
||||
panic("render: unknown layer")
|
||||
}
|
||||
@@ -319,13 +325,13 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
|
||||
switch layer {
|
||||
case RenderLayerPoints:
|
||||
applyPointStyle(drawer, style)
|
||||
drawPointsFromPlanWithRadius(drawer, dirtyPlan, w.W, w.H, style.PointRadiusPx)
|
||||
drawPointsFromPlanWithRadius(drawer, dirtyPlan, w.W, w.H, style.PointRadiusPx, allowWrap)
|
||||
case RenderLayerCircles:
|
||||
applyCircleStyle(drawer, style)
|
||||
drawCirclesFromPlan(drawer, dirtyPlan, w.W, w.H)
|
||||
drawCirclesFromPlan(drawer, dirtyPlan, w.W, w.H, allowWrap)
|
||||
case RenderLayerLines:
|
||||
applyLineStyle(drawer, style)
|
||||
drawLinesFromPlan(drawer, dirtyPlan, w.W, w.H)
|
||||
drawLinesFromPlan(drawer, dirtyPlan, w.W, w.H, allowWrap)
|
||||
default:
|
||||
panic("render: unknown layer")
|
||||
}
|
||||
@@ -352,13 +358,13 @@ func (w *World) Render(drawer PrimitiveDrawer, params RenderParams) error {
|
||||
switch layer {
|
||||
case RenderLayerPoints:
|
||||
applyPointStyle(drawer, style)
|
||||
drawPointsFromPlanWithRadius(drawer, plan, w.W, w.H, style.PointRadiusPx)
|
||||
drawPointsFromPlanWithRadius(drawer, plan, w.W, w.H, style.PointRadiusPx, allowWrap)
|
||||
case RenderLayerCircles:
|
||||
applyCircleStyle(drawer, style)
|
||||
drawCirclesFromPlan(drawer, plan, w.W, w.H)
|
||||
drawCirclesFromPlan(drawer, plan, w.W, w.H, allowWrap)
|
||||
case RenderLayerLines:
|
||||
applyLineStyle(drawer, style)
|
||||
drawLinesFromPlan(drawer, plan, w.W, w.H)
|
||||
drawLinesFromPlan(drawer, plan, w.W, w.H, allowWrap)
|
||||
default:
|
||||
panic("render: unknown layer")
|
||||
}
|
||||
@@ -448,6 +454,27 @@ func tileWorldRect(rect Rect, worldWidthFp, worldHeightFp int) []WorldTile {
|
||||
return out
|
||||
}
|
||||
|
||||
// tileWorldRectNoWrap returns 0..1 tiles for a bounded world (no wrap).
|
||||
// It intersects the expanded unwrapped rect with the canonical world [0..W)x[0..H).
|
||||
func tileWorldRectNoWrap(worldRect Rect, W, H int) []WorldTile {
|
||||
ix0 := max(worldRect.minX, 0)
|
||||
iy0 := max(worldRect.minY, 0)
|
||||
ix1 := min(worldRect.maxX, W)
|
||||
iy1 := min(worldRect.maxY, H)
|
||||
|
||||
if ix0 >= ix1 || iy0 >= iy1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []WorldTile{
|
||||
{
|
||||
Rect: Rect{minX: ix0, maxX: ix1, minY: iy0, maxY: iy1},
|
||||
OffsetX: 0,
|
||||
OffsetY: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func isEmptyRectPx(r RectPx) bool {
|
||||
return r.W <= 0 || r.H <= 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user