--[=[
	@class Shake
	Create realistic shake effects, such as camera or object shakes.

	Creating a shake is very simple with this module. For every shake,
	simply create a shake instance by calling `Shake.new()`. From
	there, configure the shake however desired. Once configured,
	call `shake:Start()` and then bind a function to it with either
	`shake:OnSignal(...)` or `shake:BindToRenderStep(...)`.
	
	The shake will output its values to the connected function, and then
	automatically stop and clean up its connections once completed.

	Shake instances can be reused indefinitely. However, only one shake
	operation per instance can be running. If more than one is needed
	of the same configuration, simply call `shake:Clone()` to duplicate
	it.

	Example of a simple camera shake:
	```lua
	local priority = Enum.RenderPriority.Last.Value

	local shake = Shake.new()
	shake.FadeInTime = 0
	shake.Frequency = 0.1
	shake.Amplitude = 5
	shake.RotationInfluence = Vector3.new(0.1, 0.1, 0.1)

	shake:Start()
	shake:BindToRenderStep(Shake.NextRenderName(), priority, function(pos, rot, isDone)
		camera.CFrame *= CFrame.new(pos) * CFrame.Angles(rot.X, rot.Y, rot.Z)
	end)
	```

	Shakes will automatically stop once the shake has been completed. Shakes can
	also be used continuously if the `Sustain` property is set to `true`.

	Here are some more helpful configuration examples:

	```lua
	local shake = Shake.new()

	-- The magnitude of the shake. Larger numbers means larger shakes.
	shake.Amplitude = 5

	-- The speed of the shake. Smaller frequencies mean faster shakes.
	shake.Frequency = 0.1

	 -- Fade-in time before max amplitude shake. Set to 0 for immediate shake.
	shake.FadeInTime = 0

	-- Fade-out time. Set to 0 for immediate cutoff.
	shake.FadeOutTime = 0

	-- How long the shake sustains full amplitude before fading out
	shake.SustainTime = 1

	-- Set to true to never end the shake. Call shake:StopSustain() to start the fade-out.
	shake.Sustain = true

	-- Multiplies against the shake vector to control the final amplitude of the position.
	-- Can be seen internally as: position = shakeVector * fadeInOut * positionInfluence
	shake.PositionInfluence = Vector3.new(1, 1, 1)

	-- Multiplies against the shake vector to control the final amplitude of the rotation.
	-- Can be seen internally as: position = shakeVector * fadeInOut * rotationInfluence
	shake.RotationInfluence = Vector3.new(0.1, 0.1, 0.1)

	```
]=]

local Shake = {}
Shake.__index = Shake
