dphfox / Fusion

A modern reactive UI library, built specifically for Roblox and Luau.
https://elttob.uk/Fusion/
MIT License
530 stars 91 forks source link

Decouple TweenInfos from Tweens #344

Closed znotfireman closed 3 weeks ago

znotfireman commented 3 weeks ago

As of v0.3 Tween values use TweenInfos. If Fusion were to be platform agnostic it should be decoupled from the TweenInfo construct. I propose Fusion should offer its own TweenInfo construct, which perhaps could take in a dictionary of values:

local TweenInfo = Fusion.TweenInfo {
   EasingStyle = Fusion.EasingStyle.Quart,
   EasingDirection = Fusion.EasingDirection.Out,
   Duration = 0.3, DelayTime = 0, Reverses = false, RepeatCount = 0
}

local tween = scope:Tween(
   scope:Computed(function(use)
      -- ... stuff ...
   end), TweenInfo
)

Accounting for https://github.com/dphfox/Fusion/issues/87, Fusion could provide functions instead of Enums. As a nice bonus, allowing custom functions enables users to plug their own easing styles into Fusion while Fusion can provide additional EasingStyles:

local TweenInfo = Fusion.TweenInfo {
   -- ... stuff ...
   EasingStyle = function(ratio: number): number
      -- ... stuff ...
   end
}

Should state objects could be supported?

-- inside tween info
local tweeninfo = Fusion.TweenInfo {
   Duration = scope:Computed(function(use)
      -- ... stuff ...
   end)
}

-- inside tween, tween already supports TweenInfo state objects
local tween = scope:Tween(
   scope:Computed(function(use)
      -- ... stuff ...
   end),
   scope:Computed(function(use)
      return use(reducedMotion) and INSTANT_TWEEN_INFO or Fusion.TweenInfo {
         -- ... stuff ...
      }
   end)
)

Roblox TweenInfos should still be supported, but with a custom construct Fusion could provide custom easing styles ie. Bezier curves, state objects for individual properties of a TweenInfo, and perhaps even new properties that may be useful ie. what RunService event to run on.

dphfox commented 3 weeks ago

This should be consolidated with #87 since that's where this API design is concerned. I suspect we will probably just go for a simple dictionary in the end though.