Thanks a lot for this collection of beautiful graphics effects! I really enjoyed all of them!
The rotating gears are one of my favorites, so I decided to give it a personal touch...
Code: Select all
EnableExplicit
InitSprite()
Enumeration
	#MainWindow
EndEnumeration
#GEAR_TEETH_SCALE = 6           ; Scale factor for converting teeth count to radius
#GEAR_HUB_RATIO = 4				; Ratio of gear radius to hub radius
#TOOTH_AMPLITUDE = 15			; Amplitude of gear teeth
#GEAR_PADDING = 12				; Additional padding around gear
#ANGLE_INCREMENT = 0.015		; Angle increment for tooth generation
Structure Gear
	sprite.i                     ; Gear sprite
	positionX.l					 ; X position on canvas
	positionY.l					 ; Y position on canvas
	radius.l					 ; Radius including teeth
	rotationSpeed.f				 ; Speed of rotation (proportional to the teeth count)
EndStructure
Global NewList Gears.Gear()
Macro LimitToothDepth(angle)
	Max(Min(Sin(angle), 0.7), -0.6)
EndMacro
Procedure.f Max(a.f, b.f) : If a > b : ProcedureReturn a : EndIf : ProcedureReturn b : EndProcedure
Procedure.f Min(a.f, b.f) : If a < b : ProcedureReturn a : EndIf : ProcedureReturn b : EndProcedure
Procedure CreateGear(centerX.l, centerY.l, teethCount.l, index.l, direction.l, gearColor.l)
	Protected *gear.Gear = AddElement(Gears())
	If *gear
		Protected.f angleStep, gearRadius, hubRadius, phase, radius
		Protected.f x, y
		
		gearRadius = (teethCount * #GEAR_TEETH_SCALE) * DesktopResolutionX()
		hubRadius = gearRadius * 0.5
		
		centerX * DesktopResolutionX()
		centerY * DesktopResolutionY()
		
		*gear\positionX = centerX - gearRadius
		*gear\positionY = centerY - gearRadius
		*gear\rotationSpeed = direction / teethCount
		*gear\radius = gearRadius + #GEAR_PADDING
		
		centerX = gearRadius + #GEAR_PADDING
		centerY = gearRadius + #GEAR_PADDING
		Protected image = CreateImage(#PB_Any, *gear\radius * 2, *gear\radius * 2, 32, #PB_Image_Transparent)
		
		If StartVectorDrawing(ImageVectorOutput(image))
			angleStep = 0
			Repeat
				radius = gearRadius + #TOOTH_AMPLITUDE * LimitToothDepth(teethCount * angleStep)
				x = centerX + radius * Cos(angleStep)
				y = centerY + (radius * Sin(angleStep) * direction)
				If angleStep = 0 : MovePathCursor(x, y) : EndIf
				AddPathLine(x, y)
				angleStep + #ANGLE_INCREMENT
			Until angleStep >= (2 * #PI) + #ANGLE_INCREMENT
			
			AddPathCircle(centerX, centerY, hubRadius)
			AddPathCircle(centerX, centerY, hubRadius * 0.75)
			VectorSourceColor(gearColor)
			FillPath(#PB_Path_Preserve)
			VectorSourceColor(RGBA(0, 0, 0, 64))
			StrokePath(6, #PB_Path_Preserve)
			VectorSourceColor(RGBA(0, 0, 0, 255))
			StrokePath(3)
			
			StopVectorDrawing()
			
			*gear\sprite = CreateSprite(#PB_Any, ImageWidth(image), ImageHeight(image), #PB_Sprite_AlphaBlending)
			If StartDrawing(SpriteOutput(*gear\sprite))
				DrawAlphaImage(ImageID(image), 0, 0)
				StopDrawing()
			EndIf
			FreeImage(image)
		EndIf
	EndIf
EndProcedure
DisableExplicit
InitSprite()
InitKeyboard()
screenWidth = 800
screenHeight = 600
windowFlags = #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered
If OpenWindow(#MainWindow, 0, 0, screenWidth, screenHeight, "Gear Animation", windowFlags)
	If OpenWindowedScreen(WindowID(#MainWindow), 0, 0, DesktopScaledX(screenWidth), DesktopScaledY(screenHeight))
		CreateGear(485, 220, 30, 1, -1, RGBA(205, 127,  50, 255))
		CreateGear(215, 240, 15, 2,  1, RGBA(176, 196, 222, 255))
		CreateGear(234, 372,  7, 4, -1, RGBA(184, 115,  51, 255))
		CreateGear(83,   74, 20, 6, -1, RGBA(192, 192, 192, 255))
		CreateGear(746, 414, 24, 3,  1, RGBA(205, 127,  50, 255))
		CreateGear(-10, 518, 40, 5,  1, RGBA(170, 169, 173, 255))
		CreateGear(705,  93, 12, 7,  1, RGBA(230, 232, 250, 255))
		
		Repeat
			Repeat
				event = WindowEvent()
				If event = #PB_Event_CloseWindow
					Break 2
				EndIf
			Until Not event
			
			currentAngle = ElapsedMilliseconds()
			
			ClearScreen(RGB(128, 128, 128))
			ForEach Gears()
				With Gears()
					RotateSprite(\sprite, currentAngle * \rotationSpeed, #PB_Absolute)
					DisplayTransparentSprite(\sprite, \positionX + 15, \positionY + 15, 64, 0) ; shadow
					DisplayTransparentSprite(\sprite, \positionX, \positionY)
				EndWith
			Next
			FlipBuffers()
		ForEver
	EndIf
EndIf