Re: vector drawing display list
Posted: Sun Oct 12, 2025 1:37 am
I'm currently working on Animated Vector Graphics Scene graph
lots to do and refactor but it's slowly coming together. There's still a bug on object reverse direction where it flashes the object on the opposite side of the animation.
The example
The code
https://Atomicwebserver.com/AvgSceneGraph.pbi
lots to do and refactor but it's slowly coming together. There's still a bug on object reverse direction where it flashes the object on the opposite side of the animation.
The example
Code: Select all
;callbacks
Procedure OnBoxMouseEnter(*obj.AVGObject, x.d, y.d)
Debug "Mouse entered : " + *obj\name + " " + Str(*obj\avg\dl()\item\id)
*obj\params\pauseAnimation = 1
EndProcedure
Procedure OnBoxMouseLeave(*obj.AVGObject, x.d, y.d)
Debug "Mouse left : " + *obj\name
*obj\params\pauseAnimation = 0
EndProcedure
Procedure OnBoxClick(*obj.AVGObject, x.d, y.d, button)
Debug " clicked: " + *obj\name
*obj\params\text = "Clicked!"
EndProcedure
Procedure OnTextUpdate(*obj.AVGObject, deltaTime.d)
;custom animation logic
EndProcedure
;Create scene
Global *scene.AVGScene = CreateAVGScene(800, 600)
LoadFont(0,"Arial",24,#PB_Font_Italic | #PB_Font_Bold )
;Box with position animation (bouncing with easing)
Global box1 = AVGCreateObject(*scene, "BouncingBox")
AVGSetOnMouseEnter(*scene, box1, @OnBoxMouseEnter())
AVGSetOnMouseLeave(*scene, box1, @OnBoxMouseLeave())
AVGSetOnMouseClick(*scene, box1, @OnBoxClick())
AVGAddPathBox(*scene, box1, 0, 0, 100, 100)
AVGVectorSourceColor(*scene, box1, RGBA(255, 128, 0, 255), RGBA(255, 255, 0, 255))
AVGFillPath(*scene, box1)
AVGVectorFont(*scene,box1,FontID(0),14)
AVGAddPathText(*scene,box1,"Bouncy box",10,10)
AVGVectorSourceColor(*scene,box1,RGBA(0, 255, 0, 255),0)
AVGFillPath(*scene, box1)
;Animate position with bounce easing, loop and reverse
AVGAnimatePosition(*scene, box1, 100, 100, 700, 100, 2.0, #Ease_OutBounce, #True, #True)
;Circle with scale animation
Global circle1 = AVGCreateObject(*scene, "PulsingCircle")
AVGSetOnMouseEnter(*scene, circle1, @OnBoxMouseEnter())
AVGSetOnMouseLeave(*scene, circle1, @OnBoxMouseLeave())
AVGSetObjectPosition(*scene, circle1, 400, 300)
AVGAddPathCircle(*scene, circle1, 0, 0, 50)
AVGVectorSourceColor(*scene, circle1, RGBA(0, 128, 255, 255),0)
AVGFillPath(*scene, circle1)
AVGAddPathCircle(*scene, circle1, 0, 0, 20)
AVGVectorSourceColor(*scene, circle1, RGBA(128, 128, 255, 255),RGBA(255, 255, 0, 255))
AVGFillPath(*scene, circle1,#PB_Path_Default)
;Animate scale with elastic easing, loop
AVGAnimateScale(*scene, circle1, 1.0, 1.0, 1.5, 1.5, 1.5, #Ease_InOutElastic, #True, #False)
;Rotating square with alpha fade
Global square1 = AVGCreateObject(*scene, "RotatingSquare")
AVGSetObjectPosition(*scene, square1, 600, 400)
AVGAddPathBox(*scene, square1, -40, -40, 80, 80)
AVGVectorSourceColor(*scene, square1, RGBA(255, 0, 128, 255))
AVGFillPath(*scene, square1)
; Animate rotation with linear easing, loop
AVGAnimateRotation(*scene, square1, 0, 360, 3.0, #Ease_Linear, #True, #False)
; Animate alpha with sine easing, loop and reverse
AVGAnimateAlpha(*scene, square1, 255, 50, 1.5, #Ease_InOutSine, #False, #True)
;Text with animation and callback
Global text1 = AVGCreateObject(*scene, "AnimatedText")
AVGSetObjectPosition(*scene, text1, 300, 500)
AVGSetOnUpdate(*scene, text1, @OnTextUpdate())
AVGVectorFont(*scene,text1,FontID(0),24)
AVGAddPathText(*scene, text1, "Eased Animation!", 0, 0)
AVGVectorSourceColor(*scene, text1, RGBA(0,255,0, 255))
AVGFillPath(*scene, text1)
;Animate position with cubic easing
AVGAnimatePosition(*scene, text1, 100, 500, 700, 500, 3.0, #Ease_InOutCubic, #False, #True)
;Child object
Global parent = AVGCreateObject(*scene, "Parent")
AVGSetObjectPosition(*scene, parent, 400, 200)
AVGAddPathBox(*scene, parent, -50, -50, 100, 100)
AVGVectorSourceColor(*scene, parent, RGBA(128, 255, 128, 255))
AVGStrokePath(*scene, parent, 2)
; Animate parent rotation
AVGAnimateRotation(*scene, parent, 0, 360, 4.0, #Ease_Linear, #False, #True)
; Add child that orbits around parent
Global child = AVGCreateObject(*scene, "Child", parent)
AVGSetObjectPosition(*scene, child,-200,-200) ; Offset from parent
AVGAddPathCircle(*scene, child, 0, 0, 15)
AVGVectorSourceColor(*scene, child, RGBA(255, 0, 0, 255))
AVGFillPath(*scene, child)
;Child has its own scale animation
AVGAnimateScale(*scene, child, 1.0, 1.0, 2.0, 2.0, 1.0, #Ease_InOutQuad, #True, #False)
OpenWindow(0,0,0,800,600,"test txt",#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget )
AddWindowTimer(0,1,15)
CanvasGadget(0,0,0,800,600)
If StartVectorDrawing(CanvasVectorOutput(0))
AVGRenderScene(*scene)
StopVectorDrawing()
EndIf
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_SizeWindow
ResizeGadget(0,0,0,DesktopScaledX(WindowWidth(0)),DesktopScaledY(WindowHeight(0)))
*scene\displayWidth = DesktopScaledX(WindowWidth(0))
*scene\displayHeight = DesktopScaledY(WindowHeight(0))
StartVectorDrawing(CanvasVectorOutput(0))
AVGRenderScene(*scene)
StopVectorDrawing()
Case #PB_Event_Gadget
If EventType() = #PB_EventType_MouseWheel
x = DesktopScaledX(WindowMouseX(0))
y = DesktopScaledX(WindowMouseY(0))
;set scene zoom scale factor
dir = GetGadgetAttribute(0,#PB_Canvas_WheelDelta)
If dir < 1
*scene\sfx / 1.2
*scene\sfy / 1.2
Else
*scene\sfx * 1.2
*scene\sfy * 1.2
EndIf
EndIf
Case #PB_Event_Timer
;Set scene mouse position
x = DesktopScaledX(WindowMouseX(0))
y = DesktopScaledX(WindowMouseY(0))
*scene\mouseX = x
*scene\mouseY = y
If StartVectorDrawing(CanvasVectorOutput(0))
;render scene
AVGRenderScene(*scene)
StopVectorDrawing()
EndIf
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
https://Atomicwebserver.com/AvgSceneGraph.pbi