better zoom and view
This commit is contained in:
parent
8037406b33
commit
35deeaba29
1 changed files with 86 additions and 33 deletions
119
pixler.bas
119
pixler.bas
|
|
@ -21,6 +21,8 @@ end type
|
|||
redim shared layers(3) as layertype
|
||||
dim shared state as statetype
|
||||
|
||||
dim shared showtoolbox as _byte: showtoolbox=-1
|
||||
dim shared showcolorpicker as _byte: showcolorpicker=-1
|
||||
|
||||
dim shared mouseclicked as integer
|
||||
dim shared mousedown as integer
|
||||
|
|
@ -86,13 +88,21 @@ do
|
|||
state.offsetY = state.offsetY + (_mousey - lastMY)
|
||||
end if
|
||||
lastMX = _mousex: lastMY = _mousey
|
||||
|
||||
|
||||
' Zooming
|
||||
if mw <> 0 then
|
||||
state.zoom = state.zoom + (mw * 0.1)
|
||||
if state.zoom < 0.1 then state.zoom = 0.1
|
||||
mw=0
|
||||
end if
|
||||
if mw <> 0 then
|
||||
' 1. Capture the current world position under the mouse
|
||||
dim mouseWorldX as single: mouseWorldX = (_mousex - state.offsetX) / state.zoom
|
||||
dim mouseWorldY as single: mouseWorldY = (_mousey - state.offsetY) / state.zoom
|
||||
' 2. Calculate the new zoom level
|
||||
state.zoom = state.zoom + (mw * 0.1 * state.zoom) ' Multiplier makes it feel smoother
|
||||
if state.zoom < 0.05 then state.zoom = 0.05
|
||||
if state.zoom > 20 then state.zoom = 20
|
||||
' 3. Adjust offsets so the world position stays under the mouse
|
||||
state.offsetX = _mousex - (mouseWorldX * state.zoom)
|
||||
state.offsetY = _mousey - (mouseWorldY * state.zoom)
|
||||
mw = 0
|
||||
end if
|
||||
|
||||
' Keyboarding
|
||||
keyin=inkey$
|
||||
|
|
@ -105,12 +115,19 @@ do
|
|||
'TODO: save logic
|
||||
case chr$(27)' esc
|
||||
'TODO: main menu
|
||||
|
||||
case "h"
|
||||
state.zoom = 1.0
|
||||
state.offsetX = (_width / 2) - (_width(layers(0).ihandle) / 2)
|
||||
state.offsetY = (_height / 2) - (_height(layers(0).ihandle) / 2)
|
||||
case "t"
|
||||
showtoolbox=not showtoolbox
|
||||
case "c"
|
||||
showcolorpicker=not showcolorpicker
|
||||
end select
|
||||
|
||||
canvas
|
||||
toolbox
|
||||
colorpicker
|
||||
canvas
|
||||
if showtoolbox then toolbox
|
||||
if showcolorpicker then colorpicker
|
||||
|
||||
_limit 30
|
||||
_display
|
||||
|
|
@ -155,26 +172,59 @@ sub colorpicker
|
|||
end sub
|
||||
|
||||
sub canvas
|
||||
dim boxX1 as integer: boxX1 = 70
|
||||
dim boxWidth as integer: boxWidth = _width - 1 - boxX1
|
||||
dim boxHeight as integer: boxHeight = _height - 20
|
||||
static polypoints(200) as single
|
||||
static pointCount as integer
|
||||
|
||||
' 1. Define the Viewport (The "Window" on your screen)
|
||||
dim viewX1 as integer
|
||||
if showtoolbox then viewX1 = 70 else viewX1 = 0
|
||||
dim viewY1 as integer: viewY1 = 0
|
||||
dim viewX2 as integer: viewX2 = _width - 1
|
||||
dim viewY2 as integer
|
||||
if showcolorpicker then viewY2 = _height - 20 else viewY2 = _height - 1
|
||||
|
||||
_dest 0
|
||||
line (boxX1, 0)-(_width - 1, boxHeight), _rgb32(32), bf
|
||||
|
||||
' 2. Render Layers with Clipping
|
||||
dim i as integer
|
||||
for i = 0 to ubound(layers)
|
||||
dim w as integer: w = _width(layers(i).ihandle) * state.zoom
|
||||
dim h as integer: h = _height(layers(i).ihandle) * state.zoom
|
||||
_putimage (state.offsetX, state.offsetY)-(state.offsetX + w, state.offsetY + h), layers(i).ihandle
|
||||
dim img as long: img = layers(i).ihandle
|
||||
dim imgW as integer: imgW = _width(img)
|
||||
dim imgH as integer: imgH = _height(img)
|
||||
|
||||
' Current scaled dimensions
|
||||
dim fullScaledW as single: fullScaledW = imgW * state.zoom
|
||||
dim fullScaledH as single: fullScaledH = imgH * state.zoom
|
||||
|
||||
' Calculate visible area in screen coordinates (Overlap of image and viewport)
|
||||
dim drawX1 as single: drawX1 = state.offsetX
|
||||
dim drawY1 as single: drawY1 = state.offsetY
|
||||
dim drawX2 as single: drawX2 = state.offsetX + fullScaledW
|
||||
dim drawY2 as single: drawY2 = state.offsetY + fullScaledH
|
||||
|
||||
' Clip the destination to the Viewport
|
||||
if drawX1 < viewX1 then drawX1 = viewX1
|
||||
if drawY1 < viewY1 then drawY1 = viewY1
|
||||
if drawX2 > viewX2 then drawX2 = viewX2
|
||||
if drawY2 > viewY2 then drawY2 = viewY2
|
||||
|
||||
' Only draw if the image is actually inside the viewport
|
||||
if drawX2 > drawX1 and drawY2 > drawY1 then
|
||||
' Map screen-clipped coordinates back to the source image coordinates
|
||||
dim srcX1 as single: srcX1 = (drawX1 - state.offsetX) / state.zoom
|
||||
dim srcY1 as single: srcY1 = (drawY1 - state.offsetY) / state.zoom
|
||||
dim srcX2 as single: srcX2 = (drawX2 - state.offsetX) / state.zoom
|
||||
dim srcY2 as single: srcY2 = (drawY2 - state.offsetY) / state.zoom
|
||||
|
||||
' Syntax: _PUTIMAGE (destX1, destY1)-(destX2, destY2), sourceHandle, 0, (srcX1, srcY1)-(srcX2, srcY2)
|
||||
_putimage (drawX1, drawY1)-(drawX2, drawY2), img, 0, (srcX1, srcY1)-(srcX2, srcY2)
|
||||
end if
|
||||
next
|
||||
|
||||
' 3. Calculate Canvas Coordinates
|
||||
dim canX as integer: canX = (_mousex - state.offsetX) / state.zoom
|
||||
dim canY as integer: canY = (_mousey - state.offsetY) / state.zoom
|
||||
|
||||
dim drawCol as _unsigned long
|
||||
drawCol = state.fcolor
|
||||
static drawCol
|
||||
if _mousebutton(1) then drawCol = state.fcolor
|
||||
if _mousebutton(2) then drawCol = state.bcolor
|
||||
|
||||
' 4. Interaction Logic
|
||||
if _mousex > boxX1 then
|
||||
|
|
@ -189,7 +239,9 @@ sub canvas
|
|||
end if
|
||||
_dest 0
|
||||
_source 0
|
||||
exit sub
|
||||
end if
|
||||
|
||||
if state.tool = 7 or state.tool = 8 then
|
||||
if mouseclicked then
|
||||
polypoints(pointCount * 2) = canX
|
||||
|
|
@ -211,7 +263,7 @@ sub canvas
|
|||
cls , 0
|
||||
|
||||
select case state.tool
|
||||
case 1 ' Pencil: This is the only tool that writes to Layer 1 IMMEDIATELY
|
||||
case 1 ' Pencil
|
||||
_dest layers(1).ihandle
|
||||
thickline state.startX, state.startY, canX, canY, drawCol
|
||||
state.startX = canX: state.startY = canY
|
||||
|
|
@ -233,9 +285,9 @@ sub canvas
|
|||
case 7, 8 ' Polygons
|
||||
if pointCount > 0 then
|
||||
for p = 1 to pointCount - 1
|
||||
thickline polypoints((p - 1) * 2), polypoints((p - 1) * 2 + 1), polypoints(p * 2), polypoints(p * 2 + 1), drawCol
|
||||
thickline polypoints((p - 1) * 2), polypoints((p - 1) * 2 + 1), polypoints(p * 2), polypoints(p * 2 + 1), state.fcolor
|
||||
next p
|
||||
thickline polypoints((pointCount - 1) * 2), polypoints((pointCount - 1) * 2 + 1), canX, canY, drawCol
|
||||
thickline polypoints((pointCount - 1) * 2), polypoints((pointCount - 1) * 2 + 1), canX, canY, state.fcolor
|
||||
end if
|
||||
end select
|
||||
|
||||
|
|
@ -244,7 +296,7 @@ sub canvas
|
|||
if state.tool = 7 or state.tool = 8 then
|
||||
if rmouseclicked then commit = -1
|
||||
else
|
||||
if mousedown = 0 then commit = -1
|
||||
if (mousedown=0) and (rmousedown=0) then commit = -1
|
||||
end if
|
||||
|
||||
if commit then
|
||||
|
|
@ -252,7 +304,7 @@ sub canvas
|
|||
if (state.tool = 8 or state.tool=7) and pointCount > 2 then
|
||||
redim finalP(pointCount * 2 - 1) as long
|
||||
for p = 0 to (pointCount * 2) - 1: finalP(p) = polypoints(p): next
|
||||
if state.tool =8 then filledPolygon finalP(), drawCol else Polygon finalP(), drawCol
|
||||
if state.tool =8 then filledPolygon finalP(), state.fcolor else Polygon finalP(), state.fcolor
|
||||
else
|
||||
' Merge the preview into the drawing layer
|
||||
_putimage , layers(2).ihandle, layers(1).ihandle
|
||||
|
|
@ -264,7 +316,7 @@ sub canvas
|
|||
end if
|
||||
end if
|
||||
end if
|
||||
_dest 0 ' Ensure we return to main screen[cite: 1]
|
||||
_dest 0 ' Ensure we return to main screen
|
||||
end sub
|
||||
|
||||
function icon (index as long)
|
||||
|
|
@ -274,11 +326,11 @@ function icon (index as long)
|
|||
redim icons(19) as long ' Room for 20 icons
|
||||
|
||||
' Define your specific tool icons here
|
||||
icons(0) = _newimage(32, 32, 32): _dest icons(0): line (5, 27)-(27, 5): _dest 0
|
||||
icons(1) = _newimage(32, 32, 32): _dest icons(1): circle (15, 15), 13: _dest 0
|
||||
icons(2) = _newimage(32, 32, 32): _dest icons(2): line (5, 5)-(27, 27), , b: _dest 0
|
||||
icons(6) = _newimage(32, 32, 32): _dest icons(6)
|
||||
line (5, 15)-(15, 5): line -(25, 15): line -(20, 25): line -(10, 25): line -(5, 15)
|
||||
icons(0) = _newimage(32,32,32): _dest icons(0): line (5, 27)-(27, 5): _dest 0
|
||||
icons(1) = _newimage(32,32,32): _dest icons(1): circle (15, 15), 13: _dest 0
|
||||
icons(2) = _newimage(32,32,32): _dest icons(2): line (5, 5)-(27, 27), , b: _dest 0
|
||||
icons(6) = _newimage(32,32,32): _dest icons(6)
|
||||
line (5,15)-(15,5):line -(25,15):line -(20,25): line -(10,25):line -(5,15)
|
||||
_dest 0
|
||||
|
||||
icons(7) = _newimage(32, 32, 32): _dest icons(7)
|
||||
|
|
@ -311,6 +363,7 @@ end function
|
|||
'$include: 'include/imgout.bm'
|
||||
'$include: 'include/palette.bm'
|
||||
'$include: 'include/tools.bm'
|
||||
''$include: 'include/effects.bm'
|
||||
|
||||
function adduiicon(imagehandle as long)
|
||||
dim unknown as long
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue