How to make a Smooth Drawing Canvas?

I’m trying to let a player draw something on a canvas, but a while loop is too slow as well as mouse.Move and RenderStepped/Heartbeat.

How would I get the points to spawn faster and make it correct, or draw a line from point a to point b to make a line for each and every point? Thanks!

My code:

game:GetService("RunService").RenderStepped:Connect(function()
	
	if canvas.Visible == true and cursor.Visible == true then
		
		local x = math.abs(mouse.X - canvas.AbsolutePosition.X)
		local y = math.abs(mouse.Y - canvas.AbsolutePosition.Y)
		
		cursor.Position = UDim2.new(x/canvas.AbsoluteSize.X, 0, y/canvas.AbsoluteSize.Y, 0)
		cursor.Size = UDim2.new(0, currentSize, 0, currentSize)
	
		if mouseDown then
				
			local paint = script.Paint:Clone()
				
			paint.Position = UDim2.new(x/canvas.AbsoluteSize.X, 0, y/canvas.AbsoluteSize.Y, 0)
			paint.Size = UDim2.new(0, currentSize, 0, currentSize)
				
			paint.ImageColor3 = erasing and Color3.fromRGB(255, 255, 255) or currentColor
				
			paint.Parent = paintContainer
		end
	end
end)

This is how it looks like:
image

unfortunately having lots of image labels can start to get slow if you have to many

the way I did this was to use a ViewportFrame | Roblox Creator Documentation

and use parts as pixels



I also did greedy meshing to reduce part count so as you can see the image on the left only used 2 parts but this was done only after you saved the image not while you was drawing

here is a video showing how I greedy meshed the pixels


and this video will show you how to position the camera of the ViewportFrame so the pixels fit perfectly


but if we look at how Free Draw 2 - Roblox works what they do is use Beam | Roblox Creator Documentation but Beams dont work in ViewportFrames so it would only work if they was drawing in the workspace

5 Likes

Alright, thanks :smiley: (Character limit)

But I have a question - would I have to make the canvas myself and then use the greedy meshing to put the canvas art on a part?

I don’t quite understand the minimap part.

So you have a viewportframe

You can put this viewportframe anywhere you like on a part or in your normal GUI

Then you create parts and each part is 1 pixel and you colour each part depending on what colour you want that pixel to be

Then you can use greedy mesh to merge colours that are the same to reduce the amount of parts you have in the viewportframe

Your viewportframe has a camera and the camera needs to be zoomed out from the parts so you can see all the parts in the viewportframe

If you want to zoom the camera out so the pixels fit perfectly the formula for calculating the amount you need to zoom out is in the mini map video

What if you found a way to use part unions in order to smooth out edges

One of the first steps might be creating four different edges, concave 90 degree angle, convex 90 degree angle, concave inverse 90 degree angle, and convex inverse 90 degree angle.

Oh okay, thanks for your help :smile: