Circular Images

So I’ve been trying to figure out how to create circular images for something I’m working on for my server, and when I try to google how to create a circular image with LUA it tells me something like physics.AddBody() I’m not too sure if that is correct for Garrysmod or not but I’m trying to get avatar images and turn them into circles if anyone knows anything that would be great. I also see stuff about stencils and UV textures but I don’t know if that would be the method I’d want to use.

What? physics.AddBody isn’t even a thing IN gmod. All you need to do is the EXACT SAME THING you do to make avatar images circular, but with a DImage instead of an avatar image

I didnt think it was, i googled how to make a image circular in LUA lol. I also noticed you cant do DoClick with avatar image what about DImage?

PANEL:OnMousePressed works with DImages and AvatarImages

How would i set the avatar image on DImage?

Why do you want an avatar image on a DImage? You can set the image on a DImage, but you can’t set it to be an avatar image… that’s the whole point of the AvatarImage element

So, this is completely copied circular AvatarImage code with the AvatarImage part changed to DImage:



local function DrawCircle( x, y, radius, seg )
	local cir = {}
	table.insert( cir, { x = x, y = y } )
	for i = 0, seg do
		local a = math.rad( ( i / seg ) * -360 )
		table.insert( cir, { x = x + math.sin( a ) * radius, y = y + math.cos( a ) * radius } )
	end
	local a = math.rad( 0 )
	table.insert( cir, { x = x + math.sin( a ) * radius, y = y + math.cos( a ) * radius } )
	surface.DrawPoly( cir )
end

local PANEL = {}

function PANEL:Init()
	self.image = vgui.Create( "DImage", self )
	self.image:SetPaintedManually( true )
end

function PANEL:PerformLayout()
	self.image:SetSize( self:GetWide(), self:GetTall() )
end

function PANEL:SetImage( img )
	self.image:SetImage( img )
end

function PANEL:Paint( w, h )
	render.ClearStencil()
	render.SetStencilEnable( true )
	render.SetStencilWriteMask( 1 )
	render.SetStencilTestMask( 1 )
	render.SetStencilFailOperation( STENCILOPERATION_REPLACE )
	render.SetStencilPassOperation( STENCILOPERATION_ZERO )
	render.SetStencilZFailOperation( STENCILOPERATION_ZERO )
	render.SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_NEVER )
	render.SetStencilReferenceValue( 1 )
	draw.NoTexture()
	surface.SetDrawColor( Color( 0, 0, 0, 255 ) )
	DrawCircle( w/2, h/2, h/2, math.max(w,h)/2 )
	render.SetStencilFailOperation( STENCILOPERATION_ZERO )
	render.SetStencilPassOperation( STENCILOPERATION_REPLACE )
	render.SetStencilZFailOperation( STENCILOPERATION_ZERO )
	render.SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_EQUAL )
	render.SetStencilReferenceValue( 1 )
	self.image:PaintManual()
	render.SetStencilEnable( false )
	render.ClearStencil()
	
end
 
vgui.Register( "CircularImage", PANEL )


Theoratically all you need to do once you’ve put all that in a clientside file is this:



local img = vgui.Create( 'CircularImage' )
img:SetImage( 'SOME_IMAGE' )
-- and so on


Note it’s always going to be far easier to just make the image circular in Photoshop or something before drawing it - circles are quite intensive to calculate (especially every frame) and usually you don’t need them

So sorry if this sounds stupid but how would I give it the avatar image? The wiki only shows how to do it with the AvatarImage panel and that way you do SetPlayer()

Why don’t you use a circular avatar image instead???

Enlighten me please, because that’s what I’m trying to achieve right now.

So you ARE trying to make a circular avatar… you could’ve just said that
http://forum.facepunch.com/showthread.php?t=1522945

I did say that actually in the first post :stuck_out_tongue:

Circular images and circular avatar images are quite different, although now I check you did actually say avatar images… fair enough

Yeah haha, anyways thanks for the help its working now.

One more question, I’m trying to make the IsHovered and OnMousePressed but I cant find out how to add them for a custom panel.



Panel = vgui.Create( "DButton" )
Panel.Paint = function()

if Panel:IsHovered then
    -- colours here/box
else
   -- default colours/box
end
end

Panel.DoClick = function()
    -- Opens page, colours anything you want to do!
end


They should be already part of the panel by default (they’re both default panel functions from what I know)



local panel = vgui.Create( 'SOMEPANEL' ) -- any panel

print( panel:IsHovered() ) -- should work

function panel:OnMousePressed( key )
    print(key)
end


I haven’t tested any of this though but from memory it should work

[editline]29th August 2016[/editline]

ninja’d, but:

you forgot the (), and:

Only works for certain types of panels and I think is just a wrapper of

PANEL:OnMousePressed, which has worked for every panel I’ve ever clicked so far

My guess is that the DoClick function is implemented somewhat like this, either internally or externally:



function SOMEPANEL:DoClick()
    --blah
end

function SOMEPANEL:OnMousePressed( key )
    if key == MOUSE_LEFT then self:DoClick() end
end


IsHovered is always active when i show it even if im not hovering over it

[editline]29th August 2016[/editline]

Okay probably should’ve been more specific on what I’m doing, but im now attempting to use DIconLayout and i have no idea whats happening with it. Heres the code and a gif of what its doing. Note this is with three players on.

hastebin.com/ayoqeveyor.m

Anyone know where im going wrong about this?