How do you calculate the bounding box for UI elements?

I’m making a drawing script, and I’m using CanvasGroups to contain strokes with some transparency. This is the only way to get this transparency effect.

However, the CanvasGroup’s size is the screen size, which will use more and more memory per stroke the user makes. That means, eventually, the CanvasGroup will be all white because there is not enough memory to hold the new textures.

To fix this, or at least increase the amount of strokes before this happens, I wanted to shrink the size to perfectly fit the stroke. No idea what the math behind that is, though… I looked all over the devforum and only found things for the bounding box of models and parts!

Does anybody here know how to help with this?

3 Likes

Assuming each pixel is an individual frame, you can get the minimum and maximum positions of the x and y axis by iterating through all the frames and checking the AbsolutePosition of each frame:

The size of the box would be as such:

local size = UDim2.fromOffset(
    maxX - minX,
    maxY - minY
)
1 Like

The drawings are made of circles and lines to connect the dots, so it’s not like that.

Video: https://gyazo.com/7ddc560c9db168e2b800fce96df5624a.mp4

I could sort of use that method for the circles since they have a radius, but the rotated lines are going to make that math harder.

I’ll try to make something with this.

Circles will always dictate where the boundaries are. Lines connect the circles, so they will never dictate where the bounds are.

Assuming each circle is an image instance, you’re going to need to retrieve the boundaries of the image:

local imageMaxX = Circle.AbsolutePosition.X + Circle.AbsoluteSize.X
local imageMinX = Circle.AbsolutePosition.X
local imageMaxY = Circle.AbsolutePosition.Y + Circle.AbsoluteSize.Y
local imageMinY = Circle.AbsolutePosition.Y

You are going to compare these values corresponding to each axis to figure out the boundaries.

1 Like

I’m pretty close to something that’s working, I’ll have to improve my math more I guess.

It works now!

Video: https://gyazo.com/17c06a7e182ce966ee9326918f92e5dc.mp4

Here’s the math if anybody wants it:

-- absat: The mouse position to draw at
local offset = Pen.Width / 2
if not Pen._Min then
	Pen._Min = absat - Vector2.new(offset, offset)
else
	Pen._Min = Vector2.new(math.min(Pen._Min.X, absat.X - offset), math.min(Pen._Min.Y, absat.Y - offset))
end

if not Pen._Max then
	Pen._Max = absat + Vector2.new(offset, offset)
else
	Pen._Max = Vector2.new(math.max(Pen._Max.X, absat.X + offset), math.max(Pen._Max.Y, absat.Y + offset))
end
-- Pen.Drawing: A Frame containing dots and lines, or nil
-- DBound: The green frame shown in pictures, called 'DebugBound'
function Pen:_DrawBounds()
	if Pen.Drawing and Pen.Drawing:FindFirstChild("DebugBound") then
		Pen.Drawing.DebugBound:Destroy()
	end
	
	if Pen._Min and Pen._Max then
		local inset = (game.GuiService:GetGuiInset()).Y
		
		local bound = DBound:Clone()
		local off = Pen.Width / 2
		bound.Position = UDim2.fromOffset(Pen._Min.X + off, Pen._Min.Y + off + inset)
		bound.Size = bound.Position - UDim2.fromOffset(Pen._Max.X + off, Pen._Max.Y + off + inset)
		bound.AnchorPoint = Vector2.new(1,1)
		bound.Parent = Pen.Drawing
	end
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.