Progress on the Zoom In/Out Feature
* Got the level chunks AND the wallpaper to both scale UP and DOWN consistently together. * Trying to draw new pixels while zoomed in/out ends up offsetting the pixels by 2X still. Still seems an issue between screen coordinates and world coordinates. Zoom in 2X and try and draw a line 64px from the corners of the screen? The committed line appropriately lands at the 64px coord on the level data but, zoomed in, it appears 2X to the right on the screen from where I dropped the cursor! * When zooming OUT, the limit on number of chunks the viewport will try and render is not increased, leaving dead space in the screen; more chunks should render when there's room.
This commit is contained in:
parent
456863839e
commit
ed492a4451
|
@ -15,6 +15,19 @@ var (
|
||||||
Stroke: render.SkyBlue,
|
Stroke: render.SkyBlue,
|
||||||
Shadow: render.Black,
|
Shadow: render.Black,
|
||||||
}
|
}
|
||||||
|
TitleScreenSubtitleFont = render.Text{
|
||||||
|
FontFilename: "DejaVuSans.ttf",
|
||||||
|
Size: 18,
|
||||||
|
Color: render.SkyBlue,
|
||||||
|
Shadow: render.SkyBlue.Darken(128),
|
||||||
|
// Color: render.RGBA(255, 153, 0, 255),
|
||||||
|
// Shadow: render.RGBA(200, 80, 0, 255),
|
||||||
|
}
|
||||||
|
TitleScreenVersionFont = render.Text{
|
||||||
|
Size: 14,
|
||||||
|
Color: render.Grey,
|
||||||
|
Shadow: render.Black,
|
||||||
|
}
|
||||||
|
|
||||||
// Window and panel styles.
|
// Window and panel styles.
|
||||||
TitleConfig = ui.Config{
|
TitleConfig = ui.Config{
|
||||||
|
|
|
@ -7,6 +7,7 @@ const (
|
||||||
Version = "0.7.1"
|
Version = "0.7.1"
|
||||||
Website = "https://www.sketchymaze.com"
|
Website = "https://www.sketchymaze.com"
|
||||||
Copyright = "2021 Noah Petherbridge"
|
Copyright = "2021 Noah Petherbridge"
|
||||||
|
Byline = "a game by Noah Petherbridge."
|
||||||
|
|
||||||
// Update check URL
|
// Update check URL
|
||||||
UpdateCheckJSON = "https://download.sketchymaze.com/version.json"
|
UpdateCheckJSON = "https://download.sketchymaze.com/version.json"
|
||||||
|
|
|
@ -29,6 +29,7 @@ type MainScene struct {
|
||||||
|
|
||||||
// UI components.
|
// UI components.
|
||||||
labelTitle *ui.Label
|
labelTitle *ui.Label
|
||||||
|
labelSubtitle *ui.Label
|
||||||
labelVersion *ui.Label
|
labelVersion *ui.Label
|
||||||
labelHint *ui.Label
|
labelHint *ui.Label
|
||||||
frame *ui.Frame // Main button frame
|
frame *ui.Frame // Main button frame
|
||||||
|
@ -66,6 +67,13 @@ func (s *MainScene) Setup(d *Doodle) error {
|
||||||
})
|
})
|
||||||
s.labelTitle.Compute(d.Engine)
|
s.labelTitle.Compute(d.Engine)
|
||||||
|
|
||||||
|
// Subtitle/byline.
|
||||||
|
s.labelSubtitle = ui.NewLabel(ui.Label{
|
||||||
|
Text: branding.Byline,
|
||||||
|
Font: balance.TitleScreenSubtitleFont,
|
||||||
|
})
|
||||||
|
s.labelSubtitle.Compute(d.Engine)
|
||||||
|
|
||||||
// Version label.
|
// Version label.
|
||||||
var shareware string
|
var shareware string
|
||||||
if !license.IsRegistered() {
|
if !license.IsRegistered() {
|
||||||
|
@ -73,11 +81,7 @@ func (s *MainScene) Setup(d *Doodle) error {
|
||||||
}
|
}
|
||||||
ver := ui.NewLabel(ui.Label{
|
ver := ui.NewLabel(ui.Label{
|
||||||
Text: fmt.Sprintf("v%s%s", branding.Version, shareware),
|
Text: fmt.Sprintf("v%s%s", branding.Version, shareware),
|
||||||
Font: render.Text{
|
Font: balance.TitleScreenVersionFont,
|
||||||
Size: 18,
|
|
||||||
Color: render.Grey,
|
|
||||||
Shadow: render.Black,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
ver.Compute(d.Engine)
|
ver.Compute(d.Engine)
|
||||||
s.labelVersion = ver
|
s.labelVersion = ver
|
||||||
|
@ -372,10 +376,17 @@ func (s *MainScene) Draw(d *Doodle) error {
|
||||||
})
|
})
|
||||||
s.labelTitle.Present(d.Engine, s.labelTitle.Point())
|
s.labelTitle.Present(d.Engine, s.labelTitle.Point())
|
||||||
|
|
||||||
|
// App subtitle label (byline).
|
||||||
|
s.labelSubtitle.MoveTo(render.Point{
|
||||||
|
X: (d.width / 2) - (s.labelSubtitle.Size().W / 2),
|
||||||
|
Y: s.labelTitle.Point().Y + s.labelTitle.Size().H + 8,
|
||||||
|
})
|
||||||
|
s.labelSubtitle.Present(d.Engine, s.labelSubtitle.Point())
|
||||||
|
|
||||||
// Version label
|
// Version label
|
||||||
s.labelVersion.MoveTo(render.Point{
|
s.labelVersion.MoveTo(render.Point{
|
||||||
X: (d.width / 2) - (s.labelVersion.Size().W / 2),
|
X: (d.width / 2) - (s.labelVersion.Size().W / 2),
|
||||||
Y: s.labelTitle.Point().Y + s.labelTitle.Size().H + 8,
|
Y: s.labelSubtitle.Point().Y + s.labelSubtitle.Size().H + 8,
|
||||||
})
|
})
|
||||||
s.labelVersion.Present(d.Engine, s.labelVersion.Point())
|
s.labelVersion.Present(d.Engine, s.labelVersion.Point())
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@ func (w *Canvas) commitStroke(tool drawtool.Tool, addHistory bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom the stroke coordinates (this modifies the pointer)
|
// Zoom the stroke coordinates (this modifies the pointer)
|
||||||
zStroke := w.ZoomStroke(w.currentStroke)
|
w.currentStroke = w.ZoomStroke(w.currentStroke)
|
||||||
_ = zStroke
|
|
||||||
|
|
||||||
// Mark the canvas as modified.
|
// Mark the canvas as modified.
|
||||||
w.modified = true
|
w.modified = true
|
||||||
|
|
|
@ -15,6 +15,11 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
var (
|
var (
|
||||||
S = w.Size()
|
S = w.Size()
|
||||||
Viewport = w.Viewport()
|
Viewport = w.Viewport()
|
||||||
|
// Bezel = render.NewRect(
|
||||||
|
// p.X+w.Scroll.X+w.BoxThickness(1),
|
||||||
|
// p.Y+w.Scroll.Y+w.BoxThickness(1),
|
||||||
|
// )
|
||||||
|
// zoomMultiplier = int(w.GetZoomMultiplier())
|
||||||
)
|
)
|
||||||
// w.MoveTo(p) // TODO: when uncommented the canvas will creep down the Workspace frame in EditorMode
|
// w.MoveTo(p) // TODO: when uncommented the canvas will creep down the Workspace frame in EditorMode
|
||||||
w.DrawBox(e, p)
|
w.DrawBox(e, p)
|
||||||
|
@ -44,7 +49,11 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom in the texture.
|
// Zoom in the texture.
|
||||||
texSize := tex.Size()
|
var (
|
||||||
|
texSize = tex.Size()
|
||||||
|
texSizeOrig = tex.Size()
|
||||||
|
)
|
||||||
|
|
||||||
if w.Zoom != 0 {
|
if w.Zoom != 0 {
|
||||||
texSize.W = w.ZoomMultiply(texSize.W)
|
texSize.W = w.ZoomMultiply(texSize.W)
|
||||||
texSize.H = w.ZoomMultiply(texSize.H)
|
texSize.H = w.ZoomMultiply(texSize.H)
|
||||||
|
@ -66,8 +75,8 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dst := render.Rect{
|
dst := render.Rect{
|
||||||
X: p.X + w.Scroll.X + w.BoxThickness(1) + (coord.X * chunk.Size),
|
X: p.X + w.Scroll.X + w.BoxThickness(1) + w.ZoomMultiply(coord.X*chunk.Size),
|
||||||
Y: p.Y + w.Scroll.Y + w.BoxThickness(1) + (coord.Y * chunk.Size),
|
Y: p.Y + w.Scroll.Y + w.BoxThickness(1) + w.ZoomMultiply(coord.Y*chunk.Size),
|
||||||
|
|
||||||
// src.W and src.H will be AT MOST the full width and height of
|
// src.W and src.H will be AT MOST the full width and height of
|
||||||
// a Canvas widget. Subtract the scroll offset to keep it bounded
|
// a Canvas widget. Subtract the scroll offset to keep it bounded
|
||||||
|
@ -76,16 +85,6 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
H: src.H,
|
H: src.H,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom the destination rect.
|
|
||||||
if w.Zoom != 0 {
|
|
||||||
// dst.X += int(w.GetZoomMultiplier())
|
|
||||||
// dst.Y += int(w.GetZoomMultiplier())
|
|
||||||
// dst.X = w.ZoomMultiply(dst.X)
|
|
||||||
// dst.Y = w.ZoomMultiply(dst.Y)
|
|
||||||
// dst.W = w.ZoomMultiply(dst.W)
|
|
||||||
// dst.H = w.ZoomMultiply(dst.H)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: all this shit is in TrimBox(), make it DRY
|
// TODO: all this shit is in TrimBox(), make it DRY
|
||||||
|
|
||||||
// If the destination width will cause it to overflow the widget
|
// If the destination width will cause it to overflow the widget
|
||||||
|
@ -144,6 +143,21 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
dst.W = S.W - w.BoxThickness(1)
|
dst.W = S.W - w.BoxThickness(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if w.Zoom < 0 {
|
||||||
|
log.Warn("dst: %+v", dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// When zooming OUT, make sure the source rect is at least the
|
||||||
|
// full size of the chunk texture; otherwise the ZoomMultiplies
|
||||||
|
// above do correctly scale e.g. 128x128 to 64x64, but it only
|
||||||
|
// samples the top-left 64x64 then and not the full texture so
|
||||||
|
// it more crops it than scales it, but does fit it neatly with
|
||||||
|
// its neighbors.
|
||||||
|
if w.Zoom < 0 {
|
||||||
|
src.W = texSizeOrig.W
|
||||||
|
src.H = texSizeOrig.H
|
||||||
|
}
|
||||||
|
|
||||||
e.Copy(tex, src, dst)
|
e.Copy(tex, src, dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ func (w *Canvas) PresentWallpaper(e render.Engine, p render.Point) error {
|
||||||
wp = w.wallpaper
|
wp = w.wallpaper
|
||||||
S = w.Size()
|
S = w.Size()
|
||||||
size = wp.corner.Size()
|
size = wp.corner.Size()
|
||||||
|
sizeOrig = wp.corner.Size()
|
||||||
|
|
||||||
// Get the relative viewport of world coordinates looked at by the canvas.
|
// Get the relative viewport of world coordinates looked at by the canvas.
|
||||||
// The X,Y values are the negative Scroll value
|
// The X,Y values are the negative Scroll value
|
||||||
|
@ -187,17 +188,20 @@ func (w *Canvas) PresentWallpaper(e render.Engine, p render.Point) error {
|
||||||
H: src.H,
|
H: src.H,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom the output texture.
|
|
||||||
if w.Zoom != 0 {
|
|
||||||
// dst.X = w.ZoomMultiply(dst.X - p.X)
|
|
||||||
// dst.Y = w.ZoomMultiply(dst.Y - p.Y)
|
|
||||||
// dst.W = w.ZoomMultiply(dst.W)
|
|
||||||
// dst.H = w.ZoomMultiply(dst.H)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim the edges of the destination box, like in canvas.go#Present
|
// Trim the edges of the destination box, like in canvas.go#Present
|
||||||
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
||||||
|
|
||||||
|
// When zooming OUT, make sure the source rect is at least the
|
||||||
|
// full size of the chunk texture; otherwise the ZoomMultiplies
|
||||||
|
// above do correctly scale e.g. 128x128 to 64x64, but it only
|
||||||
|
// samples the top-left 64x64 then and not the full texture so
|
||||||
|
// it more crops it than scales it, but does fit it neatly with
|
||||||
|
// its neighbors.
|
||||||
|
if w.Zoom < 0 {
|
||||||
|
src.W = sizeOrig.W
|
||||||
|
src.H = sizeOrig.H
|
||||||
|
}
|
||||||
|
|
||||||
e.Copy(wp.repeat, src, dst)
|
e.Copy(wp.repeat, src, dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,12 +220,10 @@ func (w *Canvas) PresentWallpaper(e render.Engine, p render.Point) error {
|
||||||
H: src.H,
|
H: src.H,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom the output texture.
|
// Zoom-out min size constraint.
|
||||||
if w.Zoom != 0 {
|
if w.Zoom < 0 {
|
||||||
// dst.X = w.ZoomMultiply(dst.X - origin.X)
|
src.W = sizeOrig.W
|
||||||
// dst.Y = w.ZoomMultiply(dst.Y - origin.Y)
|
src.H = sizeOrig.H
|
||||||
// dst.W = w.ZoomMultiply(dst.W)
|
|
||||||
// dst.H = w.ZoomMultiply(dst.H)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
||||||
|
@ -241,12 +243,10 @@ func (w *Canvas) PresentWallpaper(e render.Engine, p render.Point) error {
|
||||||
H: src.H,
|
H: src.H,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom the output texture.
|
// Zoom-out min size constraint.
|
||||||
if w.Zoom != 0 {
|
if w.Zoom < 0 {
|
||||||
// dst.X = w.ZoomMultiply(dst.X - origin.X)
|
src.W = sizeOrig.W
|
||||||
// dst.Y = w.ZoomMultiply(dst.Y - origin.Y)
|
src.H = sizeOrig.H
|
||||||
// dst.W = w.ZoomMultiply(dst.W)
|
|
||||||
// dst.H = w.ZoomMultiply(dst.H)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
||||||
|
@ -266,12 +266,10 @@ func (w *Canvas) PresentWallpaper(e render.Engine, p render.Point) error {
|
||||||
H: src.H,
|
H: src.H,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom the output texture.
|
// Zoom out min size constraint.
|
||||||
if w.Zoom != 0 {
|
if w.Zoom < 0 {
|
||||||
// dst.X = w.ZoomMultiply(dst.X - origin.X)
|
src.W = sizeOrig.W
|
||||||
// dst.Y = w.ZoomMultiply(dst.Y - origin.Y)
|
src.H = sizeOrig.H
|
||||||
// dst.W = w.ZoomMultiply(dst.W)
|
|
||||||
// dst.H = w.ZoomMultiply(dst.H)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
render.TrimBox(&src, &dst, p, S, w.BoxThickness(1))
|
||||||
|
|
|
@ -60,13 +60,37 @@ func (w *Canvas) ZoomMultiply(value int) int {
|
||||||
return int(float64(value) * w.GetZoomMultiplier())
|
return int(float64(value) * w.GetZoomMultiplier())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ZoomDivide divides an integer by the zoom inversely.
|
||||||
|
*/
|
||||||
|
func (w *Canvas) ZoomDivide(value int) int {
|
||||||
|
var divider float64
|
||||||
|
switch w.Zoom {
|
||||||
|
case -2:
|
||||||
|
divider = 2
|
||||||
|
case -1:
|
||||||
|
divider = 2
|
||||||
|
case 0:
|
||||||
|
divider = 1
|
||||||
|
case 1:
|
||||||
|
divider = 0.5
|
||||||
|
case 2:
|
||||||
|
divider = 0.25
|
||||||
|
case 3:
|
||||||
|
divider = 0.125
|
||||||
|
default:
|
||||||
|
divider = 1
|
||||||
|
}
|
||||||
|
return int(float64(value) * divider)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ZoomStroke adjusts a drawn stroke on the canvas to account for the zoom level.
|
ZoomStroke adjusts a drawn stroke on the canvas to account for the zoom level.
|
||||||
|
|
||||||
Returns a copy Stroke value without changing the original.
|
Returns a copy Stroke value without changing the original.
|
||||||
*/
|
*/
|
||||||
func (w *Canvas) ZoomStroke(stroke *drawtool.Stroke) drawtool.Stroke {
|
func (w *Canvas) ZoomStroke(stroke *drawtool.Stroke) *drawtool.Stroke {
|
||||||
copy := drawtool.Stroke{
|
copy := &drawtool.Stroke{
|
||||||
ID: stroke.ID,
|
ID: stroke.ID,
|
||||||
Shape: stroke.Shape,
|
Shape: stroke.Shape,
|
||||||
Color: stroke.Color,
|
Color: stroke.Color,
|
||||||
|
@ -82,8 +106,8 @@ func (w *Canvas) ZoomStroke(stroke *drawtool.Stroke) drawtool.Stroke {
|
||||||
// Multiply all coordinates in this stroke, which should be World
|
// Multiply all coordinates in this stroke, which should be World
|
||||||
// Coordinates in the level data, by the zoom multiplier.
|
// Coordinates in the level data, by the zoom multiplier.
|
||||||
adjust := func(p render.Point) render.Point {
|
adjust := func(p render.Point) render.Point {
|
||||||
p.X = w.ZoomMultiply(p.X)
|
p.X = w.ZoomDivide(p.X)
|
||||||
p.Y = w.ZoomMultiply(p.Y)
|
p.Y = w.ZoomDivide(p.Y)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user