function CameraModule.animateToCanvasAsync(E,b)E.camera.CameraType=Enum.CameraType.Scriptable E.initialCFrame=E.camera.CFrame E.surfaceGui=b local p=E.surfaceGui.Adornee local l=E.surfaceGui.Face local m=p.Position local M=p.CFrame:VectorToWorldSpace(Vector3.FromNormalId(l))local function D(b,E)local p=math.rad(b/2)local l=(E+CANVAS_OFFSET_PADDING)/2 return l/math.tan(p)end local z=E.camera.ViewportSize.X/E.camera.ViewportSize.Y local F=D(E.camera.FieldOfView,b.adornee.Size.Y)local k=D(E.camera.FieldOfView*z,b.adornee.Size.X)local i=math.max(k,F)i=math.clamp(i,MIN_STUDS_OFFSET,MAX_STUDS_OFFSET)M*=i local C=E:_getUpVectorByFace(p.CFrame,l)local B=CFrame.lookAt(m+M,m,C)if l==Enum.NormalId.Top then B*=CFrame.Angles(0,0,math.pi)end E:_tweenCamera(B)end
--[[
	(Yields) Animates the camera after activating the surface art prompt.

	Target position: Center of the SurfaceGui that we want to animate to (in studs)

	Parameters:
	- surfaceGui (SurfaceGui): mounted SurfaceGui instance
]]
function CameraModule:animateToCanvasAsync(surfaceGui)
	self.camera.CameraType = Enum.CameraType.Scriptable

	-- Store this so we can reset to this position later on
	self.initialCFrame = self.camera.CFrame
	self.surfaceGui = surfaceGui

	local adornee = self.surfaceGui.Adornee
	local face = self.surfaceGui.Face
	local canvasPosition = adornee.Position

	-- Look into the middle of SurfaceGui from a distance
	local offset = adornee.CFrame:VectorToWorldSpace(Vector3.FromNormalId(face))

	-- Compute offset distance dynamically to make sure entire canvas is in field of view
	local function getDistanceToCanvas(fov, size)
		local angle = math.rad(fov / 2)
		local opp = (size + CANVAS_OFFSET_PADDING) / 2

		return opp / math.tan(angle)
	end

	local aspectRatio = self.camera.ViewportSize.X / self.camera.ViewportSize.Y
	local vertical = getDistanceToCanvas(self.camera.FieldOfView, surfaceGui.adornee.Size.Y)
	local horizontal = getDistanceToCanvas(self.camera.FieldOfView * aspectRatio, surfaceGui.adornee.Size.X)

	local distance = math.max(horizontal, vertical)
	distance = math.clamp(distance, MIN_STUDS_OFFSET, MAX_STUDS_OFFSET)
	offset *= distance

	local upVector = self:_getUpVectorByFace(adornee.CFrame, face)
	local target = CFrame.lookAt(canvasPosition + offset, canvasPosition, upVector)

	-- Top view has a weird bug that turns things upside down
	if face == Enum.NormalId.Top then
		target *= CFrame.Angles(0, 0, math.pi)
	end

	self:_tweenCamera(target)
end
