Code archives/Graphics/Zoom-to-Mousewheel routine (2D)
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| The most important thing here is how objects are drawn to the screen. Check out the 'draw' method of my 'obj' type. Use the Mousewheel to zoom in / out, centered upong location of cursor. Click and drag to pan. Double clicking instantly zooms full-in on the mouse cursor. Please note that it may be used without MaxGUI, but you'll have to modify the code manually to input your desired screen resolution. The code below uses MaxGUI's GadgetWidth(Desktop()) to pick the desktop's native resolution automatically, but this is simply a convenience function and non essential to the program. You must enter Resolution width and height into GW and GH variables, respectively. | |||||
SuperStrict
Framework BRL.GLMax2D
Import BaH.Random
Import maxgui.drivers
Import BRL.PNGLoader
Import BRL.BMPLoader
Type obj
Global List:TList
Field X:Float
Field Y:Float
Field Size:Float
Field HalfSize:Float
Field R:Int
Field G:Int
Field B:Int
Method New()
X = Rand(0 , GW)
Y = Rand(0 , GH)
Size = Rnd(0 , 1)
Size = size^3
HalfSize = Size / 2.0
R = Rand(0,255)
G = Rand(0,255)
B = Rand(0 , 255)
If Not List Then List = New TList
List.AddLast(Self)
End Method
Method Draw(ZoomOriginX:Float,ZoomOriginY:Float,_VIEWSCALE:Float)
SetColor(r,g,b)
Local drawx:Float = ( (X - ZoomOriginX ) * _viewscale)
Local drawy:Float = ((Y- ZoomOriginY ) * _viewscale)
DrawRect(drawX-HalfSize,drawY-HalfSize,size+1,size+1)
End Method
End Type
Global GW:Int = ClientWidth(Desktop())
Global GH:Int = ClientHeight(Desktop())
Global GHW:Float = GW/2.0
Global GHH:Float = GH/2.0
Global Dragging:Byte = 0
Global MSX:Int
Global MSY:Int
Global MPosX:Int
Global MPosY:Int
Global DoubleClickTime:Int
Global DoubleClickDelay:Int = 300
Global Viewscale:Float = 1.0
Global WorldViewOriginX:Float = GHW
Global WorldViewOriginY:Float = GHH
Global ZoomTargetX:Float = GHW
Global ZoomTargetY:Float = GHH
Global ZoomTargetScale:Float = 1
Global ZoomFactor:Float = 1.25
Global ZoomMAX:Float = 30.0
Global ZoomMin:Float = 0.50
'Global RootDir:String = CurrentDir()
AddHook EmitEventHook, EventHook
SetGraphicsDriver(GLMax2DDriver() )
?Debug
Global GraphicsContext:TGraphics = CreateGraphics(GW , GH , 0 , 60 , Graphics_BACKBUFFER)
?Not Debug
Global GraphicsContext:TGraphics = CreateGraphics(GW , GH , 32 , 60 , Graphics_BACKBUFFER)
?
SetGraphics(GraphicsContext)
HideMouse()
For Local i:Int = 0 To 3000
Local temp:obj = New obj
Next
Local ms:Int,time:Int,dt:Float
While Not KeyHit(KEY_ESCAPE)
'ms = MilliSecs()
'dt = ms - time
'time = ms
'Print 1000.0/dt
Cls
SetScale(1 , 1)
SetOrigin(GHW,GHH)
SetColor(255 , 255 , 0)
SetLineWidth(5)
Local tempx:Float = (-WorldViewOriginX * viewscale)
Local tempy:Float = (-WorldViewOriginY * viewscale )
Local tempx2:Float = tempx+(GW*viewscale)
Local tempy2:Float = tempy+(GH*viewscale)
DrawLine(tempx , tempy , tempx2 , tempy)
DrawLine(tempx2, tempy , tempx2 , tempy2)
DrawLine(Tempx2 , tempy2 , tempx , tempy2)
DrawLine(tempx , tempy2 , tempx , tempy)
SetLineWidth(1)
SetColor(255 , 255 , 255)
SetViewScale()
For Local t:obj = EachIn Obj.List
t.draw(WorldViewOriginX, WorldViewOriginY, viewscale)
Next
SetScale(1 , 1)
SetOrigin(0 , 0)
SetBlend(LightBlend)
SetAlpha(0.4)
SetColor(255 , 155 , 0)
SetLineWidth(2)
DrawLine(MPosX- 15 , MPosY, MPosX+ 15 , MPosY)
DrawLine(MPosX, MPosY- 15 , MPosX, MPosY+ 15 )
SetLineWidth(1)
SetBlend(SolidBlend)
SetColor(255 , 255 , 255)
DrawText("SCALE: " + viewscale , 50 , 50)
Flip 0
Wend
Function SetViewScale()
WorldViewOriginX = ZoomTargetX
WorldViewOriginY = ZoomTargetY
ViewScale = ZoomTargetScale
SetScale(Viewscale , Viewscale)
End Function
Function ZoomIn(MouseScreenX:Int , MouseScreenY:Int)
If Not (ZoomTargetScale >= ZoomMax)
Local mx:Float = (MouseScreenX - GHW) /ZoomTargetScale
Local my:Float = (MouseScreenY - GHH) /ZoomTargetScale
Local z:Float = 1.0 - (1.0/ZoomFactor)
ZoomTargetX = (mx)*(z) + WorldViewOriginX
ZoomTargetY = (my)*(z) + WorldViewOriginY
If ZoomTargetX > GW
ZoomTargetX = GW
Else If ZoomTargetX < 0
ZoomTargetX = 0
EndIf
If ZoomTargetY > GH
ZoomTargetY = GH
Else If ZoomTargetY < 0
ZoomTargetY = 0
EndIf
ZoomTargetScale:* ZoomFactor
If ZoomTargetScale > ZoomMax Then ZoomTargetScale = ZoomMax
EndIf
End Function
Function ZoomOut(MouseScreenX:Int , MouseScreenY:Int)
If Not (ZoomTargetScale =< ZoomMin)
Local mx:Float = (MouseScreenX - GHW) / ZoomTargetScale
Local my:Float = (MouseScreenY - GHH) / ZoomTargetScale
Local z:Float = 1.0 - ZoomFactor
ZoomTargetX = mx*(z)+ WorldViewOriginX
ZoomTargetY = my*(z)+ WorldViewOriginY
ZoomTargetScale:/ ZoomFactor
If ZoomTargetScale < ZoomMin Then ZoomTargetScale = ZoomMin
EndIf
End Function
Function DoubleClick(button:Int , MouseScreenX:Int , MouseScreenY:Int)
ZoomTargetX = WorldViewOriginX + (MouseScreenX - GHW) / ZoomTargetScale
ZoomTargetY = WorldViewOriginY + (MouseScreenY - GHH) / ZoomTargetScale
ZoomTargetScale = ZoomMax
End Function
Function Drag(MouseScreenX:Int , MouseScreenY:Int)
Local dx:Float = (MouseScreenX - MSX) / viewscale
Local dy:Float = (MouseScreenY - MSY) / viewscale
WorldViewOriginX:- dx
WorldViewOriginY:- dy
ZoomTargetX:- dx
ZoomTargetY:- dy
MSX = MouseScreenX
MSY = MouseScreenY
If WorldViewOriginX < 0
WorldViewOriginX = 0
ZoomTargetX = 0
Else If WorldViewOriginX > GW
WorldViewOriginX = GW
ZoomTargetX = GW
EndIf
If WorldViewOriginY < 0
WorldViewOriginY = 0
ZoomTargetY = 0
Else If WorldViewOriginY > GH
WorldViewOriginY = GH
ZoomTargetY = GH
EndIf
End Function
Function EventHook:Object(ID:Int , Data:Object , Context:Object)
Local Event:TEvent = TEvent(data)
If Event = Null Then Return event
Select event.id
Case EVENT_MOUSEWHEEL
If Event.Data > 0
ZoomIn(event.x,Event.Y)
Else
ZoomOut(event.x,Event.Y)
EndIf
Case EVENT_APPTERMINATE
End
Case EVENT_KEYDOWN
Select Event.Data
Case KEY_ESCAPE End
End Select
Case EVENT_MOUSEDOWN
Local ms:Int = MilliSecs()
If ms - DoubleClickTime =< DoubleClickDelay
DoubleClick(event.Data , event.X , event.Y)
Return Null
Else DoubleClickTime = ms
EndIf
Select Event.data
Case 1
Dragging = 1
MSX = Event.X
MSY = Event.Y
Case 3
Dragging = 1
MSX = Event.X
MSY = Event.Y
End Select
Case EVENT_MOUSEUP
Select Event.data
Case 1,3
Dragging = 0
End Select
Case EVENT_MOUSEMOVE
MPosx = Event.x
MPosY = Event.y
If Dragging
Drag(event.x,event.y)
EndIf
End Select
End Function |
Comments
| ||
Simplified zoom function. I'm aware of how poorly documented this is - if you have any questions, please email usnavyfish at gmail dot com.Method Zoom(MouseScreenX:Double , MouseScreenY:Double, amount:Double = 0) ZoomInProgress = True If ZoomTargetScale < ZoomMax And ZoomTargetScale >= ZoomMin Local mx:Double = (MouseScreenX - GHW) /ZoomTargetScale Local my:Double = (MouseScreenY - GHH) / ZoomTargetScale Local NewZoom:Double, ZF:Double, Z:Double ZF = ZoomFactor * Abs(amount) If amount > 0 NewZoom = ZoomtargetScale * ZF If NewZoom > ZoomMax Then ZF = 1 z = 1.0 - (1.0/ZF) ZoomTargetScale:* ZF Else NewZoom = ZoomTargetScale / ZF If NewZoom < ZoomMin Then ZF = 1 z = 1.0 - ZF ZoomTargetScale:/ ZF EndIf ZoomTargetX:+ (mx)*(z) ZoomTargetY:+ (my)*(z) If ZoomTargetX > GW ZoomTargetX = GW Else If ZoomTargetX < 0 ZoomTargetX = 0 EndIf If ZoomTargetY > GH ZoomTargetY = GH Else If ZoomTargetY < 0 ZoomTargetY = 0 EndIf EndIf ZoomInProgress = False End Method |
Code Archives Forum