Custom camera snaps when I stop moving

i’m working on a first-person game. for the most part, it’s going swimmingly. that was, until just now. when i added sine waves to make it feel like you were actually walking (with purpose), the camera snaps when i stop walking. however, when i try to use linear interpolation, it made the camera bug out completely. i’m stumped. how can i make it smoothly reset to the original cframe after the character stops walking?

the goods:

a video that describes my issue:

the source code:

-- services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

-- wait for character to fully load in; prevents output being flooded with errors
local client = Players.LocalPlayer
repeat task.wait() until client.Character

local character = client.Character
local head = character:WaitForChild("Head")
local root_part = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")

local current_camera = workspace.CurrentCamera
local camera_rotation = Vector2.new(0, 0)
local height_offset = head.Position.Y - root_part.Position.Y
local cam_connection, root_connection

local attachment = Instance.new("Attachment")
attachment.Name = "spectate_point"
attachment.Parent = root_part

local function toggle_player(enabled)
	if enabled then
		for _, child in ipairs(character:GetDescendants()) do
			if child:IsA("BasePart") and child.Name ~= "HumanoidRootPart" then
				child.LocalTransparencyModifier = 1
				if child:IsA("Decal") then
					child.LocalTransparencyModifier = 1
				end
			end
		end
	else
		for _, child in ipairs(character:GetDescendants()) do
			if child:IsA("BasePart") and child.Name ~= "HumanoidRootPart" then
				child.LocalTransparencyModifier = 0
				if child:IsA("Decal") then
					child.LocalTransparencyModifier = 0
				end
			end
		end
	end
end

local function update_camera()
	local player_camera = root_part:FindFirstChild("spectate_point")
	if not player_camera then
		return
	end

	if humanoid.Health > 0 then
		-- no "up down, up down", sorry cory
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
		camera_rotation += UserInputService:GetMouseDelta() * math.rad(UserInputService.MouseDeltaSensitivity / 6)
		camera_rotation = Vector2.new(camera_rotation.X, math.clamp(camera_rotation.Y, math.rad(-0), math.rad(0)))

		if humanoid.MoveDirection.Magnitude ~= 0 then
			local current_time = tick()
			local frequency = 1.8 -- controls the speed
			local amplitude = 0.56 -- controls the height
			local y_offset = amplitude * math.sin(2 * math.pi * frequency * current_time)
			
			local camera_pos = Vector3.new(0, height_offset + y_offset, 0) + root_part.Position
			player_camera.WorldCFrame = CFrame.new(camera_pos) * CFrame.Angles(0, -camera_rotation.X, 0) * CFrame.Angles(camera_rotation.Y, 0, 0)
		else
			-- reset camera position when not moving
			player_camera.WorldCFrame = CFrame.new(Vector3.new(0, height_offset, 0) + root_part.Position) * CFrame.Angles(0, -camera_rotation.X, 0) * CFrame.Angles(camera_rotation.Y, 0, 0)
		end
	end

	toggle_player(true)
	current_camera.CFrame = player_camera.WorldCFrame
end

function setup_camera(enabled)
	if enabled then
		cam_connection = RunService.PreRender:Connect(update_camera)
		root_connection = RunService.PostSimulation:Connect(function()
			if humanoid.Health > 0 then
				local camera_look_vector = root_part.Position + current_camera.CFrame.LookVector
				root_part.CFrame = CFrame.new(root_part.Position, Vector3.new(camera_look_vector.X, root_part.Position.Y, camera_look_vector.Z))
			end
			humanoid.AutoRotate = false
		end)
	else
		if cam_connection and root_connection then
			toggle_player(false)
			humanoid.AutoRotate = true
			
			UserInputService.MouseBehavior = Enum.MouseBehavior.Default
			current_camera.CameraType = Enum.CameraType.Custom
			cam_connection:Disconnect()
			root_connection:Disconnect()
		end
	end
end

setup_camera(true)