diff --git a/src/Animations/Types/Spring.lua b/src/Animations/Types/Spring.lua index 3b850f2..f213ffd 100644 --- a/src/Animations/Types/Spring.lua +++ b/src/Animations/Types/Spring.lua @@ -12,6 +12,7 @@ export type SpringProperties = { speed: number?, start: any, target: any, + force: any?, } function Spring.definition(props: SpringProperties) @@ -30,7 +31,7 @@ function Spring.new(props: SpringProperties) return self end -function Spring:Play(from: any?) +function Spring:Play(from: any?, immediate: boolean?) if self.playing then self:Stop() end @@ -47,6 +48,7 @@ function Spring:Play(from: any?) end local newSpring = SpringValue.new(baseFromValue, self.props.speed, self.props.damper) + newSpring:SetImmediate(immediate) newSpring:SetGoal(baseToValue) local oldVelocity = self._oldSpring and self._oldSpring:GetVelocity() diff --git a/src/Animations/Types/Tween.lua b/src/Animations/Types/Tween.lua index e14caad..1954142 100644 --- a/src/Animations/Types/Tween.lua +++ b/src/Animations/Types/Tween.lua @@ -146,7 +146,7 @@ function Tween.new(props: TweenProperties) return self end -function Tween:Play(from: any?) +function Tween:Play(from: any?, immediate: boolean?) if self.playing then self:Stop() end @@ -182,6 +182,15 @@ function Tween:Play(from: any?) local fromValue = LinearValue.fromValue(baseFromValue) local toValue = LinearValue.fromValue(baseToValue) + if immediate then + self.listener(baseToValue) + + self.playing = false + self.player = nil + + return Promise.resolve() + end + local animation = Promise.new(function(resolve, _, onCancel) local play, cancel = playTween2(tweenInfo, function(value) local newValue = fromValue:Lerp(toValue, value):ToValue() diff --git a/src/Hooks/useAnimation.lua b/src/Hooks/useAnimation.lua index e41baeb..67f6d08 100644 --- a/src/Hooks/useAnimation.lua +++ b/src/Hooks/useAnimation.lua @@ -38,7 +38,7 @@ function Animation:SetListener(listener: (string, any) -> ()) self.listener = listener end -function Animation:Play(fromProps: AnimationProps) +function Animation:Play(fromProps: AnimationProps, immediate: boolean?) if self.playing then self:Stop() end @@ -47,7 +47,7 @@ function Animation:Play(fromProps: AnimationProps) local promises = {} for name, animatable in self.animation do - local animationPromise = animatable:Play(fromProps[name]) + local animationPromise = animatable:Play(fromProps[name], immediate) table.insert(promises, animationPromise) end diff --git a/src/Hooks/useGroupAnimation.lua b/src/Hooks/useGroupAnimation.lua index 4eb9dd5..f70a040 100644 --- a/src/Hooks/useGroupAnimation.lua +++ b/src/Hooks/useGroupAnimation.lua @@ -10,7 +10,7 @@ type StateSetters = { } export type Animation = { - Play: (DefaultProperties) -> Animation, + Play: (DefaultProperties, boolean?) -> Animation, Stop: () -> nil, } @@ -45,7 +45,7 @@ function GroupAnimationController.new(props: GroupAnimation, default: DefaultPro return self end -function GroupAnimationController:Play(newState: string) +function GroupAnimationController:Play(newState: string, immediate: boolean?) local animation = self.animations[newState] assert(animation, `No animation found for state {newState}`) @@ -56,7 +56,7 @@ function GroupAnimationController:Play(newState: string) end self.currentAnimation = animation - animation:Play(self.state) + animation:Play(self.state, immediate) end function GroupAnimationController:Stop() @@ -98,10 +98,9 @@ local function useGroupAnimation(props: GroupAnimation, default: DefaultProperti newController:UpdateSetters(newSetters) end, - play = function(newState: string) + play = function(newState: string, immediate: boolean?) assert(typeof(newState) == "string", "useGroupAnimation expects a string 'state'") - - newController:Play(newState) + newController:Play(newState, immediate) end, stop = function() diff --git a/src/Hooks/useSequenceAnimation.lua b/src/Hooks/useSequenceAnimation.lua index 459d11c..21e6bcd 100644 --- a/src/Hooks/useSequenceAnimation.lua +++ b/src/Hooks/useSequenceAnimation.lua @@ -65,7 +65,7 @@ function Sequence:SetListener(listener: (string, any) -> ()) self.listener = listener end -function Sequence:Play(fromProps: SequenceProps) +function Sequence:Play(fromProps: SequenceProps, immediate: boolean?) if self.playing then self:Stop() end @@ -75,7 +75,7 @@ function Sequence:Play(fromProps: SequenceProps) local playing = {} for _, sequenced in self.animation do - local animationPromise = Promise.delay(sequenced.timestamp):andThen(function() + local animationPromise = Promise.delay(if immediate then 0 else sequenced.timestamp):andThen(function() local allAnimatables = {} for name, animatable in sequenced do @@ -87,7 +87,7 @@ function Sequence:Play(fromProps: SequenceProps) playing[name]:cancel() end - local promise = animatable:Play(fromProps[name]) + local promise = animatable:Play(fromProps[name], immediate) playing[name] = promise table.insert(allAnimatables, promise) diff --git a/src/Hooks/useSpring.lua b/src/Hooks/useSpring.lua index b33202c..b55f81f 100644 --- a/src/Hooks/useSpring.lua +++ b/src/Hooks/useSpring.lua @@ -14,9 +14,11 @@ local function useSpring(props: Spring.SpringProperties) return { spring = spring, - start = function(subProps: Spring.SpringProperties) + start = function(subProps: Spring.SpringProperties, immediate: boolean?) assert(typeof(subProps) == "table", "useSpring expects a table of properties") + spring:SetImmediate(immediate) + if subProps.target then spring:SetGoal(subProps.target) end diff --git a/src/Hooks/useTween.lua b/src/Hooks/useTween.lua index a53eb06..7a05d42 100644 --- a/src/Hooks/useTween.lua +++ b/src/Hooks/useTween.lua @@ -14,15 +14,15 @@ local function useTween(props: Tween.TweenProperties) return { tween = tween, - start = function(subProps: Tween.TweenProperties) + start = function(subProps: Tween.TweenProperties, immediate: boolean?) assert(typeof(subProps) == "table", "useTween expects a table of properties") tween.props.info = subProps.info or tween.props.info tween.props.start = subProps.start or binding:getValue() tween.props.target = subProps.target or tween.props.target - tween.props.immediate = subProps.immediate or tween.props.immediate + tween.props.startImmediate = subProps.startImmediate or tween.props.startImmediate tween.props.delay = subProps.delay or tween.props.delay - tween:Play(subProps.start or binding:getValue()) + tween:Play(subProps.start or binding:getValue(), immediate) end, stop = function() diff --git a/src/Utility/SpringValue.lua b/src/Utility/SpringValue.lua index 98060ee..56964f0 100644 --- a/src/Utility/SpringValue.lua +++ b/src/Utility/SpringValue.lua @@ -23,6 +23,7 @@ function SpringValue.new(initial: LinearValue.LinearValueType, speed: number?, d _velocities = velocity, _speed = speed or 1, _damper = damper or 1, + _immediate = false, _updater = nil, }, SpringValue) end @@ -55,6 +56,10 @@ function SpringValue:SetDamper(damper: number) self._damper = damper end +function SpringValue:SetImmediate(immediate: boolean) + self._immediate = immediate +end + function SpringValue:SetUpdater(updater: (any) -> ()) self._updater = updater @@ -118,6 +123,16 @@ function SpringValue:Run(update: () -> ()?) self._updater = update end + if self._immediate then + self._current = self._goal + + if self._updater then + self._updater(self:GetValue()) + end + + return Promise.resolve() + end + return Promise.new(function(resolve, _, onCancel) onCancel(function() self:Stop() diff --git a/test/Test.lua b/test/Test.lua index 5604d65..7791381 100644 --- a/test/Test.lua +++ b/test/Test.lua @@ -60,6 +60,10 @@ end local function TestAnimation() local sequence, play, stop = useGroupAnimation({ moveRight = useAnimation({ + textSize = Tween({ + info = TweenInfo.new(1, Enum.EasingStyle.Back), + target = 25, + }), position = Spring({ target = UDim2.fromScale(0.8, 0), speed = 5, @@ -73,8 +77,13 @@ local function TestAnimation() speed = 5, damper = 0.7, }), + textSize = Tween({ + info = TweenInfo.new(1, Enum.EasingStyle.Back), + target = 10, + }), }), }, { + textSize = 10, size = UDim2.fromOffset(200, 200), position = UDim2.fromScale(0.5, 0), }) @@ -101,6 +110,7 @@ local function TestAnimation() Name = "Animation Group", Position = sequence.position, Size = sequence.size, + TextSize = sequence.textSize, ParentSize = UDim2.fromScale(1, 0.25), }) end diff --git a/wally.toml b/wally.toml index d52cc05..3ba06eb 100644 --- a/wally.toml +++ b/wally.toml @@ -1,7 +1,7 @@ [package] name = "outofbears/react-flow" description = "React Animation Library for Roblox" -version = "0.1.3" +version = "0.1.4" authors = ["Jack Fox "] homepage = "https://github.com/outofbears/react-flow" registry = "https://github.com/UpliftGames/wally-index"