Noah Petherbridge
ecdfc46358
Progress on the Zoom feature: when you zoom in and out, you can draw shapes accurately onto the level. Seems a little buggy if you edit while scrolling (as in drawing a very long line). The title screen buttons are now more colorful.
137 lines
2.7 KiB
Go
137 lines
2.7 KiB
Go
package uix
|
|
|
|
import (
|
|
"git.kirsle.net/apps/doodle/pkg/drawtool"
|
|
"git.kirsle.net/go/render"
|
|
)
|
|
|
|
// Functions related to the Zoom Tool to magnify the size of the canvas.
|
|
|
|
/*
|
|
GetZoomMultiplier parses the .Zoom integer and returns a multiplier.
|
|
|
|
Examples:
|
|
|
|
Zoom = 0: neutral (100% scale, 1x)
|
|
Zoom = 1: 2x zoom
|
|
Zoom = 2: 4x zoom
|
|
Zoom = 3: 8x zoom
|
|
Zoom = -1: 0.5x zoom
|
|
Zoom = -2: 0.25x zoom
|
|
*/
|
|
func (w *Canvas) GetZoomMultiplier() float64 {
|
|
// Get and bounds cap the zoom setting.
|
|
if w.Zoom < -2 {
|
|
w.Zoom = -2
|
|
} else if w.Zoom > 3 {
|
|
w.Zoom = 3
|
|
}
|
|
|
|
// Return the multipliers.
|
|
switch w.Zoom {
|
|
case -2:
|
|
return 0.25
|
|
case -1:
|
|
return 0.5
|
|
case 0:
|
|
return 1
|
|
case 1:
|
|
return 1.5
|
|
case 2:
|
|
return 2
|
|
case 3:
|
|
return 2.5
|
|
default:
|
|
return 1
|
|
}
|
|
}
|
|
|
|
/*
|
|
ZoomMultiply multiplies a width or height value by the Zoom Multiplier and
|
|
returns the modified integer.
|
|
|
|
Usage is like:
|
|
|
|
// when building a render.Rect destination box.
|
|
dest.W *= ZoomMultiply(dest.W)
|
|
dest.H *= ZoomMultiply(dest.H)
|
|
*/
|
|
func (w *Canvas) ZoomMultiply(value int) int {
|
|
return int(float64(value) * w.GetZoomMultiplier())
|
|
}
|
|
|
|
/*
|
|
ZoomDivide divides an integer by the zoom inversely.
|
|
|
|
The algo is: int(float64(value) * divider)
|
|
|
|
Where the divider is a map of:
|
|
|
|
w.Zoom => divider
|
|
-2 => 4
|
|
-1 => 2
|
|
0 => 1
|
|
1 => 0.675*
|
|
2 => 0.5
|
|
3 => 0.404*
|
|
|
|
The 0.675 and 0.404 numbers I don't understand but were
|
|
discovered the hard way when the 1.5x and 2.5x zoom levels
|
|
were coming out jank. Expected to be 0.25 and 0.75.
|
|
*/
|
|
func (w *Canvas) ZoomDivide(value int) int {
|
|
var divider float64
|
|
switch w.Zoom {
|
|
case -2:
|
|
divider = 4
|
|
case -1:
|
|
divider = 2
|
|
case 0:
|
|
divider = 1
|
|
case 1:
|
|
divider = 0.675 // JANK
|
|
case 2:
|
|
divider = 0.5 // GOOD, 2x (200%) zoom in
|
|
case 3:
|
|
divider = 0.404 // JANK
|
|
default:
|
|
divider = 1
|
|
}
|
|
return int(float64(value) * divider)
|
|
}
|
|
|
|
/*
|
|
ZoomStroke adjusts a drawn stroke on the canvas to account for the zoom level.
|
|
|
|
Returns a copy Stroke value without changing the original.
|
|
*/
|
|
func (w *Canvas) ZoomStroke(stroke *drawtool.Stroke) *drawtool.Stroke {
|
|
copy := &drawtool.Stroke{
|
|
ID: stroke.ID,
|
|
Shape: stroke.Shape,
|
|
Color: stroke.Color,
|
|
Thickness: stroke.Thickness,
|
|
ExtraData: stroke.ExtraData,
|
|
PointA: stroke.PointA,
|
|
PointB: stroke.PointB,
|
|
Points: stroke.Points,
|
|
OriginalPoints: stroke.OriginalPoints,
|
|
}
|
|
|
|
// Multiply all coordinates in this stroke, which should be World
|
|
// Coordinates in the level data, by the zoom multiplier.
|
|
adjust := func(p render.Point) render.Point {
|
|
p.X = w.ZoomDivide(p.X)
|
|
p.Y = w.ZoomDivide(p.Y)
|
|
return p
|
|
}
|
|
|
|
copy.PointA = adjust(copy.PointA)
|
|
copy.PointB = adjust(copy.PointB)
|
|
for i := range copy.Points {
|
|
copy.Points[i] = adjust(copy.Points[i])
|
|
}
|
|
|
|
return copy
|
|
}
|